bcrypt_pbkdf 1.1.1.rc2-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad16bd7ac931db04bf6ed0932305e819ed727867bcaf0a89f7953fb9651562a3
4
+ data.tar.gz: 34344ed743c08e28060e115367ccfcdcf7f6d5b4a4a91b46a3f3fa5bb19ed151
5
+ SHA512:
6
+ metadata.gz: e4c735f29cff70ae6353466f85eda75cfcb89d10ec3e50493c7d4633df79607bd18ebb0f953a0bd035d0e679f742f89d45b2e17f80785a18fd7f93bc642a8503
7
+ data.tar.gz: df3a28c85c38da1a0ae6d5851ce26437db53a95e188cf62e285f3e3187a1ee313e1937d35de4a1fbbd39cf71233fe75e6b57a0c276d011c806560f7292f4f77c
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: ci
3
+
4
+ on:
5
+ pull_request:
6
+ branches: [ main ]
7
+ push:
8
+ branches: [ main ]
9
+ workflow_dispatch:
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ jobs:
16
+ windows:
17
+ name: ${{ matrix.os }} ruby ${{ matrix.ruby }}
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ ruby: [2.7, 3.3, head, mingw, mswin, ucrt]
22
+ os: [windows-latest]
23
+ runs-on: ${{ matrix.os }}
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: ${{ matrix.ruby }}
29
+ bundler-cache: true
30
+ - run: bundle exec rake compile
31
+ - run: bundle exec rake test
32
+
33
+ unix:
34
+ name: ${{ matrix.os }} ruby ${{ matrix.ruby }}
35
+ strategy:
36
+ fail-fast: false
37
+ matrix:
38
+ ruby: [2.7, 3.3, head]
39
+ os: [ubuntu-latest, macos-latest]
40
+ runs-on: ${{ matrix.os }}
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+ - uses: ruby/setup-ruby@v1
44
+ with:
45
+ ruby-version: ${{ matrix.ruby }}
46
+ bundler-cache: true
47
+ - run: bundle exec rake compile
48
+ - run: bundle exec rake test
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ lib/
2
+ pkg/
3
+ tmp/
4
+ Gemfile.lock
5
+ .bundle/
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ # 1.0.0.apha1
2
+
3
+ initial version
data/COPYING ADDED
@@ -0,0 +1,23 @@
1
+ (The MIT License)
2
+
3
+ Copyright 2007-2016: Miklós Fazekas <mfazekas@szemafor.com>
4
+ C implementation of bcrypt_pbkdf: OpenBSD: Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ 'Software'), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ # bcrypt_pbkdf-ruby
2
+
3
+ bcrypt_pbkdf is a ruby gem implementing bcrypt_pbkdf from OpenBSD. This is currently used by net-ssh to read password encrypted Ed25519 keys.
4
+
5
+ [![Build Status](https://github.com/net-ssh/bcrypt_pbkdf-ruby/actions/workflows/ci.yml/badge.svg?branch=master&event=push)](https://github.com/net-ssh/bcrypt_pbkdf-ruby/actions/workflows/ci.yml)
6
+
7
+ ## Acknowledgements
8
+
9
+ * The gut of the code is based on OpenBSD's bcrypt_pbkdf.c implementation
10
+ * Some ideas/code were taken adopted bcrypt-ruby: https://github.com/codahale/bcrypt-ruby
11
+
12
+ ## Links
13
+
14
+ * http://www.tedunangst.com/flak/post/bcrypt-pbkdf
15
+ * http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libutil/bcrypt_pbkdf.c?rev=1.13&content-type=text/x-cvsweb-markup
16
+
17
+ ## Building
18
+
19
+ For windows and osx cross build make sure you checked out the gem source under the home directory and have docker installed.
20
+
21
+ ```sh
22
+ gem install rake-compiler-dock
23
+ ```
24
+
25
+ ```sh
26
+ bundle exec rake compile
27
+ bundle exec rake test
28
+ bundle exec rake clean clobber
29
+ bundle exec rake gem:all
30
+ bundle exec rake release
31
+ bundle exec rake gem:release
32
+ ```
data/Rakefile ADDED
@@ -0,0 +1,168 @@
1
+ require 'rake/testtask'
2
+ require 'rubygems/package_task'
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/extensiontask'
5
+ require 'rake/clean'
6
+ require 'rdoc/task'
7
+ require 'benchmark'
8
+ require 'rake_compiler_dock'
9
+
10
+ CLEAN.add("{ext,lib}/**/*.{o,so}", "pkg")
11
+
12
+ cross_rubies = ["3.3.0", "3.2.0", "3.1.0", "3.0.0", "2.7.0"]
13
+ cross_platforms = [
14
+ "arm64-darwin",
15
+ "x64-mingw-ucrt",
16
+ "x64-mingw32",
17
+ "x86-mingw32",
18
+ "x86_64-darwin",
19
+ ]
20
+ ENV["RUBY_CC_VERSION"] = cross_rubies.join(":")
21
+
22
+ GEMSPEC = Gem::Specification.load("bcrypt_pbkdf.gemspec")
23
+
24
+ task :default => [:compile, :spec]
25
+
26
+ desc "Run all tests"
27
+ Rake::TestTask.new do |t|
28
+ #t.pattern =
29
+ t.test_files = FileList['test/**/*_test.rb']
30
+ t.ruby_opts = ['-w']
31
+ t.libs << "test"
32
+ t.verbose = true
33
+ end
34
+ task :spec => :test
35
+
36
+ desc 'Generate RDoc'
37
+ RDoc::Task.new do |rdoc|
38
+ rdoc.rdoc_dir = 'doc/rdoc'
39
+ rdoc.options += GEMSPEC.rdoc_options
40
+ rdoc.template = ENV['TEMPLATE'] if ENV['TEMPLATE']
41
+ rdoc.rdoc_files.include(*GEMSPEC.extra_rdoc_files)
42
+ end
43
+
44
+ Rake::ExtensionTask.new("bcrypt_pbkdf_ext", GEMSPEC) do |ext|
45
+ ext.ext_dir = 'ext/mri'
46
+ ext.cross_compile = true
47
+ ext.cross_platform = cross_platforms
48
+ ext.cross_config_options << "--enable-cross-build" # so extconf.rb knows we're cross-compiling
49
+ end
50
+
51
+ namespace "gem" do
52
+ cross_platforms.each do |platform|
53
+ desc "build native gem for #{platform}"
54
+ task platform do
55
+ RakeCompilerDock.sh(<<~EOF, platform: platform, verbose: true)
56
+ gem install bundler --no-document &&
57
+ BUNDLE_IGNORE_CONFIG=1 BUNDLE_PATH=.bundle/#{platform} bundle &&
58
+ BUNDLE_IGNORE_CONFIG=1 BUNDLE_PATH=.bundle/#{platform} bundle exec rake gem:#{platform}:buildit
59
+ EOF
60
+ end
61
+
62
+ namespace platform do
63
+ # this runs in the rake-compiler-dock docker container
64
+ task "buildit" do
65
+ # use Task#invoke because the pkg/*gem task is defined at runtime
66
+ Rake::Task["native:#{platform}"].invoke
67
+ Rake::Task["pkg/#{GEMSPEC.full_name}-#{Gem::Platform.new(platform)}.gem"].invoke
68
+ end
69
+
70
+ task "release" do
71
+ sh "gem push pkg/#{GEMSPEC.full_name}-#{Gem::Platform.new(platform)}.gem"
72
+ end
73
+ end
74
+ end
75
+
76
+ desc "build native gem for all platforms"
77
+ task "all" do
78
+ cross_platforms.each do |platform|
79
+ Rake::Task["gem:#{platform}"].invoke
80
+ end
81
+ end
82
+
83
+ desc "release native gem for all platforms"
84
+ task "release" do
85
+ cross_platforms.each do |platform|
86
+ Rake::Task["gem:#{platform}:release"].invoke
87
+ end
88
+ end
89
+ end
90
+
91
+ def change_version(&block)
92
+ version = GEMSPEC.version
93
+ version_file = 'bcrypt_pbkdf.gemspec'
94
+ raise "No version found" if version.nil?
95
+ final = version.segments.take_while{ |i| i.is_a?(Integer) }.to_a
96
+ pre = version.segments.drop_while{ |i| i.is_a?(Integer) }.to_a.join("")
97
+ pre = nil if pre.empty?
98
+ tiny = final.last
99
+ result = block[pre: pre, tiny: tiny]
100
+ raise ArgumentError, "Version change logic should always return a pre" unless result.key?(:pre)
101
+
102
+ puts "result: #{result.inspect}"
103
+
104
+ new_pre = result[:pre] || []
105
+ new_tiny = result[:tiny] || tiny
106
+ final[-1] = new_tiny
107
+ new_version = Gem::Version.new([final, *new_pre].join("."))
108
+
109
+ found = false
110
+ File.open("#{version_file}.new", "w") do |f|
111
+ File.readlines(version_file).each do |line|
112
+ match = /^(\s+s\.version\s*=\s*\')[\d[a-z]\.]+(\'\s*)$/.match(line)
113
+ if match
114
+ prefix = match[1]
115
+ postfix = match[2]
116
+ new_line = "#{prefix}#{new_version.to_s}#{postfix}"
117
+ puts "Changing:\n - #{line} + #{new_line}"
118
+ line = new_line
119
+ found = true
120
+ end
121
+ f.write(line)
122
+ end
123
+ raise ArgumentError, "Cound not find version line in #{version_file}" unless found
124
+ end
125
+
126
+ FileUtils.mv version_file, "#{version_file}.old"
127
+ FileUtils.mv "#{version_file}.new", version_file
128
+ FileUtils.rm_f "#{version_file}.old"
129
+ end
130
+
131
+ namespace :vbump do
132
+ desc "Final release"
133
+ task :final do
134
+ change_version do |pre:, tiny:|
135
+ _ = tiny
136
+ if pre.nil?
137
+ { tiny: tiny + 1, pre: nil }
138
+ else
139
+ raise ArgumentError, "Unexpected pre: #{pre}" if pre.nil?
140
+
141
+ { pre: nil }
142
+ end
143
+ end
144
+ end
145
+
146
+ desc "Increment prerelease"
147
+ task :pre, [:type] do |_t, args|
148
+ change_version do |pre:, tiny:|
149
+ puts " PRE => #{pre.inspect}"
150
+ match = /^([a-z]+)(\d+)/.match(pre)
151
+ raise ArgumentError, "Unexpected pre: #{pre}" if match.nil? && args[:type].nil?
152
+
153
+ if match.nil? || (!args[:type].nil? && args[:type] != match[1])
154
+ if pre.nil?
155
+ { pre: "#{args[:type]}1", tiny: tiny + 1 }
156
+ else
157
+ { pre: "#{args[:type]}1" }
158
+ end
159
+ else
160
+ { pre: "#{match[1]}#{match[2].to_i + 1}" }
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ task "package" => cross_platforms.map { |p| "gem:#{p}" } # "package" task for all the native platforms
167
+
168
+ Rake::Task["package"].prerequisites.prepend("compile")
@@ -0,0 +1,28 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'bcrypt_pbkdf'
3
+ s.version = '1.1.1.rc2'
4
+
5
+ s.summary = "OpenBSD's bcrypt_pbkdf (a variant of PBKDF2 with bcrypt-based PRF)"
6
+ s.description = <<-EOF
7
+ This gem implements bcrypt_pbkdf (a variant of PBKDF2 with bcrypt-based PRF)
8
+ EOF
9
+
10
+ s.files = `git ls-files`.split("\n")
11
+ s.require_path = 'lib'
12
+
13
+ s.add_development_dependency 'rake-compiler', '~> 1.2.5'
14
+ s.add_development_dependency 'minitest', '~> 5'
15
+ s.add_development_dependency 'openssl', '~> 3'
16
+ s.add_development_dependency 'rdoc', '~> 6'
17
+ s.add_development_dependency 'rake-compiler-dock', '~> 1.5.0'
18
+
19
+ s.rdoc_options += ['--title', 'bcrypt_pbkdf', '--line-numbers', '--inline-source', '--main', 'README.md']
20
+ s.extra_rdoc_files += ['README.md', 'COPYING', 'CHANGELOG.md', *Dir['lib/**/*.rb']]
21
+
22
+ s.extensions = 'ext/mri/extconf.rb'
23
+
24
+ s.authors = ["Miklos Fazekas"]
25
+ s.email = "mfazekas@szemafor.com"
26
+ s.homepage = "https://github.com/net-ssh/bcrypt_pbkdf-ruby"
27
+ s.license = "MIT"
28
+ end
@@ -0,0 +1,169 @@
1
+ /* $OpenBSD: bcrypt_pbkdf.c,v 1.13 2015/01/12 03:20:04 tedu Exp $ */
2
+ /*
3
+ * Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+
18
+ #include <sys/types.h>
19
+
20
+ #include <stdint.h>
21
+ #include <stdlib.h>
22
+ #include "blf.h"
23
+ #include "sha2.h"
24
+ #include <string.h>
25
+ #include "util.h"
26
+
27
+ #define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
28
+
29
+ /*
30
+ * pkcs #5 pbkdf2 implementation using the "bcrypt" hash
31
+ *
32
+ * The bcrypt hash function is derived from the bcrypt password hashing
33
+ * function with the following modifications:
34
+ * 1. The input password and salt are preprocessed with SHA512.
35
+ * 2. The output length is expanded to 256 bits.
36
+ * 3. Subsequently the magic string to be encrypted is lengthened and modifed
37
+ * to "OxychromaticBlowfishSwatDynamite"
38
+ * 4. The hash function is defined to perform 64 rounds of initial state
39
+ * expansion. (More rounds are performed by iterating the hash.)
40
+ *
41
+ * Note that this implementation pulls the SHA512 operations into the caller
42
+ * as a performance optimization.
43
+ *
44
+ * One modification from official pbkdf2. Instead of outputting key material
45
+ * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
46
+ * generate (e.g.) 512 bits of key material for use as two 256 bit keys, an
47
+ * attacker can merely run once through the outer loop, but the user
48
+ * always runs it twice. Shuffling output bytes requires computing the
49
+ * entirety of the key material to assemble any subkey. This is something a
50
+ * wise caller could do; we just do it for you.
51
+ */
52
+
53
+ #define BCRYPT_WORDS 8
54
+ #define BCRYPT_HASHSIZE (BCRYPT_WORDS * 4)
55
+
56
+ void
57
+ bcrypt_hash(const uint8_t *sha2pass, const uint8_t *sha2salt, uint8_t *out)
58
+ {
59
+ blf_ctx state;
60
+ uint8_t ciphertext[BCRYPT_HASHSIZE] =
61
+ "OxychromaticBlowfishSwatDynamite";
62
+ uint32_t cdata[BCRYPT_WORDS];
63
+ int i;
64
+ uint16_t j;
65
+ size_t shalen = SHA512_DIGEST_LENGTH;
66
+
67
+ /* key expansion */
68
+ Blowfish_initstate(&state);
69
+ Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
70
+ for (i = 0; i < 64; i++) {
71
+ Blowfish_expand0state(&state, sha2salt, shalen);
72
+ Blowfish_expand0state(&state, sha2pass, shalen);
73
+ }
74
+
75
+ /* encryption */
76
+ j = 0;
77
+ for (i = 0; i < BCRYPT_WORDS; i++)
78
+ cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
79
+ &j);
80
+ for (i = 0; i < 64; i++)
81
+ blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t));
82
+
83
+ /* copy out */
84
+ for (i = 0; i < BCRYPT_WORDS; i++) {
85
+ out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
86
+ out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
87
+ out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
88
+ out[4 * i + 0] = cdata[i] & 0xff;
89
+ }
90
+
91
+ /* zap */
92
+ explicit_bzero(ciphertext, sizeof(ciphertext));
93
+ explicit_bzero(cdata, sizeof(cdata));
94
+ explicit_bzero(&state, sizeof(state));
95
+ }
96
+
97
+ int
98
+ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, size_t saltlen,
99
+ uint8_t *key, size_t keylen, unsigned int rounds)
100
+ {
101
+ SHA2_CTX ctx;
102
+ uint8_t sha2pass[SHA512_DIGEST_LENGTH];
103
+ uint8_t sha2salt[SHA512_DIGEST_LENGTH];
104
+ uint8_t out[BCRYPT_HASHSIZE];
105
+ uint8_t tmpout[BCRYPT_HASHSIZE];
106
+ uint8_t countsalt[4];
107
+ size_t i, j, amt, stride;
108
+ uint32_t count;
109
+ size_t origkeylen = keylen;
110
+
111
+ /* nothing crazy */
112
+ if (rounds < 1)
113
+ return -1;
114
+ if (passlen == 0 || saltlen == 0 || keylen == 0 ||
115
+ keylen > sizeof(out) * sizeof(out))
116
+ return -1;
117
+ stride = (keylen + sizeof(out) - 1) / sizeof(out);
118
+ amt = (keylen + stride - 1) / stride;
119
+
120
+ /* collapse password */
121
+ SHA512Init(&ctx);
122
+ SHA512Update(&ctx, pass, passlen);
123
+ SHA512Final(sha2pass, &ctx);
124
+
125
+
126
+ /* generate key, sizeof(out) at a time */
127
+ for (count = 1; keylen > 0; count++) {
128
+ countsalt[0] = (count >> 24) & 0xff;
129
+ countsalt[1] = (count >> 16) & 0xff;
130
+ countsalt[2] = (count >> 8) & 0xff;
131
+ countsalt[3] = count & 0xff;
132
+
133
+ /* first round, salt is salt */
134
+ SHA512Init(&ctx);
135
+ SHA512Update(&ctx, salt, saltlen);
136
+ SHA512Update(&ctx, countsalt, sizeof(countsalt));
137
+ SHA512Final(sha2salt, &ctx);
138
+ bcrypt_hash(sha2pass, sha2salt, tmpout);
139
+ memcpy(out, tmpout, sizeof(out));
140
+
141
+ for (i = 1; i < rounds; i++) {
142
+ /* subsequent rounds, salt is previous output */
143
+ SHA512Init(&ctx);
144
+ SHA512Update(&ctx, tmpout, sizeof(tmpout));
145
+ SHA512Final(sha2salt, &ctx);
146
+ bcrypt_hash(sha2pass, sha2salt, tmpout);
147
+ for (j = 0; j < sizeof(out); j++)
148
+ out[j] ^= tmpout[j];
149
+ }
150
+
151
+ /*
152
+ * pbkdf2 deviation: output the key material non-linearly.
153
+ */
154
+ amt = MINIMUM(amt, keylen);
155
+ for (i = 0; i < amt; i++) {
156
+ size_t dest = i * stride + (count - 1);
157
+ if (dest >= origkeylen)
158
+ break;
159
+ key[dest] = out[i];
160
+ }
161
+ keylen -= i;
162
+ }
163
+
164
+ /* zap */
165
+ explicit_bzero(&ctx, sizeof(ctx));
166
+ explicit_bzero(out, sizeof(out));
167
+
168
+ return 0;
169
+ }
@@ -0,0 +1,44 @@
1
+ #include "includes.h"
2
+ #include <ruby.h>
3
+
4
+ static VALUE mBCryptPbkdf;
5
+ static VALUE cBCryptPbkdfEngine;
6
+
7
+ /* Given a secret and a salt a key and the number of rounds and returns the encrypted secret
8
+ */
9
+ static VALUE bc_crypt_pbkdf(VALUE self, VALUE pass, VALUE salt, VALUE keylen, VALUE rounds) {
10
+ size_t okeylen = NUM2ULONG(keylen);
11
+ u_int8_t* okey = xmalloc(okeylen);
12
+ VALUE out;
13
+
14
+ int ret = bcrypt_pbkdf(
15
+ StringValuePtr(pass), RSTRING_LEN(pass),
16
+ (const u_int8_t*)StringValuePtr(salt), RSTRING_LEN(salt),
17
+ okey, okeylen,
18
+ NUM2ULONG(rounds));
19
+ if (ret < 0)
20
+ return Qnil;
21
+ out = rb_str_new((const char*)okey, okeylen);
22
+ xfree(okey);
23
+ return out;
24
+ }
25
+
26
+ static VALUE bc_crypt_hash(VALUE self, VALUE pass, VALUE salt) {
27
+ u_int8_t hash[BCRYPT_HASHSIZE];
28
+ if (RSTRING_LEN(pass) != 64U)
29
+ return Qnil;
30
+ if (RSTRING_LEN(salt) != 64U)
31
+ return Qnil;
32
+ bcrypt_hash((const u_int8_t*)StringValuePtr(pass), (const u_int8_t*)StringValuePtr(salt), hash);
33
+ return rb_str_new((const char*)hash, sizeof(hash));
34
+ }
35
+
36
+
37
+ /* Create the BCryptPbkdf and BCryptPbkdf::Engine modules, and populate them with methods. */
38
+ void Init_bcrypt_pbkdf_ext(){
39
+ mBCryptPbkdf = rb_define_module("BCryptPbkdf");
40
+ cBCryptPbkdfEngine = rb_define_class_under(mBCryptPbkdf, "Engine", rb_cObject);
41
+
42
+ rb_define_singleton_method(cBCryptPbkdfEngine, "__bc_crypt_pbkdf", bc_crypt_pbkdf, 4);
43
+ rb_define_singleton_method(cBCryptPbkdfEngine, "__bc_crypt_hash", bc_crypt_hash, 2);
44
+ }
data/ext/mri/blf.h ADDED
@@ -0,0 +1,90 @@
1
+ /* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
2
+ /*
3
+ * Blowfish - a fast block cipher designed by Bruce Schneier
4
+ *
5
+ * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions
10
+ * are met:
11
+ * 1. Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * 2. Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * 3. All advertising materials mentioning features or use of this software
17
+ * must display the following acknowledgement:
18
+ * This product includes software developed by Niels Provos.
19
+ * 4. The name of the author may not be used to endorse or promote products
20
+ * derived from this software without specific prior written permission.
21
+ *
22
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+
34
+ #ifndef _BLF_H_
35
+ #define _BLF_H_
36
+
37
+ #include "includes.h"
38
+
39
+ #if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H)
40
+
41
+ /* Schneier specifies a maximum key length of 56 bytes.
42
+ * This ensures that every key bit affects every cipher
43
+ * bit. However, the subkeys can hold up to 72 bytes.
44
+ * Warning: For normal blowfish encryption only 56 bytes
45
+ * of the key affect all cipherbits.
46
+ */
47
+
48
+ #define BLF_N 16 /* Number of Subkeys */
49
+ #define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
50
+ #define BLF_MAXUTILIZED ((BLF_N+2)*4) /* 576 bits */
51
+
52
+ /* Blowfish context */
53
+ typedef struct BlowfishContext {
54
+ u_int32_t S[4][256]; /* S-Boxes */
55
+ u_int32_t P[BLF_N + 2]; /* Subkeys */
56
+ } blf_ctx;
57
+
58
+ /* Raw access to customized Blowfish
59
+ * blf_key is just:
60
+ * Blowfish_initstate( state )
61
+ * Blowfish_expand0state( state, key, keylen )
62
+ */
63
+
64
+ void Blowfish_encipher(blf_ctx *, u_int32_t *, u_int32_t *);
65
+ void Blowfish_decipher(blf_ctx *, u_int32_t *, u_int32_t *);
66
+ void Blowfish_initstate(blf_ctx *);
67
+ void Blowfish_expand0state(blf_ctx *, const u_int8_t *, u_int16_t);
68
+ void Blowfish_expandstate
69
+ (blf_ctx *, const u_int8_t *, u_int16_t, const u_int8_t *, u_int16_t);
70
+
71
+ /* Standard Blowfish */
72
+
73
+ void blf_key(blf_ctx *, const u_int8_t *, u_int16_t);
74
+ void blf_enc(blf_ctx *, u_int32_t *, u_int16_t);
75
+ void blf_dec(blf_ctx *, u_int32_t *, u_int16_t);
76
+
77
+ void blf_ecb_encrypt(blf_ctx *, u_int8_t *, u_int32_t);
78
+ void blf_ecb_decrypt(blf_ctx *, u_int8_t *, u_int32_t);
79
+
80
+ void blf_cbc_encrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t);
81
+ void blf_cbc_decrypt(blf_ctx *, u_int8_t *, u_int8_t *, u_int32_t);
82
+
83
+ /* Converts u_int8_t to u_int32_t */
84
+ u_int32_t Blowfish_stream2word(const u_int8_t *, u_int16_t , u_int16_t *);
85
+
86
+ #define DEF_WEAK(foo)
87
+
88
+ #endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
89
+ #endif /* _BLF_H */
90
+