ffi-hydrogen 0.1.0

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.
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
+ }