bcrypt_pbkdf 1.2.0.beta1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +75 -0
- data/.gitignore +6 -0
- data/CHANGELOG.md +38 -0
- data/COPYING +23 -0
- data/Gemfile +2 -0
- data/Gemfile.memcheck +5 -0
- data/README.md +41 -0
- data/Rakefile +208 -0
- data/bcrypt_pbkdf.gemspec +29 -0
- data/ext/jruby/org/netssh/bcrypt_pbkdf/BCryptPbkdf.java +402 -0
- data/ext/jruby/org/netssh/bcrypt_pbkdf/BCryptPbkdfExt.java +47 -0
- data/ext/mri/bcrypt_pbkdf.c +167 -0
- data/ext/mri/bcrypt_pbkdf_ext.c +48 -0
- data/ext/mri/blf.h +87 -0
- data/ext/mri/blowfish.c +695 -0
- data/ext/mri/crypto_api.h +3 -0
- data/ext/mri/crypto_hash_sha512.h +19 -0
- data/ext/mri/explicit_bzero.c +20 -0
- data/ext/mri/extconf.rb +3 -0
- data/ext/mri/hash_sha512.c +320 -0
- data/ext/mri/includes.h +27 -0
- data/ext/mri/sha2.h +13 -0
- data/ext/mri/util.h +0 -0
- data/ext/mri/utils.h +5 -0
- data/lib/bcrypt_pbkdf.rb +28 -0
- data/lib/bcrypt_pbkdf_ext.jar +0 -0
- data/test/bcrypt_pnkdf/engine_test.rb +115 -0
- data/test/test_helper.rb +2 -0
- metadata +165 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
package org.netssh.bcrypt_pbkdf;
|
|
2
|
+
|
|
3
|
+
import java.nio.charset.StandardCharsets;
|
|
4
|
+
import java.security.MessageDigest;
|
|
5
|
+
import java.security.NoSuchAlgorithmException;
|
|
6
|
+
import java.util.Arrays;
|
|
7
|
+
|
|
8
|
+
public final class BCryptPbkdf {
|
|
9
|
+
private static final int BLF_N = 16;
|
|
10
|
+
private static final int BCRYPT_WORDS = 8;
|
|
11
|
+
private static final int BCRYPT_HASHSIZE = BCRYPT_WORDS * 4;
|
|
12
|
+
private static final int SHA512_DIGEST_LENGTH = 64;
|
|
13
|
+
private static final int[] INITSTATE = new int[] {
|
|
14
|
+
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
|
15
|
+
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
|
16
|
+
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
|
|
17
|
+
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
|
18
|
+
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
|
|
19
|
+
0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
|
20
|
+
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
|
|
21
|
+
0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
|
22
|
+
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
|
|
23
|
+
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
|
24
|
+
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
|
|
25
|
+
0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
|
26
|
+
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
|
|
27
|
+
0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
|
28
|
+
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
|
|
29
|
+
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
|
30
|
+
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
|
|
31
|
+
0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
|
32
|
+
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
|
|
33
|
+
0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
|
34
|
+
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
|
|
35
|
+
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
|
36
|
+
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
|
|
37
|
+
0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
|
38
|
+
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
|
|
39
|
+
0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
|
40
|
+
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
|
|
41
|
+
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
|
42
|
+
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
|
|
43
|
+
0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
|
44
|
+
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
|
|
45
|
+
0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
|
46
|
+
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
|
|
47
|
+
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
|
48
|
+
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
|
|
49
|
+
0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
|
50
|
+
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
|
|
51
|
+
0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
|
52
|
+
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
|
|
53
|
+
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
|
54
|
+
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
|
|
55
|
+
0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
|
56
|
+
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, 0x4b7a70e9, 0xb5b32944,
|
|
57
|
+
0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
|
58
|
+
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29,
|
|
59
|
+
0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
|
60
|
+
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26,
|
|
61
|
+
0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
|
62
|
+
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c,
|
|
63
|
+
0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
|
64
|
+
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6,
|
|
65
|
+
0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
|
66
|
+
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f,
|
|
67
|
+
0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
|
68
|
+
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810,
|
|
69
|
+
0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
|
70
|
+
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa,
|
|
71
|
+
0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
|
72
|
+
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55,
|
|
73
|
+
0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
|
74
|
+
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1,
|
|
75
|
+
0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
|
76
|
+
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78,
|
|
77
|
+
0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
|
78
|
+
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883,
|
|
79
|
+
0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
|
80
|
+
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170,
|
|
81
|
+
0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
|
82
|
+
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7,
|
|
83
|
+
0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
|
84
|
+
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099,
|
|
85
|
+
0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
|
86
|
+
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263,
|
|
87
|
+
0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
|
88
|
+
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3,
|
|
89
|
+
0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
|
90
|
+
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7,
|
|
91
|
+
0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
|
92
|
+
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d,
|
|
93
|
+
0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
|
94
|
+
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460,
|
|
95
|
+
0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
|
96
|
+
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484,
|
|
97
|
+
0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
|
98
|
+
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a,
|
|
99
|
+
0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
|
100
|
+
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a,
|
|
101
|
+
0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
|
102
|
+
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785,
|
|
103
|
+
0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
|
104
|
+
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900,
|
|
105
|
+
0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
|
106
|
+
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9,
|
|
107
|
+
0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
|
108
|
+
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397,
|
|
109
|
+
0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
|
110
|
+
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9,
|
|
111
|
+
0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
|
112
|
+
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f,
|
|
113
|
+
0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
|
114
|
+
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e,
|
|
115
|
+
0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
|
116
|
+
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd,
|
|
117
|
+
0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
|
118
|
+
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8,
|
|
119
|
+
0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
|
120
|
+
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c,
|
|
121
|
+
0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
|
122
|
+
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b,
|
|
123
|
+
0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
|
124
|
+
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386,
|
|
125
|
+
0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
|
126
|
+
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0,
|
|
127
|
+
0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
|
128
|
+
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2,
|
|
129
|
+
0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
|
130
|
+
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770,
|
|
131
|
+
0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
|
132
|
+
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c,
|
|
133
|
+
0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
|
134
|
+
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa,
|
|
135
|
+
0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
|
136
|
+
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63,
|
|
137
|
+
0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
|
138
|
+
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9,
|
|
139
|
+
0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
|
140
|
+
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4,
|
|
141
|
+
0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
|
142
|
+
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
|
|
143
|
+
0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
|
144
|
+
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
|
|
145
|
+
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
|
146
|
+
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
|
|
147
|
+
0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
|
148
|
+
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
|
|
149
|
+
0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
|
150
|
+
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
|
|
151
|
+
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
|
152
|
+
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
|
|
153
|
+
0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
|
154
|
+
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
|
|
155
|
+
0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
|
156
|
+
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
|
|
157
|
+
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
|
158
|
+
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
|
|
159
|
+
0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
|
160
|
+
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
|
|
161
|
+
0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
|
162
|
+
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
|
|
163
|
+
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
|
164
|
+
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
|
|
165
|
+
0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
|
166
|
+
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
|
|
167
|
+
0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
|
168
|
+
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
|
|
169
|
+
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
|
170
|
+
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
|
|
171
|
+
0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
|
172
|
+
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
|
|
173
|
+
0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
|
174
|
+
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
|
|
175
|
+
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
|
176
|
+
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
|
|
177
|
+
0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
|
178
|
+
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
|
|
179
|
+
0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
|
180
|
+
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
|
|
181
|
+
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
|
182
|
+
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
|
|
183
|
+
0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
|
184
|
+
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6, 0x243f6a88, 0x85a308d3,
|
|
185
|
+
0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
|
186
|
+
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd,
|
|
187
|
+
0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
static byte[] cryptPbkdf(byte[] pass, byte[] salt, int keylen, int rounds) {
|
|
191
|
+
if (rounds < 1 || pass.length == 0 || salt.length == 0 || keylen == 0 || keylen > BCRYPT_HASHSIZE * BCRYPT_HASHSIZE || salt.length > (1 << 20)) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
byte[] key = new byte[keylen];
|
|
196
|
+
byte[] sha2pass = sha512(pass);
|
|
197
|
+
byte[] sha2salt;
|
|
198
|
+
byte[] out = new byte[BCRYPT_HASHSIZE];
|
|
199
|
+
byte[] tmpout;
|
|
200
|
+
byte[] countsalt = new byte[salt.length + 4];
|
|
201
|
+
System.arraycopy(salt, 0, countsalt, 0, salt.length);
|
|
202
|
+
|
|
203
|
+
int stride = (keylen + BCRYPT_HASHSIZE - 1) / BCRYPT_HASHSIZE;
|
|
204
|
+
int amt = (keylen + stride - 1) / stride;
|
|
205
|
+
int origkeylen = keylen;
|
|
206
|
+
|
|
207
|
+
for (int count = 1; keylen > 0; count++) {
|
|
208
|
+
countsalt[salt.length] = (byte) ((count >>> 24) & 0xff);
|
|
209
|
+
countsalt[salt.length + 1] = (byte) ((count >>> 16) & 0xff);
|
|
210
|
+
countsalt[salt.length + 2] = (byte) ((count >>> 8) & 0xff);
|
|
211
|
+
countsalt[salt.length + 3] = (byte) (count & 0xff);
|
|
212
|
+
|
|
213
|
+
sha2salt = sha512(countsalt);
|
|
214
|
+
tmpout = bcryptHash(sha2pass, sha2salt);
|
|
215
|
+
System.arraycopy(tmpout, 0, out, 0, out.length);
|
|
216
|
+
|
|
217
|
+
for (int i = 1; i < rounds; i++) {
|
|
218
|
+
sha2salt = sha512(tmpout);
|
|
219
|
+
tmpout = bcryptHash(sha2pass, sha2salt);
|
|
220
|
+
for (int j = 0; j < out.length; j++) {
|
|
221
|
+
out[j] ^= tmpout[j];
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
amt = Math.min(amt, keylen);
|
|
226
|
+
int i;
|
|
227
|
+
for (i = 0; i < amt; i++) {
|
|
228
|
+
int dest = i * stride + (count - 1);
|
|
229
|
+
if (dest >= origkeylen) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
key[dest] = out[i];
|
|
233
|
+
}
|
|
234
|
+
keylen -= i;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
Arrays.fill(sha2pass, (byte) 0);
|
|
238
|
+
Arrays.fill(out, (byte) 0);
|
|
239
|
+
return key;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
static byte[] cryptHash(byte[] sha2pass, byte[] sha2salt) {
|
|
243
|
+
if (sha2pass.length != SHA512_DIGEST_LENGTH || sha2salt.length != SHA512_DIGEST_LENGTH) {
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
return bcryptHash(sha2pass, sha2salt);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
private static byte[] bcryptHash(byte[] sha2pass, byte[] sha2salt) {
|
|
250
|
+
BlowfishContext state = new BlowfishContext();
|
|
251
|
+
byte[] ciphertext = "OxychromaticBlowfishSwatDynamite".getBytes(StandardCharsets.US_ASCII);
|
|
252
|
+
int[] cdata = new int[BCRYPT_WORDS];
|
|
253
|
+
byte[] out = new byte[BCRYPT_HASHSIZE];
|
|
254
|
+
int[] current = new int[] { 0 };
|
|
255
|
+
|
|
256
|
+
Blowfish_initstate(state);
|
|
257
|
+
Blowfish_expandstate(state, sha2salt, SHA512_DIGEST_LENGTH, sha2pass, SHA512_DIGEST_LENGTH);
|
|
258
|
+
for (int i = 0; i < 64; i++) {
|
|
259
|
+
Blowfish_expand0state(state, sha2salt, SHA512_DIGEST_LENGTH);
|
|
260
|
+
Blowfish_expand0state(state, sha2pass, SHA512_DIGEST_LENGTH);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
for (int i = 0; i < BCRYPT_WORDS; i++) {
|
|
264
|
+
cdata[i] = Blowfish_stream2word(ciphertext, ciphertext.length, current);
|
|
265
|
+
}
|
|
266
|
+
for (int i = 0; i < 64; i++) {
|
|
267
|
+
blf_enc(state, cdata, cdata.length / 2);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
for (int i = 0; i < BCRYPT_WORDS; i++) {
|
|
271
|
+
out[4 * i + 3] = (byte) ((cdata[i] >>> 24) & 0xff);
|
|
272
|
+
out[4 * i + 2] = (byte) ((cdata[i] >>> 16) & 0xff);
|
|
273
|
+
out[4 * i + 1] = (byte) ((cdata[i] >>> 8) & 0xff);
|
|
274
|
+
out[4 * i] = (byte) (cdata[i] & 0xff);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
Arrays.fill(ciphertext, (byte) 0);
|
|
278
|
+
Arrays.fill(cdata, 0);
|
|
279
|
+
state.clear();
|
|
280
|
+
return out;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private static byte[] sha512(byte[] data) {
|
|
284
|
+
try {
|
|
285
|
+
return MessageDigest.getInstance("SHA-512").digest(data);
|
|
286
|
+
} catch (NoSuchAlgorithmException e) {
|
|
287
|
+
throw new IllegalStateException(e);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private static int F(int[][] s, int x) {
|
|
292
|
+
return ((s[0][(x >>> 24) & 0xff] + s[1][(x >>> 16) & 0xff]) ^ s[2][(x >>> 8) & 0xff]) + s[3][x & 0xff];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private static void Blowfish_encipher(BlowfishContext c, int[] data, int offset) {
|
|
296
|
+
int xl = data[offset];
|
|
297
|
+
int xr = data[offset + 1];
|
|
298
|
+
int[] p = c.P;
|
|
299
|
+
|
|
300
|
+
xl ^= p[0];
|
|
301
|
+
xr ^= F(c.S, xl) ^ p[1]; xl ^= F(c.S, xr) ^ p[2];
|
|
302
|
+
xr ^= F(c.S, xl) ^ p[3]; xl ^= F(c.S, xr) ^ p[4];
|
|
303
|
+
xr ^= F(c.S, xl) ^ p[5]; xl ^= F(c.S, xr) ^ p[6];
|
|
304
|
+
xr ^= F(c.S, xl) ^ p[7]; xl ^= F(c.S, xr) ^ p[8];
|
|
305
|
+
xr ^= F(c.S, xl) ^ p[9]; xl ^= F(c.S, xr) ^ p[10];
|
|
306
|
+
xr ^= F(c.S, xl) ^ p[11]; xl ^= F(c.S, xr) ^ p[12];
|
|
307
|
+
xr ^= F(c.S, xl) ^ p[13]; xl ^= F(c.S, xr) ^ p[14];
|
|
308
|
+
xr ^= F(c.S, xl) ^ p[15]; xl ^= F(c.S, xr) ^ p[16];
|
|
309
|
+
|
|
310
|
+
data[offset] = xr ^ p[17];
|
|
311
|
+
data[offset + 1] = xl;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
private static void Blowfish_initstate(BlowfishContext c) {
|
|
315
|
+
int n = 0;
|
|
316
|
+
for (int i = 0; i < 4; i++) {
|
|
317
|
+
System.arraycopy(INITSTATE, n, c.S[i], 0, 256);
|
|
318
|
+
n += 256;
|
|
319
|
+
}
|
|
320
|
+
System.arraycopy(INITSTATE, n, c.P, 0, BLF_N + 2);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
private static int Blowfish_stream2word(byte[] data, int databytes, int[] current) {
|
|
324
|
+
int temp = 0;
|
|
325
|
+
int j = current[0];
|
|
326
|
+
for (int i = 0; i < 4; i++, j++) {
|
|
327
|
+
if (j >= databytes) {
|
|
328
|
+
j = 0;
|
|
329
|
+
}
|
|
330
|
+
temp = (temp << 8) | (data[j] & 0xff);
|
|
331
|
+
}
|
|
332
|
+
current[0] = j;
|
|
333
|
+
return temp;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
private static void Blowfish_expand0state(BlowfishContext c, byte[] key, int keybytes) {
|
|
337
|
+
int[] current = new int[] { 0 };
|
|
338
|
+
for (int i = 0; i < BLF_N + 2; i++) {
|
|
339
|
+
c.P[i] ^= Blowfish_stream2word(key, keybytes, current);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
int[] data = new int[] { 0, 0 };
|
|
343
|
+
for (int i = 0; i < BLF_N + 2; i += 2) {
|
|
344
|
+
Blowfish_encipher(c, data, 0);
|
|
345
|
+
c.P[i] = data[0];
|
|
346
|
+
c.P[i + 1] = data[1];
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
for (int i = 0; i < 4; i++) {
|
|
350
|
+
for (int k = 0; k < 256; k += 2) {
|
|
351
|
+
Blowfish_encipher(c, data, 0);
|
|
352
|
+
c.S[i][k] = data[0];
|
|
353
|
+
c.S[i][k + 1] = data[1];
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
private static void Blowfish_expandstate(BlowfishContext c, byte[] dataBytes, int databytes, byte[] key, int keybytes) {
|
|
359
|
+
int[] current = new int[] { 0 };
|
|
360
|
+
for (int i = 0; i < BLF_N + 2; i++) {
|
|
361
|
+
c.P[i] ^= Blowfish_stream2word(key, keybytes, current);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
current[0] = 0;
|
|
365
|
+
int[] data = new int[] { 0, 0 };
|
|
366
|
+
for (int i = 0; i < BLF_N + 2; i += 2) {
|
|
367
|
+
data[0] ^= Blowfish_stream2word(dataBytes, databytes, current);
|
|
368
|
+
data[1] ^= Blowfish_stream2word(dataBytes, databytes, current);
|
|
369
|
+
Blowfish_encipher(c, data, 0);
|
|
370
|
+
c.P[i] = data[0];
|
|
371
|
+
c.P[i + 1] = data[1];
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
for (int i = 0; i < 4; i++) {
|
|
375
|
+
for (int k = 0; k < 256; k += 2) {
|
|
376
|
+
data[0] ^= Blowfish_stream2word(dataBytes, databytes, current);
|
|
377
|
+
data[1] ^= Blowfish_stream2word(dataBytes, databytes, current);
|
|
378
|
+
Blowfish_encipher(c, data, 0);
|
|
379
|
+
c.S[i][k] = data[0];
|
|
380
|
+
c.S[i][k + 1] = data[1];
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
private static void blf_enc(BlowfishContext c, int[] data, int blocks) {
|
|
386
|
+
for (int i = 0, offset = 0; i < blocks; i++, offset += 2) {
|
|
387
|
+
Blowfish_encipher(c, data, offset);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
private static class BlowfishContext {
|
|
392
|
+
final int[][] S = new int[4][256];
|
|
393
|
+
final int[] P = new int[BLF_N + 2];
|
|
394
|
+
|
|
395
|
+
void clear() {
|
|
396
|
+
for (int[] s : S) {
|
|
397
|
+
Arrays.fill(s, 0);
|
|
398
|
+
}
|
|
399
|
+
Arrays.fill(P, 0);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
package org.netssh.bcrypt_pbkdf;
|
|
2
|
+
|
|
3
|
+
import org.jcodings.specific.ASCIIEncoding;
|
|
4
|
+
import org.jruby.Ruby;
|
|
5
|
+
import org.jruby.RubyClass;
|
|
6
|
+
import org.jruby.RubyModule;
|
|
7
|
+
import org.jruby.RubyNumeric;
|
|
8
|
+
import org.jruby.RubyString;
|
|
9
|
+
import org.jruby.anno.JRubyMethod;
|
|
10
|
+
import org.jruby.runtime.ThreadContext;
|
|
11
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
|
12
|
+
|
|
13
|
+
public final class BCryptPbkdfExt {
|
|
14
|
+
|
|
15
|
+
public static void load(final Ruby runtime) {
|
|
16
|
+
RubyModule bcryptPbkdf = runtime.getOrCreateModule("BCryptPbkdf");
|
|
17
|
+
RubyClass engine = bcryptPbkdf.defineOrGetClassUnder("Engine", runtime.getObject());
|
|
18
|
+
engine.getSingletonClass().defineAnnotatedMethods(BCryptPbkdfExt.class);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@JRubyMethod(required = 4, rest = true)
|
|
22
|
+
public static IRubyObject __bc_crypt_pbkdf(ThreadContext context, IRubyObject self, IRubyObject[] args) {
|
|
23
|
+
byte[] key = BCryptPbkdf.cryptPbkdf(
|
|
24
|
+
stringToBytes(args[0]),
|
|
25
|
+
stringToBytes(args[1]),
|
|
26
|
+
RubyNumeric.num2int(args[2]),
|
|
27
|
+
RubyNumeric.num2int(args[3]));
|
|
28
|
+
if (key == null) return context.nil;
|
|
29
|
+
return newString(context.runtime, key);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@JRubyMethod(required = 2, rest = true)
|
|
34
|
+
public static IRubyObject __bc_crypt_hash(ThreadContext context, IRubyObject self, IRubyObject[] args) {
|
|
35
|
+
byte[] out = BCryptPbkdf.cryptHash(stringToBytes(args[0]), stringToBytes(args[1]));
|
|
36
|
+
if (out == null) return context.nil;
|
|
37
|
+
return newString(context.runtime, out);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private static byte[] stringToBytes(final IRubyObject value) {
|
|
41
|
+
return value.convertToString().getBytes();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private static RubyString newString(final Ruby runtime, final byte[] bytes) {
|
|
45
|
+
return RubyString.newString(runtime, bytes, 0, bytes.length, ASCIIEncoding.INSTANCE);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/* $OpenBSD: bcrypt_pbkdf.c,v 1.17 2022/12/27 17:10:08 jmc 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 "includes.h"
|
|
19
|
+
#include "crypto_api.h"
|
|
20
|
+
|
|
21
|
+
#ifdef SHA512_DIGEST_LENGTH
|
|
22
|
+
# undef SHA512_DIGEST_LENGTH
|
|
23
|
+
#endif
|
|
24
|
+
#define SHA512_DIGEST_LENGTH crypto_hash_sha512_BYTES
|
|
25
|
+
|
|
26
|
+
#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
|
|
30
|
+
*
|
|
31
|
+
* The bcrypt hash function is derived from the bcrypt password hashing
|
|
32
|
+
* function with the following modifications:
|
|
33
|
+
* 1. The input password and salt are preprocessed with SHA512.
|
|
34
|
+
* 2. The output length is expanded to 256 bits.
|
|
35
|
+
* 3. Subsequently the magic string to be encrypted is lengthened and modified
|
|
36
|
+
* to "OxychromaticBlowfishSwatDynamite"
|
|
37
|
+
* 4. The hash function is defined to perform 64 rounds of initial state
|
|
38
|
+
* expansion. (More rounds are performed by iterating the hash.)
|
|
39
|
+
*
|
|
40
|
+
* Note that this implementation pulls the SHA512 operations into the caller
|
|
41
|
+
* as a performance optimization.
|
|
42
|
+
*
|
|
43
|
+
* One modification from official pbkdf2. Instead of outputting key material
|
|
44
|
+
* linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
|
|
45
|
+
* generate (e.g.) 512 bits of key material for use as two 256 bit keys, an
|
|
46
|
+
* attacker can merely run once through the outer loop, but the user
|
|
47
|
+
* always runs it twice. Shuffling output bytes requires computing the
|
|
48
|
+
* entirety of the key material to assemble any subkey. This is something a
|
|
49
|
+
* wise caller could do; we just do it for you.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
void
|
|
53
|
+
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
|
|
54
|
+
{
|
|
55
|
+
blf_ctx state;
|
|
56
|
+
#if defined(__has_attribute) && __has_attribute(__nonstring__)
|
|
57
|
+
uint8_t __attribute__ ((__nonstring__)) ciphertext[BCRYPT_HASHSIZE] =
|
|
58
|
+
#else
|
|
59
|
+
uint8_t ciphertext[BCRYPT_HASHSIZE] =
|
|
60
|
+
#endif
|
|
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, BCRYPT_WORDS / 2);
|
|
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
|
+
uint8_t sha2pass[SHA512_DIGEST_LENGTH];
|
|
102
|
+
uint8_t sha2salt[SHA512_DIGEST_LENGTH];
|
|
103
|
+
uint8_t out[BCRYPT_HASHSIZE];
|
|
104
|
+
uint8_t tmpout[BCRYPT_HASHSIZE];
|
|
105
|
+
uint8_t *countsalt;
|
|
106
|
+
size_t i, j, amt, stride;
|
|
107
|
+
uint32_t count;
|
|
108
|
+
size_t origkeylen = keylen;
|
|
109
|
+
|
|
110
|
+
/* nothing crazy */
|
|
111
|
+
if (rounds < 1)
|
|
112
|
+
return -1;
|
|
113
|
+
if (passlen == 0 || saltlen == 0 || keylen == 0 ||
|
|
114
|
+
keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20)
|
|
115
|
+
return -1;
|
|
116
|
+
if ((countsalt = calloc(1, saltlen + 4)) == NULL)
|
|
117
|
+
return -1;
|
|
118
|
+
stride = (keylen + sizeof(out) - 1) / sizeof(out);
|
|
119
|
+
amt = (keylen + stride - 1) / stride;
|
|
120
|
+
|
|
121
|
+
memcpy(countsalt, salt, saltlen);
|
|
122
|
+
|
|
123
|
+
/* collapse password */
|
|
124
|
+
crypto_hash_sha512(sha2pass, (const uint8_t *)pass, passlen);
|
|
125
|
+
|
|
126
|
+
/* generate key, sizeof(out) at a time */
|
|
127
|
+
for (count = 1; keylen > 0; count++) {
|
|
128
|
+
countsalt[saltlen + 0] = (count >> 24) & 0xff;
|
|
129
|
+
countsalt[saltlen + 1] = (count >> 16) & 0xff;
|
|
130
|
+
countsalt[saltlen + 2] = (count >> 8) & 0xff;
|
|
131
|
+
countsalt[saltlen + 3] = count & 0xff;
|
|
132
|
+
|
|
133
|
+
/* first round, salt is salt */
|
|
134
|
+
crypto_hash_sha512(sha2salt, countsalt, saltlen + 4);
|
|
135
|
+
|
|
136
|
+
bcrypt_hash(sha2pass, sha2salt, tmpout);
|
|
137
|
+
memcpy(out, tmpout, sizeof(out));
|
|
138
|
+
|
|
139
|
+
for (i = 1; i < rounds; i++) {
|
|
140
|
+
/* subsequent rounds, salt is previous output */
|
|
141
|
+
crypto_hash_sha512(sha2salt, tmpout, sizeof(tmpout));
|
|
142
|
+
bcrypt_hash(sha2pass, sha2salt, tmpout);
|
|
143
|
+
for (j = 0; j < sizeof(out); j++)
|
|
144
|
+
out[j] ^= tmpout[j];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/*
|
|
148
|
+
* pbkdf2 deviation: output the key material non-linearly.
|
|
149
|
+
*/
|
|
150
|
+
amt = MINIMUM(amt, keylen);
|
|
151
|
+
for (i = 0; i < amt; i++) {
|
|
152
|
+
size_t dest = i * stride + (count - 1);
|
|
153
|
+
if (dest >= origkeylen)
|
|
154
|
+
break;
|
|
155
|
+
key[dest] = out[i];
|
|
156
|
+
}
|
|
157
|
+
keylen -= i;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* zap */
|
|
161
|
+
explicit_bzero(countsalt, saltlen + 4);
|
|
162
|
+
free(countsalt);
|
|
163
|
+
explicit_bzero(out, sizeof(out));
|
|
164
|
+
explicit_bzero(tmpout, sizeof(tmpout));
|
|
165
|
+
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
if (okeylen == 0 || okeylen > 1024)
|
|
12
|
+
return Qnil;
|
|
13
|
+
u_int8_t* okey = xmalloc(okeylen);
|
|
14
|
+
VALUE out;
|
|
15
|
+
|
|
16
|
+
int ret = bcrypt_pbkdf(
|
|
17
|
+
StringValuePtr(pass), RSTRING_LEN(pass),
|
|
18
|
+
(const u_int8_t*)StringValuePtr(salt), RSTRING_LEN(salt),
|
|
19
|
+
okey, okeylen,
|
|
20
|
+
NUM2ULONG(rounds));
|
|
21
|
+
if (ret < 0) {
|
|
22
|
+
xfree(okey);
|
|
23
|
+
return Qnil;
|
|
24
|
+
}
|
|
25
|
+
out = rb_str_new((const char*)okey, okeylen);
|
|
26
|
+
xfree(okey);
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static VALUE bc_crypt_hash(VALUE self, VALUE pass, VALUE salt) {
|
|
31
|
+
u_int8_t hash[BCRYPT_HASHSIZE];
|
|
32
|
+
if (RSTRING_LEN(pass) != 64U)
|
|
33
|
+
return Qnil;
|
|
34
|
+
if (RSTRING_LEN(salt) != 64U)
|
|
35
|
+
return Qnil;
|
|
36
|
+
bcrypt_hash((u_int8_t*)StringValuePtr(pass), (u_int8_t*)StringValuePtr(salt), hash);
|
|
37
|
+
return rb_str_new((const char*)hash, sizeof(hash));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/* Create the BCryptPbkdf and BCryptPbkdf::Engine modules, and populate them with methods. */
|
|
42
|
+
void Init_bcrypt_pbkdf_ext(){
|
|
43
|
+
mBCryptPbkdf = rb_define_module("BCryptPbkdf");
|
|
44
|
+
cBCryptPbkdfEngine = rb_define_class_under(mBCryptPbkdf, "Engine", rb_cObject);
|
|
45
|
+
|
|
46
|
+
rb_define_singleton_method(cBCryptPbkdfEngine, "__bc_crypt_pbkdf", bc_crypt_pbkdf, 4);
|
|
47
|
+
rb_define_singleton_method(cBCryptPbkdfEngine, "__bc_crypt_hash", bc_crypt_hash, 2);
|
|
48
|
+
}
|