yescrypt 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.
@@ -0,0 +1,43 @@
1
+ /*
2
+ * SHA-256 implementation for yescrypt.
3
+ * Based on the public domain implementation by Colin Percival.
4
+ *
5
+ * Copyright (c) 2009 Colin Percival
6
+ * Copyright (c) 2013-2021 Alexander Peslyak
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted.
10
+ */
11
+
12
+ #ifndef SHA256_H
13
+ #define SHA256_H
14
+
15
+ #include <stddef.h>
16
+ #include <stdint.h>
17
+
18
+ typedef struct {
19
+ uint32_t state[8];
20
+ uint64_t count;
21
+ uint8_t buf[64];
22
+ } SHA256_CTX;
23
+
24
+ void SHA256_Init(SHA256_CTX *ctx);
25
+ void SHA256_Update(SHA256_CTX *ctx, const void *in, size_t len);
26
+ void SHA256_Final(uint8_t digest[32], SHA256_CTX *ctx);
27
+
28
+ /* HMAC-SHA256 */
29
+ typedef struct {
30
+ SHA256_CTX ictx;
31
+ SHA256_CTX octx;
32
+ } HMAC_SHA256_CTX;
33
+
34
+ void HMAC_SHA256_Init(HMAC_SHA256_CTX *ctx, const void *key, size_t keylen);
35
+ void HMAC_SHA256_Update(HMAC_SHA256_CTX *ctx, const void *in, size_t len);
36
+ void HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX *ctx);
37
+
38
+ /* PBKDF2-HMAC-SHA256 */
39
+ void PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen,
40
+ const uint8_t *salt, size_t saltlen,
41
+ uint64_t c, uint8_t *buf, size_t dkLen);
42
+
43
+ #endif /* SHA256_H */
@@ -0,0 +1,381 @@
1
+ /*
2
+ * yescrypt common functions: encoding, decoding, salt generation.
3
+ *
4
+ * Copyright (c) 2013-2021 Alexander Peslyak
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted.
9
+ */
10
+
11
+ #include <string.h>
12
+ #include <stdlib.h>
13
+ #include <stdint.h>
14
+
15
+ #include "yescrypt.h"
16
+ #include "insecure_memzero.h"
17
+ #include "sha256.h"
18
+
19
+ /* Base64 encoding table (crypt-style, ./0-9A-Za-z) */
20
+ static const char *itoa64 =
21
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
22
+
23
+ static uint8_t *encode64_uint32(uint8_t *dst, size_t dstlen,
24
+ uint32_t src, uint32_t srcbits)
25
+ {
26
+ uint32_t bit;
27
+ for (bit = 0; bit < srcbits; bit += 6) {
28
+ if (dstlen < 1)
29
+ return NULL;
30
+ *dst++ = itoa64[src & 0x3f];
31
+ dstlen--;
32
+ src >>= 6;
33
+ }
34
+ return dst;
35
+ }
36
+
37
+ static const uint8_t *decode64_uint32(uint32_t *dst, uint32_t dstbits,
38
+ const uint8_t *src)
39
+ {
40
+ uint32_t bit;
41
+ uint32_t val = 0;
42
+ for (bit = 0; bit < dstbits; bit += 6) {
43
+ uint32_t c = *src++;
44
+ if (c == '\0')
45
+ return NULL;
46
+ const char *p = strchr(itoa64, c);
47
+ if (!p)
48
+ return NULL;
49
+ val |= (uint32_t)(p - itoa64) << bit;
50
+ }
51
+ *dst = val;
52
+ return src;
53
+ }
54
+
55
+ static uint8_t *encode64(uint8_t *dst, size_t dstlen,
56
+ const uint8_t *src, size_t srclen)
57
+ {
58
+ size_t i;
59
+ for (i = 0; i < srclen; ) {
60
+ uint8_t *dnext;
61
+ uint32_t value = 0, bits = 0;
62
+ do {
63
+ value |= (uint32_t)src[i++] << bits;
64
+ bits += 8;
65
+ } while (bits < 24 && i < srclen);
66
+ dnext = encode64_uint32(dst, dstlen, value, bits);
67
+ if (!dnext)
68
+ return NULL;
69
+ dstlen -= (dnext - dst);
70
+ dst = dnext;
71
+ }
72
+ return dst;
73
+ }
74
+
75
+ static const uint8_t *decode64(uint8_t *dst, size_t *dstlen,
76
+ const uint8_t *src)
77
+ {
78
+ size_t len = 0;
79
+ size_t maxlen = *dstlen;
80
+
81
+ while (*src) {
82
+ uint32_t c = *src;
83
+ if (!strchr(itoa64, c))
84
+ break;
85
+
86
+ uint32_t value = 0;
87
+ uint32_t bits = 0;
88
+ const uint8_t *snext = src;
89
+ do {
90
+ const char *p = strchr(itoa64, *snext);
91
+ if (!p)
92
+ break;
93
+ value |= (uint32_t)(p - itoa64) << bits;
94
+ bits += 6;
95
+ snext++;
96
+ } while (bits < 24 && *snext && strchr(itoa64, *snext));
97
+
98
+ src = snext;
99
+ while (bits >= 8) {
100
+ if (len >= maxlen)
101
+ return NULL;
102
+ dst[len++] = value & 0xff;
103
+ value >>= 8;
104
+ bits -= 8;
105
+ }
106
+ }
107
+
108
+ *dstlen = len;
109
+ return src;
110
+ }
111
+
112
+ /* Memory allocation and initialization */
113
+ int yescrypt_init_local(yescrypt_local_t *local)
114
+ {
115
+ if (!local)
116
+ return -1;
117
+ local->base = NULL;
118
+ local->aligned_size = 0;
119
+ local->aligned = NULL;
120
+ return 0;
121
+ }
122
+
123
+ int yescrypt_free_local(yescrypt_local_t *local)
124
+ {
125
+ if (!local)
126
+ return -1;
127
+ if (local->base) {
128
+ insecure_memzero(local->base, local->aligned_size);
129
+ free(local->base);
130
+ }
131
+ local->base = NULL;
132
+ local->aligned_size = 0;
133
+ local->aligned = NULL;
134
+ return 0;
135
+ }
136
+
137
+ int yescrypt_init_shared(yescrypt_shared_t *shared)
138
+ {
139
+ if (!shared)
140
+ return -1;
141
+ shared->region.base = NULL;
142
+ shared->region.aligned_size = 0;
143
+ shared->region.aligned = NULL;
144
+ shared->mask1 = 0;
145
+ shared->N = 0;
146
+ shared->dummy = 0;
147
+ return 0;
148
+ }
149
+
150
+ int yescrypt_free_shared(yescrypt_shared_t *shared)
151
+ {
152
+ if (!shared)
153
+ return -1;
154
+ if (shared->region.base) {
155
+ free(shared->region.base);
156
+ }
157
+ memset(shared, 0, sizeof(*shared));
158
+ return 0;
159
+ }
160
+
161
+ /* Ensure local storage has enough room */
162
+ int yescrypt_ensure_local(yescrypt_local_t *local, size_t need)
163
+ {
164
+ if (local->aligned_size >= need)
165
+ return 0;
166
+
167
+ if (local->base)
168
+ free(local->base);
169
+
170
+ local->base = malloc(need);
171
+ if (!local->base) {
172
+ local->aligned_size = 0;
173
+ local->aligned = NULL;
174
+ return -1;
175
+ }
176
+ local->aligned_size = need;
177
+ local->aligned = local->base;
178
+ return 0;
179
+ }
180
+
181
+ /* Generate a yescrypt setting/salt string.
182
+ * Format: $y$j<params>$<salt>$
183
+ * where params encode N_log2, r, p, t, flags
184
+ */
185
+ uint8_t *yescrypt_gensalt(
186
+ uint32_t N_log2, uint32_t r, uint32_t p, uint32_t t,
187
+ yescrypt_flags_t flags,
188
+ const uint8_t *src, size_t srclen,
189
+ uint8_t *buf, size_t buflen)
190
+ {
191
+ uint8_t *dst = buf;
192
+ uint8_t *end = buf + buflen - 1; /* leave room for NUL */
193
+
194
+ if (buflen < 32 || !src || srclen < 1)
195
+ return NULL;
196
+
197
+ /* Prefix */
198
+ *dst++ = '$';
199
+ *dst++ = 'y';
200
+ *dst++ = '$';
201
+
202
+ /* Flavor indicator */
203
+ *dst++ = 'j';
204
+
205
+ /* Encode params: N_log2 in 6 bits */
206
+ dst = encode64_uint32(dst, end - dst, N_log2, 6);
207
+ if (!dst) return NULL;
208
+
209
+ /* r in 30 bits */
210
+ dst = encode64_uint32(dst, end - dst, r, 30);
211
+ if (!dst) return NULL;
212
+
213
+ /* p in 30 bits */
214
+ dst = encode64_uint32(dst, end - dst, p, 30);
215
+ if (!dst) return NULL;
216
+
217
+ /* t in 6 bits */
218
+ dst = encode64_uint32(dst, end - dst, t, 6);
219
+ if (!dst) return NULL;
220
+
221
+ /* flags in 6 bits */
222
+ dst = encode64_uint32(dst, end - dst, (uint32_t)flags, 6);
223
+ if (!dst) return NULL;
224
+
225
+ *dst++ = '$';
226
+
227
+ /* Encode salt */
228
+ dst = encode64(dst, end - dst, src, srclen);
229
+ if (!dst) return NULL;
230
+
231
+ *dst++ = '$';
232
+ *dst = '\0';
233
+
234
+ return buf;
235
+ }
236
+
237
+ /* Decode a setting string to extract params */
238
+ static const uint8_t *yescrypt_decode_params(
239
+ const uint8_t *setting,
240
+ uint32_t *N_log2, uint32_t *r, uint32_t *p, uint32_t *t,
241
+ yescrypt_flags_t *flags,
242
+ const uint8_t **salt, size_t *saltlen)
243
+ {
244
+ const uint8_t *src;
245
+
246
+ /* Check prefix $y$j */
247
+ if (setting[0] != '$' || setting[1] != 'y' ||
248
+ setting[2] != '$' || setting[3] != 'j')
249
+ return NULL;
250
+
251
+ src = setting + 4;
252
+
253
+ src = decode64_uint32(N_log2, 6, src);
254
+ if (!src) return NULL;
255
+
256
+ src = decode64_uint32(r, 30, src);
257
+ if (!src) return NULL;
258
+
259
+ src = decode64_uint32(p, 30, src);
260
+ if (!src) return NULL;
261
+
262
+ src = decode64_uint32(t, 6, src);
263
+ if (!src) return NULL;
264
+
265
+ uint32_t f;
266
+ src = decode64_uint32(&f, 6, src);
267
+ if (!src) return NULL;
268
+ *flags = (yescrypt_flags_t)f;
269
+
270
+ if (*src != '$')
271
+ return NULL;
272
+ src++;
273
+
274
+ *salt = src;
275
+
276
+ /* Find end of salt */
277
+ const uint8_t *sEnd = (const uint8_t *)strchr((const char *)src, '$');
278
+ if (!sEnd)
279
+ return NULL;
280
+
281
+ *saltlen = sEnd - src;
282
+
283
+ return sEnd + 1; /* points past the trailing $ */
284
+ }
285
+
286
+ /* Public wrapper: decode params only (no salt output) for Ruby binding */
287
+ const uint8_t *yescrypt_decode_params_ext(
288
+ const uint8_t *setting,
289
+ uint32_t *N_log2, uint32_t *r, uint32_t *p, uint32_t *t,
290
+ yescrypt_flags_t *flags)
291
+ {
292
+ const uint8_t *salt;
293
+ size_t saltlen;
294
+ return yescrypt_decode_params(setting, N_log2, r, p, t, flags,
295
+ &salt, &saltlen);
296
+ }
297
+
298
+ /* Hash a password with yescrypt, crypt-style */
299
+ uint8_t *yescrypt_r(
300
+ const yescrypt_shared_t *shared,
301
+ yescrypt_local_t *local,
302
+ const uint8_t *passwd, size_t passwdlen,
303
+ const uint8_t *setting,
304
+ uint8_t *buf, size_t buflen)
305
+ {
306
+ uint32_t N_log2, r, p, t;
307
+ yescrypt_flags_t flags;
308
+ const uint8_t *salt_encoded;
309
+ size_t salt_encoded_len;
310
+ uint8_t salt_decoded[64];
311
+ size_t salt_decoded_len;
312
+ uint8_t dk[32];
313
+ uint8_t salt_buf[64];
314
+ uint8_t *dst;
315
+ size_t need;
316
+ uint8_t *retval = NULL;
317
+
318
+ memset(salt_decoded, 0, sizeof(salt_decoded));
319
+ memset(dk, 0, sizeof(dk));
320
+ memset(salt_buf, 0, sizeof(salt_buf));
321
+
322
+ if (!setting || !buf || buflen < 128)
323
+ return NULL;
324
+
325
+ /* Decode setting string */
326
+ const uint8_t *hash_pos = yescrypt_decode_params(
327
+ setting, &N_log2, &r, &p, &t, &flags,
328
+ &salt_encoded, &salt_encoded_len);
329
+ if (!hash_pos)
330
+ goto cleanup;
331
+
332
+ /* Reject unreasonable parameters from untrusted setting strings */
333
+ if (N_log2 < 1 || N_log2 > 24 || r < 1 || r > 256 || p < 1 || p > 256)
334
+ goto cleanup;
335
+
336
+ /* Decode the base64 salt */
337
+ salt_decoded_len = sizeof(salt_decoded);
338
+ if (salt_encoded_len >= sizeof(salt_buf))
339
+ goto cleanup;
340
+ memcpy(salt_buf, salt_encoded, salt_encoded_len);
341
+ salt_buf[salt_encoded_len] = '\0';
342
+ const uint8_t *dec_end = decode64(salt_decoded, &salt_decoded_len, salt_buf);
343
+ if (!dec_end)
344
+ goto cleanup;
345
+
346
+ /* Compute the hash */
347
+ yescrypt_params_t params;
348
+ params.flags = flags;
349
+ params.N = (uint64_t)1 << N_log2;
350
+ params.r = r;
351
+ params.p = p;
352
+ params.t = t;
353
+ params.g = 0;
354
+
355
+ if (yescrypt_kdf(shared, local, passwd, passwdlen,
356
+ salt_decoded, salt_decoded_len, &params,
357
+ dk, sizeof(dk)))
358
+ goto cleanup;
359
+
360
+ /* Build output: copy setting up to hash position, then encode hash */
361
+ need = (hash_pos - setting);
362
+ if (need + 64 > buflen)
363
+ goto cleanup;
364
+
365
+ memcpy(buf, setting, need);
366
+ dst = buf + need;
367
+
368
+ dst = encode64(dst, buflen - need, dk, sizeof(dk));
369
+ if (!dst)
370
+ goto cleanup;
371
+ *dst = '\0';
372
+
373
+ retval = buf;
374
+
375
+ cleanup:
376
+ insecure_memzero(dk, sizeof(dk));
377
+ insecure_memzero(salt_decoded, sizeof(salt_decoded));
378
+ insecure_memzero(salt_buf, sizeof(salt_buf));
379
+
380
+ return retval;
381
+ }