ffi-hydrogen 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +30 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +72 -0
  9. data/Rakefile +46 -0
  10. data/bench/both.rb +86 -0
  11. data/bench/encode.rb +57 -0
  12. data/bench/encrypt.rb +80 -0
  13. data/bench/init.rb +5 -0
  14. data/bin/console +14 -0
  15. data/bin/setup +8 -0
  16. data/ffi-hydrogen.gemspec +31 -0
  17. data/lib/ffi/hydrogen.rb +216 -0
  18. data/vendor/.clang-format +2 -0
  19. data/vendor/.gitignore +3 -0
  20. data/vendor/README.md +2 -0
  21. data/vendor/libhydrogen/.clang-format +95 -0
  22. data/vendor/libhydrogen/.gitignore +32 -0
  23. data/vendor/libhydrogen/.travis.yml +22 -0
  24. data/vendor/libhydrogen/LICENSE +18 -0
  25. data/vendor/libhydrogen/Makefile +61 -0
  26. data/vendor/libhydrogen/Makefile.arduino +51 -0
  27. data/vendor/libhydrogen/README.md +29 -0
  28. data/vendor/libhydrogen/hydrogen.c +18 -0
  29. data/vendor/libhydrogen/hydrogen.h +317 -0
  30. data/vendor/libhydrogen/impl/common.h +316 -0
  31. data/vendor/libhydrogen/impl/core.h +220 -0
  32. data/vendor/libhydrogen/impl/gimli-core/portable.h +39 -0
  33. data/vendor/libhydrogen/impl/gimli-core/sse2.h +97 -0
  34. data/vendor/libhydrogen/impl/gimli-core.h +25 -0
  35. data/vendor/libhydrogen/impl/hash.h +138 -0
  36. data/vendor/libhydrogen/impl/hydrogen_p.h +83 -0
  37. data/vendor/libhydrogen/impl/kdf.h +20 -0
  38. data/vendor/libhydrogen/impl/kx.h +441 -0
  39. data/vendor/libhydrogen/impl/pwhash.h +281 -0
  40. data/vendor/libhydrogen/impl/random.h +376 -0
  41. data/vendor/libhydrogen/impl/secretbox.h +236 -0
  42. data/vendor/libhydrogen/impl/sign.h +207 -0
  43. data/vendor/libhydrogen/impl/x25519.h +383 -0
  44. data/vendor/libhydrogen/library.properties +10 -0
  45. data/vendor/libhydrogen/logo.png +0 -0
  46. data/vendor/libhydrogen/tests/tests.c +431 -0
  47. data/vendor/main.c +140 -0
  48. data/vendor/stringencoders/.gitignore +25 -0
  49. data/vendor/stringencoders/.travis.yml +13 -0
  50. data/vendor/stringencoders/AUTHORS +1 -0
  51. data/vendor/stringencoders/COPYING +2 -0
  52. data/vendor/stringencoders/ChangeLog +170 -0
  53. data/vendor/stringencoders/Doxyfile +276 -0
  54. data/vendor/stringencoders/INSTALL +119 -0
  55. data/vendor/stringencoders/LICENSE +22 -0
  56. data/vendor/stringencoders/Makefile.am +3 -0
  57. data/vendor/stringencoders/NEWS +3 -0
  58. data/vendor/stringencoders/README +2 -0
  59. data/vendor/stringencoders/README.md +32 -0
  60. data/vendor/stringencoders/bootstrap.sh +3 -0
  61. data/vendor/stringencoders/configure-gcc-hardened.sh +16 -0
  62. data/vendor/stringencoders/configure.ac +44 -0
  63. data/vendor/stringencoders/doxy/footer.html +34 -0
  64. data/vendor/stringencoders/doxy/header.html +85 -0
  65. data/vendor/stringencoders/indent.sh +9 -0
  66. data/vendor/stringencoders/javascript/base64-speed.html +43 -0
  67. data/vendor/stringencoders/javascript/base64-test.html +209 -0
  68. data/vendor/stringencoders/javascript/base64.html +18 -0
  69. data/vendor/stringencoders/javascript/base64.js +176 -0
  70. data/vendor/stringencoders/javascript/qunit.css +119 -0
  71. data/vendor/stringencoders/javascript/qunit.js +1062 -0
  72. data/vendor/stringencoders/javascript/urlparse-test.html +367 -0
  73. data/vendor/stringencoders/javascript/urlparse.js +328 -0
  74. data/vendor/stringencoders/make-ci.sh +13 -0
  75. data/vendor/stringencoders/makerelease.sh +16 -0
  76. data/vendor/stringencoders/python/b85.py +176 -0
  77. data/vendor/stringencoders/src/Makefile.am +134 -0
  78. data/vendor/stringencoders/src/arraytoc.c +85 -0
  79. data/vendor/stringencoders/src/arraytoc.h +43 -0
  80. data/vendor/stringencoders/src/extern_c_begin.h +3 -0
  81. data/vendor/stringencoders/src/extern_c_end.h +3 -0
  82. data/vendor/stringencoders/src/html_named_entities_generator.py +203 -0
  83. data/vendor/stringencoders/src/modp_ascii.c +159 -0
  84. data/vendor/stringencoders/src/modp_ascii.h +162 -0
  85. data/vendor/stringencoders/src/modp_ascii_data.h +84 -0
  86. data/vendor/stringencoders/src/modp_ascii_gen.c +55 -0
  87. data/vendor/stringencoders/src/modp_b16.c +125 -0
  88. data/vendor/stringencoders/src/modp_b16.h +148 -0
  89. data/vendor/stringencoders/src/modp_b16_data.h +104 -0
  90. data/vendor/stringencoders/src/modp_b16_gen.c +65 -0
  91. data/vendor/stringencoders/src/modp_b2.c +69 -0
  92. data/vendor/stringencoders/src/modp_b2.h +130 -0
  93. data/vendor/stringencoders/src/modp_b2_data.h +44 -0
  94. data/vendor/stringencoders/src/modp_b2_gen.c +36 -0
  95. data/vendor/stringencoders/src/modp_b36.c +108 -0
  96. data/vendor/stringencoders/src/modp_b36.h +170 -0
  97. data/vendor/stringencoders/src/modp_b64.c +254 -0
  98. data/vendor/stringencoders/src/modp_b64.h +236 -0
  99. data/vendor/stringencoders/src/modp_b64_data.h +477 -0
  100. data/vendor/stringencoders/src/modp_b64_gen.c +168 -0
  101. data/vendor/stringencoders/src/modp_b64r.c +254 -0
  102. data/vendor/stringencoders/src/modp_b64r.h +242 -0
  103. data/vendor/stringencoders/src/modp_b64r_data.h +477 -0
  104. data/vendor/stringencoders/src/modp_b64w.c +254 -0
  105. data/vendor/stringencoders/src/modp_b64w.h +231 -0
  106. data/vendor/stringencoders/src/modp_b64w_data.h +477 -0
  107. data/vendor/stringencoders/src/modp_b85.c +109 -0
  108. data/vendor/stringencoders/src/modp_b85.h +171 -0
  109. data/vendor/stringencoders/src/modp_b85_data.h +36 -0
  110. data/vendor/stringencoders/src/modp_b85_gen.c +65 -0
  111. data/vendor/stringencoders/src/modp_bjavascript.c +65 -0
  112. data/vendor/stringencoders/src/modp_bjavascript.h +105 -0
  113. data/vendor/stringencoders/src/modp_bjavascript_data.h +84 -0
  114. data/vendor/stringencoders/src/modp_bjavascript_gen.c +58 -0
  115. data/vendor/stringencoders/src/modp_burl.c +228 -0
  116. data/vendor/stringencoders/src/modp_burl.h +259 -0
  117. data/vendor/stringencoders/src/modp_burl_data.h +136 -0
  118. data/vendor/stringencoders/src/modp_burl_gen.c +121 -0
  119. data/vendor/stringencoders/src/modp_html.c +128 -0
  120. data/vendor/stringencoders/src/modp_html.h +53 -0
  121. data/vendor/stringencoders/src/modp_html_named_entities.h +9910 -0
  122. data/vendor/stringencoders/src/modp_json.c +315 -0
  123. data/vendor/stringencoders/src/modp_json.h +103 -0
  124. data/vendor/stringencoders/src/modp_json_data.h +57 -0
  125. data/vendor/stringencoders/src/modp_json_gen.py +60 -0
  126. data/vendor/stringencoders/src/modp_mainpage.h +120 -0
  127. data/vendor/stringencoders/src/modp_numtoa.c +350 -0
  128. data/vendor/stringencoders/src/modp_numtoa.h +100 -0
  129. data/vendor/stringencoders/src/modp_qsiter.c +76 -0
  130. data/vendor/stringencoders/src/modp_qsiter.h +71 -0
  131. data/vendor/stringencoders/src/modp_stdint.h +43 -0
  132. data/vendor/stringencoders/src/modp_utf8.c +88 -0
  133. data/vendor/stringencoders/src/modp_utf8.h +38 -0
  134. data/vendor/stringencoders/src/modp_xml.c +311 -0
  135. data/vendor/stringencoders/src/modp_xml.h +166 -0
  136. data/vendor/stringencoders/src/stringencoders.pc +10 -0
  137. data/vendor/stringencoders/src/stringencoders.pc.in +10 -0
  138. data/vendor/stringencoders/test/Makefile.am +113 -0
  139. data/vendor/stringencoders/test/apr_base64.c +262 -0
  140. data/vendor/stringencoders/test/apr_base64.h +120 -0
  141. data/vendor/stringencoders/test/cxx_test.cc +482 -0
  142. data/vendor/stringencoders/test/minunit.h +82 -0
  143. data/vendor/stringencoders/test/modp_ascii_test.c +281 -0
  144. data/vendor/stringencoders/test/modp_b16_test.c +288 -0
  145. data/vendor/stringencoders/test/modp_b2_test.c +250 -0
  146. data/vendor/stringencoders/test/modp_b64_test.c +266 -0
  147. data/vendor/stringencoders/test/modp_b85_test.c +130 -0
  148. data/vendor/stringencoders/test/modp_bjavascript_test.c +137 -0
  149. data/vendor/stringencoders/test/modp_burl_test.c +423 -0
  150. data/vendor/stringencoders/test/modp_html_test.c +296 -0
  151. data/vendor/stringencoders/test/modp_json_test.c +336 -0
  152. data/vendor/stringencoders/test/modp_numtoa_test.c +545 -0
  153. data/vendor/stringencoders/test/modp_qsiter_test.c +280 -0
  154. data/vendor/stringencoders/test/modp_utf8_test.c +188 -0
  155. data/vendor/stringencoders/test/modp_xml_test.c +339 -0
  156. data/vendor/stringencoders/test/speedtest.c +241 -0
  157. data/vendor/stringencoders/test/speedtest_ascii.c +345 -0
  158. data/vendor/stringencoders/test/speedtest_msg.c +78 -0
  159. data/vendor/stringencoders/test/speedtest_numtoa.c +276 -0
  160. metadata +314 -0
@@ -0,0 +1,281 @@
1
+ #define hydro_pwhash_ENC_ALGBYTES 1
2
+ #define hydro_pwhash_HASH_ALGBYTES 1
3
+ #define hydro_pwhash_THREADSBYTES 1
4
+ #define hydro_pwhash_OPSLIMITBYTES 8
5
+ #define hydro_pwhash_MEMLIMITBYTES 8
6
+ #define hydro_pwhash_HASHBYTES 32
7
+ #define hydro_pwhash_SALTBYTES 16
8
+ #define hydro_pwhash_PARAMSBYTES \
9
+ (hydro_pwhash_HASH_ALGBYTES + hydro_pwhash_THREADSBYTES + hydro_pwhash_OPSLIMITBYTES + \
10
+ hydro_pwhash_MEMLIMITBYTES + hydro_pwhash_SALTBYTES + hydro_pwhash_HASHBYTES)
11
+ #define hydro_pwhash_ENC_ALG 0x01
12
+ #define hydro_pwhash_HASH_ALG 0x01
13
+ #define hydro_pwhash_CONTEXT "hydro_pw"
14
+
15
+ static int
16
+ _hydro_pwhash_hash(uint8_t out[hydro_random_SEEDBYTES], size_t h_len,
17
+ const uint8_t salt[hydro_pwhash_SALTBYTES], const char *passwd,
18
+ size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES],
19
+ const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
20
+ size_t memlimit, uint8_t threads)
21
+ {
22
+ _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
23
+ hydro_hash_state h_st;
24
+ uint8_t tmp64_u8[8];
25
+ uint64_t i;
26
+ uint8_t tmp8;
27
+
28
+ COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES >= hydro_hash_KEYBYTES);
29
+ hydro_hash_init(&h_st, ctx, master_key);
30
+
31
+ STORE64_LE(tmp64_u8, (uint64_t) passwd_len);
32
+ hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
33
+ hydro_hash_update(&h_st, passwd, passwd_len);
34
+
35
+ hydro_hash_update(&h_st, salt, hydro_pwhash_SALTBYTES);
36
+
37
+ tmp8 = hydro_pwhash_HASH_ALG;
38
+ hydro_hash_update(&h_st, &tmp8, 1);
39
+
40
+ hydro_hash_update(&h_st, &threads, 1);
41
+
42
+ STORE64_LE(tmp64_u8, (uint64_t) memlimit);
43
+ hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
44
+
45
+ STORE64_LE(tmp64_u8, (uint64_t) h_len);
46
+ hydro_hash_update(&h_st, tmp64_u8, sizeof tmp64_u8);
47
+
48
+ hydro_hash_final(&h_st, (uint8_t *) (void *) &state, sizeof state);
49
+
50
+ gimli_core_u8(state, 1);
51
+ COMPILER_ASSERT(gimli_RATE >= 8);
52
+ for (i = 0; i < opslimit; i++) {
53
+ mem_zero(state, gimli_RATE);
54
+ STORE64_LE(state, i);
55
+ gimli_core_u8(state, 0);
56
+ }
57
+ mem_zero(state, gimli_RATE);
58
+
59
+ COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY);
60
+ memcpy(out, state + gimli_RATE, hydro_random_SEEDBYTES);
61
+ hydro_memzero(state, sizeof state);
62
+
63
+ return 0;
64
+ }
65
+
66
+ void
67
+ hydro_pwhash_keygen(uint8_t master_key[hydro_pwhash_MASTERKEYBYTES])
68
+ {
69
+ hydro_random_buf(master_key, hydro_pwhash_MASTERKEYBYTES);
70
+ }
71
+
72
+ int
73
+ hydro_pwhash_deterministic(uint8_t *h, size_t h_len, const char *passwd, size_t passwd_len,
74
+ const char ctx[hydro_pwhash_CONTEXTBYTES],
75
+ const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
76
+ size_t memlimit, uint8_t threads)
77
+ {
78
+ uint8_t seed[hydro_random_SEEDBYTES];
79
+
80
+ COMPILER_ASSERT(sizeof zero >= hydro_pwhash_SALTBYTES);
81
+ COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES);
82
+
83
+ (void) memlimit;
84
+ if (_hydro_pwhash_hash(seed, h_len, zero, passwd, passwd_len, ctx, master_key, opslimit,
85
+ memlimit, threads) != 0) {
86
+ return -1;
87
+ }
88
+ hydro_random_buf_deterministic(h, h_len, seed);
89
+ hydro_memzero(seed, sizeof seed);
90
+
91
+ return 0;
92
+ }
93
+
94
+ int
95
+ hydro_pwhash_create(uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd, size_t passwd_len,
96
+ const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
97
+ size_t memlimit, uint8_t threads)
98
+ {
99
+ uint8_t *const enc_alg = &stored[0];
100
+ uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
101
+ uint8_t *const hash_alg = &secretbox[hydro_secretbox_HEADERBYTES];
102
+ uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
103
+ uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
104
+ uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
105
+ uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
106
+ uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
107
+
108
+ COMPILER_ASSERT(hydro_pwhash_STOREDBYTES >= hydro_pwhash_ENC_ALGBYTES +
109
+ hydro_secretbox_HEADERBYTES +
110
+ hydro_pwhash_PARAMSBYTES);
111
+ (void) memlimit;
112
+ mem_zero(stored, hydro_pwhash_STOREDBYTES);
113
+ *enc_alg = hydro_pwhash_ENC_ALG;
114
+ *hash_alg = hydro_pwhash_HASH_ALG;
115
+ *threads_u8 = threads;
116
+ STORE64_LE(opslimit_u8, opslimit);
117
+ STORE64_LE(memlimit_u8, (uint64_t) memlimit);
118
+ hydro_random_buf(salt, hydro_pwhash_SALTBYTES);
119
+
120
+ COMPILER_ASSERT(sizeof zero >= hydro_pwhash_MASTERKEYBYTES);
121
+ if (_hydro_pwhash_hash(h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len,
122
+ hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) != 0) {
123
+ return -1;
124
+ }
125
+ COMPILER_ASSERT(hydro_pwhash_MASTERKEYBYTES == hydro_secretbox_KEYBYTES);
126
+
127
+ return hydro_secretbox_encrypt(secretbox, hash_alg, hydro_pwhash_PARAMSBYTES,
128
+ (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key);
129
+ }
130
+
131
+ static int
132
+ _hydro_pwhash_verify(uint8_t computed_h[hydro_pwhash_HASHBYTES],
133
+ const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
134
+ size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
135
+ uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
136
+ {
137
+ const uint8_t *const enc_alg = &stored[0];
138
+ const uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
139
+
140
+ uint8_t params[hydro_pwhash_PARAMSBYTES];
141
+ uint8_t *const hash_alg = &params[0];
142
+ uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
143
+ uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
144
+ uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
145
+ uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
146
+ uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
147
+
148
+ uint64_t opslimit;
149
+ size_t memlimit;
150
+ uint8_t threads;
151
+
152
+ (void) memlimit;
153
+ if (*enc_alg != hydro_pwhash_ENC_ALG) {
154
+ return -1;
155
+ }
156
+ if (hydro_secretbox_decrypt(params, secretbox,
157
+ hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
158
+ (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
159
+ return -1;
160
+ }
161
+ if (*hash_alg != hydro_pwhash_HASH_ALG || (opslimit = LOAD64_LE(opslimit_u8)) > opslimit_max ||
162
+ (memlimit = (size_t) LOAD64_LE(memlimit_u8)) > memlimit_max ||
163
+ (threads = *threads_u8) > threads_max) {
164
+ return -1;
165
+ }
166
+ if (_hydro_pwhash_hash(computed_h, hydro_pwhash_HASHBYTES, salt, passwd, passwd_len,
167
+ hydro_pwhash_CONTEXT, zero, opslimit, memlimit, threads) == 0 &&
168
+ hydro_equal(computed_h, h, hydro_pwhash_HASHBYTES) == 1) {
169
+ return 0;
170
+ }
171
+ return -1;
172
+ }
173
+
174
+ int
175
+ hydro_pwhash_verify(const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
176
+ size_t passwd_len, const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
177
+ uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
178
+ {
179
+ uint8_t computed_h[hydro_pwhash_HASHBYTES];
180
+ int ret;
181
+
182
+ ret = _hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max,
183
+ memlimit_max, threads_max);
184
+ hydro_memzero(computed_h, sizeof computed_h);
185
+
186
+ return ret;
187
+ }
188
+
189
+ int
190
+ hydro_pwhash_derive_static_key(uint8_t *static_key, size_t static_key_len,
191
+ const uint8_t stored[hydro_pwhash_STOREDBYTES], const char *passwd,
192
+ size_t passwd_len, const char ctx[hydro_pwhash_CONTEXTBYTES],
193
+ const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
194
+ uint64_t opslimit_max, size_t memlimit_max, uint8_t threads_max)
195
+ {
196
+ uint8_t computed_h[hydro_pwhash_HASHBYTES];
197
+
198
+ if (_hydro_pwhash_verify(computed_h, stored, passwd, passwd_len, master_key, opslimit_max,
199
+ memlimit_max, threads_max) != 0) {
200
+ hydro_memzero(computed_h, sizeof computed_h);
201
+ return -1;
202
+ }
203
+ COMPILER_ASSERT(hydro_kdf_CONTEXTBYTES <= hydro_pwhash_CONTEXTBYTES);
204
+ COMPILER_ASSERT(hydro_kdf_KEYBYTES <= hydro_pwhash_HASHBYTES);
205
+ hydro_kdf_derive_from_key(static_key, static_key_len, 0, ctx, computed_h);
206
+ hydro_memzero(computed_h, sizeof computed_h);
207
+
208
+ return 0;
209
+ }
210
+
211
+ int
212
+ hydro_pwhash_reencrypt(uint8_t stored[hydro_pwhash_STOREDBYTES],
213
+ const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES],
214
+ const uint8_t new_master_key[hydro_pwhash_MASTERKEYBYTES])
215
+ {
216
+ uint8_t *const enc_alg = &stored[0];
217
+ uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
218
+ uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES];
219
+
220
+ if (*enc_alg != hydro_pwhash_ENC_ALG) {
221
+ return -1;
222
+ }
223
+ if (hydro_secretbox_decrypt(secretbox, secretbox,
224
+ hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
225
+ (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
226
+ return -1;
227
+ }
228
+ memmove(params, secretbox, hydro_pwhash_PARAMSBYTES);
229
+ return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg,
230
+ hydro_pwhash_CONTEXT, new_master_key);
231
+ }
232
+
233
+ int
234
+ hydro_pwhash_upgrade(uint8_t stored[hydro_pwhash_STOREDBYTES],
235
+ const uint8_t master_key[hydro_pwhash_MASTERKEYBYTES], uint64_t opslimit,
236
+ size_t memlimit, uint8_t threads)
237
+ {
238
+ uint8_t *const enc_alg = &stored[0];
239
+ uint8_t *const secretbox = &enc_alg[hydro_pwhash_ENC_ALGBYTES];
240
+ uint8_t *const params = &secretbox[hydro_secretbox_HEADERBYTES];
241
+ uint8_t *const hash_alg = &params[0];
242
+ uint8_t *const threads_u8 = &hash_alg[hydro_pwhash_HASH_ALGBYTES];
243
+ uint8_t *const opslimit_u8 = &threads_u8[hydro_pwhash_THREADSBYTES];
244
+ uint8_t *const memlimit_u8 = &opslimit_u8[hydro_pwhash_OPSLIMITBYTES];
245
+ uint8_t *const salt = &memlimit_u8[hydro_pwhash_MEMLIMITBYTES];
246
+ uint8_t *const h = &salt[hydro_pwhash_SALTBYTES];
247
+
248
+ _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
249
+ uint64_t i;
250
+ uint64_t opslimit_prev;
251
+
252
+ if (*enc_alg != hydro_pwhash_ENC_ALG) {
253
+ return -1;
254
+ }
255
+ if (hydro_secretbox_decrypt(secretbox, secretbox,
256
+ hydro_secretbox_HEADERBYTES + hydro_pwhash_PARAMSBYTES,
257
+ (uint64_t) *enc_alg, hydro_pwhash_CONTEXT, master_key) != 0) {
258
+ return -1;
259
+ }
260
+ memmove(params, secretbox, hydro_pwhash_PARAMSBYTES);
261
+ opslimit_prev = LOAD64_LE(opslimit_u8);
262
+ if (*hash_alg != hydro_pwhash_HASH_ALG) {
263
+ mem_zero(stored, hydro_pwhash_STOREDBYTES);
264
+ return -1;
265
+ }
266
+ COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_CAPACITY);
267
+ memcpy(state + gimli_RATE, h, hydro_random_SEEDBYTES);
268
+ for (i = opslimit_prev; i < opslimit; i++) {
269
+ mem_zero(state, gimli_RATE);
270
+ STORE64_LE(state, i);
271
+ gimli_core_u8(state, 0);
272
+ }
273
+ mem_zero(state, gimli_RATE);
274
+ memcpy(h, state + gimli_RATE, hydro_random_SEEDBYTES);
275
+ *threads_u8 = threads;
276
+ STORE64_LE(opslimit_u8, opslimit);
277
+ STORE64_LE(memlimit_u8, (uint64_t) memlimit);
278
+
279
+ return hydro_secretbox_encrypt(secretbox, params, hydro_pwhash_PARAMSBYTES, (uint64_t) *enc_alg,
280
+ hydro_pwhash_CONTEXT, master_key);
281
+ }
@@ -0,0 +1,376 @@
1
+ static TLS struct {
2
+ _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
3
+ uint64_t counter;
4
+ uint8_t initialized;
5
+ uint8_t available;
6
+ } hydro_random_context;
7
+
8
+ #if defined(AVR) && !defined(__unix__)
9
+ #include <Arduino.h>
10
+
11
+ static bool
12
+ hydro_random_rbit(unsigned int x)
13
+ {
14
+ size_t i;
15
+ bool res = 0;
16
+
17
+ for (i = 0; i < sizeof x; i++) {
18
+ res ^= ((x >> i) & 1);
19
+ }
20
+ return res;
21
+ }
22
+
23
+ static int
24
+ hydro_random_init(void)
25
+ {
26
+ const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
27
+ hydro_hash_state st;
28
+ uint16_t ebits = 0;
29
+ uint16_t tc;
30
+ bool a, b;
31
+
32
+ cli();
33
+ MCUSR = 0;
34
+ WDTCSR |= _BV(WDCE) | _BV(WDE);
35
+ WDTCSR = _BV(WDIE);
36
+ sei();
37
+
38
+ hydro_hash_init(&st, ctx, NULL);
39
+
40
+ while (ebits < 256) {
41
+ delay(1);
42
+ tc = TCNT1;
43
+ hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc);
44
+ a = hydro_random_rbit(tc);
45
+ delay(1);
46
+ tc = TCNT1;
47
+ b = hydro_random_rbit(tc);
48
+ hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc);
49
+ if (a == b) {
50
+ continue;
51
+ }
52
+ hydro_hash_update(&st, (const uint8_t *) &b, sizeof b);
53
+ ebits++;
54
+ }
55
+
56
+ cli();
57
+ MCUSR = 0;
58
+ WDTCSR |= _BV(WDCE) | _BV(WDE);
59
+ WDTCSR = 0;
60
+ sei();
61
+
62
+ hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
63
+ hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
64
+
65
+ return 0;
66
+ }
67
+
68
+ ISR(WDT_vect) {}
69
+
70
+ #elif (defined(ESP32) || defined(ESP8266)) && !defined(__unix__)
71
+
72
+ // Important: RF *must* be activated on ESP board
73
+ // https://techtutorialsx.com/2017/12/22/esp32-arduino-random-number-generation/
74
+
75
+ #include <esp_system.h>
76
+
77
+ static int
78
+ hydro_random_init(void)
79
+ {
80
+ const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
81
+ hydro_hash_state st;
82
+ uint16_t ebits = 0;
83
+ uint16_t tc;
84
+ bool a, b;
85
+
86
+ hydro_hash_init(&st, ctx, NULL);
87
+
88
+ while (ebits < 256) {
89
+ uint32_t r = esp_random();
90
+
91
+ delay(10);
92
+ hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
93
+ ebits += 32;
94
+ }
95
+
96
+ hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
97
+ hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
98
+
99
+ return 0;
100
+ }
101
+
102
+ #elif defined(_WIN32)
103
+
104
+ #include <windows.h>
105
+ #define RtlGenRandom SystemFunction036
106
+ #if defined(__cplusplus)
107
+ extern "C"
108
+ #endif
109
+ BOOLEAN NTAPI
110
+ RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
111
+ #pragma comment(lib, "advapi32.lib")
112
+
113
+ static int
114
+ hydro_random_init(void)
115
+ {
116
+ if (!RtlGenRandom((PVOID) hydro_random_context.state,
117
+ (ULONG) sizeof hydro_random_context.state)) {
118
+ return -1;
119
+ }
120
+ hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);
121
+ return 0;
122
+ }
123
+
124
+ #elif defined(__unix__)
125
+
126
+ #include <errno.h>
127
+ #include <fcntl.h>
128
+ #ifdef __linux__
129
+ #include <poll.h>
130
+ #endif
131
+ #include <sys/types.h>
132
+ #include <unistd.h>
133
+
134
+ #ifdef __linux__
135
+ static int
136
+ hydro_random_block_on_dev_random(void)
137
+ {
138
+ struct pollfd pfd;
139
+ int fd;
140
+ int pret;
141
+
142
+ fd = open("/dev/random", O_RDONLY);
143
+ if (fd == -1) {
144
+ return 0;
145
+ }
146
+ pfd.fd = fd;
147
+ pfd.events = POLLIN;
148
+ pfd.revents = 0;
149
+ do {
150
+ pret = poll(&pfd, 1, -1);
151
+ } while (pret < 0 && (errno == EINTR || errno == EAGAIN));
152
+ if (pret != 1) {
153
+ (void) close(fd);
154
+ errno = EIO;
155
+ return -1;
156
+ }
157
+ return close(fd);
158
+ }
159
+ #endif
160
+
161
+ static ssize_t
162
+ hydro_random_safe_read(const int fd, void *const buf_, size_t len)
163
+ {
164
+ unsigned char *buf = (unsigned char *) buf_;
165
+ ssize_t readnb;
166
+
167
+ do {
168
+ while ((readnb = read(fd, buf, len)) < (ssize_t) 0 && (errno == EINTR || errno == EAGAIN))
169
+ ;
170
+ if (readnb < (ssize_t) 0) {
171
+ return readnb;
172
+ }
173
+ if (readnb == (ssize_t) 0) {
174
+ break;
175
+ }
176
+ len -= (size_t) readnb;
177
+ buf += readnb;
178
+ } while (len > (ssize_t) 0);
179
+
180
+ return (ssize_t)(buf - (unsigned char *) buf_);
181
+ }
182
+
183
+ static int
184
+ hydro_random_init(void)
185
+ {
186
+ uint8_t tmp[gimli_BLOCKBYTES + 8];
187
+ int fd;
188
+ int ret = -1;
189
+
190
+ #ifdef __linux__
191
+ if (hydro_random_block_on_dev_random() != 0) {
192
+ return -1;
193
+ }
194
+ #endif
195
+ do {
196
+ fd = open("/dev/urandom", O_RDONLY);
197
+ if (fd == -1 && errno != EINTR) {
198
+ return -1;
199
+ }
200
+ } while (fd == -1);
201
+ if (hydro_random_safe_read(fd, tmp, sizeof tmp) == (ssize_t) sizeof tmp) {
202
+ memcpy(hydro_random_context.state, tmp, gimli_BLOCKBYTES);
203
+ memcpy(&hydro_random_context.counter, tmp + gimli_BLOCKBYTES, 8);
204
+ hydro_memzero(tmp, sizeof tmp);
205
+ ret = 0;
206
+ }
207
+ ret |= close(fd);
208
+
209
+ return ret;
210
+ }
211
+
212
+ #elif defined(TARGET_LIKE_MBED)
213
+
214
+ #include <mbedtls/ctr_drbg.h>
215
+ #include <mbedtls/entropy.h>
216
+
217
+ #if defined(MBEDTLS_ENTROPY_C)
218
+
219
+ static int
220
+ hydro_random_init(void)
221
+ {
222
+ mbedtls_entropy_context entropy;
223
+ uint16_t pos = 0;
224
+
225
+ mbedtls_entropy_init(&entropy);
226
+
227
+ // Pull data directly out of the entropy pool for the state, as it's small enough.
228
+ if (mbedtls_entropy_func(&entropy, (uint8_t *) &hydro_random_context.counter,
229
+ sizeof hydro_random_context.counter) != 0) {
230
+ return -1;
231
+ }
232
+ // mbedtls_entropy_func can't provide more than MBEDTLS_ENTROPY_BLOCK_SIZE in one go.
233
+ // This constant depends of mbedTLS configuration (whether the PRNG is backed by SHA256/SHA512
234
+ // at this time) Therefore, if necessary, we get entropy multiple times.
235
+
236
+ do {
237
+ const uint8_t dataLeftToConsume = gimli_BLOCKBYTES - pos;
238
+ const uint8_t currentChunkSize = (dataLeftToConsume > MBEDTLS_ENTROPY_BLOCK_SIZE)
239
+ ? MBEDTLS_ENTROPY_BLOCK_SIZE
240
+ : dataLeftToConsume;
241
+
242
+ // Forces mbedTLS to fetch fresh entropy, then get some to feed libhydrogen.
243
+ if (mbedtls_entropy_gather(&entropy) != 0 ||
244
+ mbedtls_entropy_func(&entropy, &hydro_random_context.state[pos], currentChunkSize) != 0) {
245
+ return -1;
246
+ }
247
+ pos += MBEDTLS_ENTROPY_BLOCK_SIZE;
248
+ } while (pos < gimli_BLOCKBYTES);
249
+
250
+ mbedtls_entropy_free(&entropy);
251
+
252
+ return 0;
253
+ }
254
+
255
+ #else
256
+ #error Need an entropy source
257
+ #endif
258
+
259
+ #else
260
+ #error Unsupported platform
261
+ #endif
262
+
263
+ static void
264
+ hydro_random_check_initialized(void)
265
+ {
266
+ if (hydro_random_context.initialized == 0) {
267
+ if (hydro_random_init() != 0) {
268
+ abort();
269
+ }
270
+ gimli_core_u8(hydro_random_context.state, 0);
271
+ hydro_random_ratchet();
272
+ hydro_random_context.initialized = 1;
273
+ }
274
+ }
275
+
276
+ void
277
+ hydro_random_ratchet(void)
278
+ {
279
+ mem_zero(hydro_random_context.state, gimli_RATE);
280
+ STORE64_LE(hydro_random_context.state, hydro_random_context.counter);
281
+ hydro_random_context.counter++;
282
+ gimli_core_u8(hydro_random_context.state, 0);
283
+ hydro_random_context.available = gimli_RATE;
284
+ }
285
+
286
+ uint32_t
287
+ hydro_random_u32(void)
288
+ {
289
+ uint32_t v;
290
+
291
+ hydro_random_check_initialized();
292
+ if (hydro_random_context.available < 4) {
293
+ hydro_random_ratchet();
294
+ }
295
+ memcpy(&v, &hydro_random_context.state[gimli_RATE - hydro_random_context.available], 4);
296
+ hydro_random_context.available -= 4;
297
+
298
+ return v;
299
+ }
300
+
301
+ uint32_t
302
+ hydro_random_uniform(const uint32_t upper_bound)
303
+ {
304
+ uint32_t min;
305
+ uint32_t r;
306
+
307
+ if (upper_bound < 2U) {
308
+ return 0;
309
+ }
310
+ min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */
311
+ do {
312
+ r = hydro_random_u32();
313
+ } while (r < min);
314
+ /* r is now clamped to a set whose size mod upper_bound == 0
315
+ * the worst case (2**31+1) requires 2 attempts on average */
316
+
317
+ return r % upper_bound;
318
+ }
319
+
320
+ void
321
+ hydro_random_buf(void *out, size_t out_len)
322
+ {
323
+ uint8_t *p = (uint8_t *) out;
324
+ size_t i;
325
+ size_t leftover;
326
+
327
+ for (i = 0; i < out_len / gimli_RATE; i++) {
328
+ gimli_core_u8(hydro_random_context.state, 0);
329
+ memcpy(p + i * gimli_RATE, hydro_random_context.state, gimli_RATE);
330
+ }
331
+ leftover = out_len % gimli_RATE;
332
+ if (leftover != 0) {
333
+ gimli_core_u8(hydro_random_context.state, 0);
334
+ mem_cpy(p + i * gimli_RATE, hydro_random_context.state, leftover);
335
+ }
336
+ hydro_random_ratchet();
337
+ }
338
+
339
+ void
340
+ hydro_random_buf_deterministic(void *out, size_t out_len,
341
+ const uint8_t seed[hydro_random_SEEDBYTES])
342
+ {
343
+ static const uint8_t prefix[] = { 7, 'd', 'r', 'b', 'g', '2', '5', '6' };
344
+ _hydro_attr_aligned_(16) uint8_t state[gimli_BLOCKBYTES];
345
+ uint8_t * p = (uint8_t *) out;
346
+ size_t i;
347
+ size_t leftover;
348
+
349
+ mem_zero(state, gimli_BLOCKBYTES);
350
+ COMPILER_ASSERT(sizeof prefix + 8 <= gimli_RATE);
351
+ memcpy(state, prefix, sizeof prefix);
352
+ STORE64_LE(state + sizeof prefix, (uint64_t) out_len);
353
+ gimli_core_u8(state, 1);
354
+ COMPILER_ASSERT(hydro_random_SEEDBYTES == gimli_RATE * 2);
355
+ mem_xor(state, seed, gimli_RATE);
356
+ gimli_core_u8(state, 2);
357
+ mem_xor(state, seed + gimli_RATE, gimli_RATE);
358
+ gimli_core_u8(state, 2);
359
+ for (i = 0; i < out_len / gimli_RATE; i++) {
360
+ gimli_core_u8(state, 0);
361
+ memcpy(p + i * gimli_RATE, state, gimli_RATE);
362
+ }
363
+ leftover = out_len % gimli_RATE;
364
+ if (leftover != 0) {
365
+ gimli_core_u8(state, 0);
366
+ mem_cpy(p + i * gimli_RATE, state, leftover);
367
+ }
368
+ hydro_random_ratchet();
369
+ }
370
+
371
+ void
372
+ hydro_random_reseed(void)
373
+ {
374
+ hydro_random_context.initialized = 0;
375
+ hydro_random_check_initialized();
376
+ }