Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/yescrypt/yescrypt-common.c
1201 views
1
/*-
2
* Copyright 2013,2014 Alexander Peslyak
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted.
7
*
8
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
9
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
12
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
13
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
14
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
17
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18
* SUCH DAMAGE.
19
*/
20
21
#include <stdint.h>
22
#include <string.h>
23
#include <stdio.h>
24
25
#include "compat.h"
26
27
#include "yescrypt.h"
28
29
#define BYTES2CHARS(bytes) \
30
((((bytes) * 8) + 5) / 6)
31
32
#define HASH_SIZE 32 /* bytes */
33
#define HASH_LEN BYTES2CHARS(HASH_SIZE) /* base-64 chars */
34
#define YESCRYPT_FLAGS (YESCRYPT_RW | YESCRYPT_PWXFORM)
35
36
static const char * const itoa64 =
37
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
38
39
char *yescrypt_client_key = NULL;
40
int yescrypt_client_key_len = 0;
41
42
static uint8_t* encode64_uint32(uint8_t* dst, size_t dstlen, uint32_t src, uint32_t srcbits)
43
{
44
uint32_t bit;
45
46
for (bit = 0; bit < srcbits; bit += 6) {
47
if (dstlen < 1)
48
return NULL;
49
*dst++ = itoa64[src & 0x3f];
50
dstlen--;
51
src >>= 6;
52
}
53
54
return dst;
55
}
56
57
static uint8_t* encode64(uint8_t* dst, size_t dstlen, const uint8_t* src, size_t srclen)
58
{
59
size_t i;
60
61
for (i = 0; i < srclen; ) {
62
uint8_t * dnext;
63
uint32_t value = 0, bits = 0;
64
do {
65
value |= (uint32_t)src[i++] << bits;
66
bits += 8;
67
} while (bits < 24 && i < srclen);
68
dnext = encode64_uint32(dst, dstlen, value, bits);
69
if (!dnext)
70
return NULL;
71
dstlen -= dnext - dst;
72
dst = dnext;
73
}
74
75
return dst;
76
}
77
78
static int decode64_one(uint32_t* dst, uint8_t src)
79
{
80
const char * ptr = strchr(itoa64, src);
81
if (ptr) {
82
*dst = (uint32_t) (ptr - itoa64);
83
return 0;
84
}
85
*dst = 0;
86
return -1;
87
}
88
89
static const uint8_t* decode64_uint32(uint32_t* dst, uint32_t dstbits, const uint8_t* src)
90
{
91
uint32_t bit;
92
uint32_t value;
93
94
value = 0;
95
for (bit = 0; bit < dstbits; bit += 6) {
96
uint32_t one;
97
if (decode64_one(&one, *src)) {
98
*dst = 0;
99
return NULL;
100
}
101
src++;
102
value |= one << bit;
103
}
104
105
*dst = value;
106
return src;
107
}
108
109
uint8_t* yescrypt_r(const yescrypt_shared_t* shared, yescrypt_local_t* local,
110
const uint8_t* passwd, size_t passwdlen, const uint8_t* setting, uint8_t* buf, size_t buflen)
111
{
112
uint8_t hash[HASH_SIZE];
113
const uint8_t * src, * salt;
114
uint8_t * dst;
115
size_t prefixlen, saltlen, need;
116
uint8_t version;
117
uint64_t N;
118
uint32_t r, p;
119
yescrypt_flags_t flags = YESCRYPT_WORM;
120
121
printf("pass1 ...");
122
fflush(stdout);
123
124
if (setting[0] != '$' || setting[1] != '7') {
125
printf("died$7 ...");
126
fflush(stdout);
127
return NULL;
128
}
129
130
printf("died80 ...");
131
fflush(stdout);
132
133
src = setting + 2;
134
135
printf("hello '%p'\n", (char *)src);
136
fflush(stdout);
137
138
switch ((version = *src)) {
139
case '$':
140
printf("died2 ...");
141
fflush(stdout);
142
break;
143
case 'X':
144
src++;
145
flags = YESCRYPT_RW;
146
printf("died3 ...");
147
fflush(stdout);
148
break;
149
default:
150
printf("died4 ...");
151
fflush(stdout);
152
return NULL;
153
}
154
155
printf("pass2 ...");
156
fflush(stdout);
157
158
if (*src != '$') {
159
uint32_t decoded_flags;
160
if (decode64_one(&decoded_flags, *src)) {
161
printf("died5 ...");
162
fflush(stdout);
163
return NULL;
164
}
165
flags = decoded_flags;
166
if (*++src != '$') {
167
printf("died6 ...");
168
fflush(stdout);
169
return NULL;
170
}
171
}
172
173
src++;
174
175
{
176
uint32_t N_log2;
177
if (decode64_one(&N_log2, *src)) {
178
printf("died7 ...");
179
return NULL;
180
}
181
src++;
182
N = (uint64_t)1 << N_log2;
183
}
184
185
src = decode64_uint32(&r, 30, src);
186
if (!src) {
187
printf("died6 ...");
188
return NULL;
189
}
190
191
src = decode64_uint32(&p, 30, src);
192
if (!src) {
193
printf("died7 ...");
194
return NULL;
195
}
196
197
prefixlen = src - setting;
198
199
salt = src;
200
src = (uint8_t *)strrchr((char *)salt, '$');
201
if (src)
202
saltlen = src - salt;
203
else
204
saltlen = strlen((char *)salt);
205
206
need = prefixlen + saltlen + 1 + HASH_LEN + 1;
207
if (need > buflen || need < saltlen) {
208
printf("'%d %d %d'", (int) need, (int) buflen, (int) saltlen);
209
printf("died8killbuf ...");
210
fflush(stdout);
211
return NULL;
212
}
213
214
if (yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, N, r, p, 0, flags, hash, sizeof(hash))) {
215
printf("died10 ...");
216
fflush(stdout);
217
return NULL;
218
}
219
220
dst = buf;
221
memcpy(dst, setting, prefixlen + saltlen);
222
dst += prefixlen + saltlen;
223
*dst++ = '$';
224
225
dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
226
/* Could zeroize hash[] here, but yescrypt_kdf() doesn't zeroize its
227
* memory allocations yet anyway. */
228
if (!dst || dst >= buf + buflen) { /* Can't happen */
229
printf("died11 ...");
230
return NULL;
231
}
232
233
*dst = 0; /* NUL termination */
234
235
printf("died12 ...");
236
fflush(stdout);
237
238
return buf;
239
}
240
241
uint8_t* yescrypt(const uint8_t* passwd, const uint8_t* setting)
242
{
243
static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1 + HASH_LEN + 1];
244
yescrypt_shared_t shared;
245
yescrypt_local_t local;
246
uint8_t * retval;
247
248
if (yescrypt_init_shared(&shared, NULL, 0,
249
0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0))
250
return NULL;
251
if (yescrypt_init_local(&local)) {
252
yescrypt_free_shared(&shared);
253
return NULL;
254
}
255
retval = yescrypt_r(&shared, &local,
256
passwd, 80, setting, buf, sizeof(buf));
257
//printf("hashse='%s'\n", (char *)retval);
258
if (yescrypt_free_local(&local)) {
259
yescrypt_free_shared(&shared);
260
return NULL;
261
}
262
if (yescrypt_free_shared(&shared))
263
return NULL;
264
return retval;
265
}
266
267
uint8_t* yescrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, yescrypt_flags_t flags,
268
const uint8_t* src, size_t srclen, uint8_t* buf, size_t buflen)
269
{
270
uint8_t * dst;
271
size_t prefixlen = 3 + 1 + 5 + 5;
272
size_t saltlen = BYTES2CHARS(srclen);
273
size_t need;
274
275
if (p == 1)
276
flags &= ~YESCRYPT_PARALLEL_SMIX;
277
278
if (flags) {
279
if (flags & ~0x3f)
280
return NULL;
281
282
prefixlen++;
283
if (flags != YESCRYPT_RW)
284
prefixlen++;
285
}
286
287
need = prefixlen + saltlen + 1;
288
if (need > buflen || need < saltlen || saltlen < srclen)
289
return NULL;
290
291
if (N_log2 > 63 || ((uint64_t)r * (uint64_t)p >= (1U << 30)))
292
return NULL;
293
294
dst = buf;
295
*dst++ = '$';
296
*dst++ = '7';
297
if (flags) {
298
*dst++ = 'X'; /* eXperimental, subject to change */
299
if (flags != YESCRYPT_RW)
300
*dst++ = itoa64[flags];
301
}
302
*dst++ = '$';
303
304
*dst++ = itoa64[N_log2];
305
306
dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
307
if (!dst) /* Can't happen */
308
return NULL;
309
310
dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
311
if (!dst) /* Can't happen */
312
return NULL;
313
314
dst = encode64(dst, buflen - (dst - buf), src, srclen);
315
if (!dst || dst >= buf + buflen) /* Can't happen */
316
return NULL;
317
318
*dst = 0; /* NUL termination */
319
320
return buf;
321
}
322
323
uint8_t* yescrypt_gensalt(uint32_t N_log2, uint32_t r, uint32_t p, yescrypt_flags_t flags,
324
const uint8_t * src, size_t srclen)
325
{
326
static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1];
327
return yescrypt_gensalt_r(N_log2, r, p, flags, src, srclen,
328
buf, sizeof(buf));
329
}
330
331
static int yescrypt_bsty(const uint8_t * passwd, size_t passwdlen,
332
const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
333
uint8_t * buf, size_t buflen)
334
{
335
static __thread int initialized = 0;
336
static __thread yescrypt_shared_t shared;
337
static __thread yescrypt_local_t local;
338
int retval;
339
340
if (!initialized) {
341
/* "shared" could in fact be shared, but it's simpler to keep it private
342
* along with "local". It's dummy and tiny anyway. */
343
if (yescrypt_init_shared(&shared, NULL, 0,
344
0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0))
345
return -1;
346
if (yescrypt_init_local(&local)) {
347
yescrypt_free_shared(&shared);
348
return -1;
349
}
350
initialized = 1;
351
}
352
retval = yescrypt_kdf(&shared, &local,
353
passwd, passwdlen, salt, saltlen, N, r, p, 0, YESCRYPT_FLAGS,
354
buf, buflen);
355
#if 0
356
if (yescrypt_free_local(&local)) {
357
yescrypt_free_shared(&shared);
358
return -1;
359
}
360
if (yescrypt_free_shared(&shared))
361
return -1;
362
initialized = 0;
363
#endif
364
return retval;
365
}
366
367
/* main hash 80 bytes input */
368
void yescrypt_hash(const char *input, char *output, uint32_t len)
369
{
370
yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 2048, 8, 1, (uint8_t*)output, 32);
371
}
372
373
void yescrypt_hash_r8(const char *input, char *output, uint32_t len)
374
{
375
yescrypt_client_key = "Client Key";
376
yescrypt_client_key_len = strlen("Client Key");
377
yescrypt_bsty((uint8_t*)input, len, (uint8_t *)input, len, 2048, 8, 1, (uint8_t*)output, 32);
378
379
}
380
381
void yescrypt_hash_r16(const char *input, char *output, uint32_t len)
382
{
383
yescrypt_client_key = "Client Key";
384
yescrypt_client_key_len = strlen("Client Key");
385
yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 4096, 16, 1, (uint8_t*)output, 32);
386
387
}
388
389
void yescrypt_hash_r32(const char *input, char *output, uint32_t len)
390
{
391
yescrypt_client_key = "WaviBanana";
392
yescrypt_client_key_len = strlen("WaviBanana");
393
yescrypt_bsty((uint8_t*)input, len, (uint8_t*)input, len, 4096, 32, 1, (uint8_t*)output, 32);
394
395
}
396
/* for util.c test */
397
void yescrypthash(void *output, const void *input)
398
{
399
yescrypt_hash((char*) input, (char*) output, 80);
400
}
401
402
403