int yescrypt_init_shared(yescrypt_shared_t * shared, const uint8_t * param, size_t paramlen, uint64_t N, uint32_t r, uint32_t p, yescrypt_init_shared_flags_t flags, uint8_t * buf, size_t buflen) { yescrypt_shared_t half1, half2; uint8_t salt[32]; if (flags & YESCRYPT_SHARED_PREALLOCATED) { if (!shared->aligned || !shared->aligned_size) return -1; } else { init_region(shared); } if (!param && !paramlen && !N && !r && !p && !buf && !buflen) return 0; if (yescrypt_kdf(NULL, shared, param, paramlen, NULL, 0, N, r, p, 0, 0, YESCRYPT_RW | __YESCRYPT_INIT_SHARED_1, salt, sizeof(salt))) goto out; half1 = half2 = *shared; half1.aligned_size /= 2; half2.aligned += half1.aligned_size; half2.aligned_size = half1.aligned_size; N /= 2; if (p > 1 && yescrypt_kdf(&half1, &half2, param, paramlen, salt, sizeof(salt), N, r, p, 0, 0, YESCRYPT_RW | __YESCRYPT_INIT_SHARED_2, salt, sizeof(salt))) goto out; if (yescrypt_kdf(&half2, &half1, param, paramlen, salt, sizeof(salt), N, r, p, 0, 0, YESCRYPT_RW | __YESCRYPT_INIT_SHARED_1, salt, sizeof(salt))) goto out; if (yescrypt_kdf(&half1, &half2, param, paramlen, salt, sizeof(salt), N, r, p, 0, 0, YESCRYPT_RW | __YESCRYPT_INIT_SHARED_1, buf, buflen)) goto out; return 0; out: if (!(flags & YESCRYPT_SHARED_PREALLOCATED)) free_region(shared); return -1; }
static #endif int PHS(void *out, size_t outlen, const void *in, size_t inlen, const void *salt, size_t saltlen, unsigned int t_cost, unsigned int m_cost) { yescrypt_shared_t shared; yescrypt_local_t local; int retval; if (yescrypt_init_shared(&shared, NULL, 0, 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0)) return -1; if (yescrypt_init_local(&local)) { yescrypt_free_shared(&shared); return -1; } retval = yescrypt_kdf(&shared, &local, in, inlen, salt, saltlen, (uint64_t)YESCRYPT_BASE_N << m_cost, YESCRYPT_R, YESCRYPT_P, t_cost, YESCRYPT_FLAGS, out, outlen); if (yescrypt_free_local(&local)) { yescrypt_free_shared(&shared); return -1; } if (yescrypt_free_shared(&shared)) return -1; return retval; }
static int yescrypt_bsty(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { static __thread int initialized = 0; static __thread yescrypt_shared_t shared; static __thread yescrypt_local_t local; int retval; if (!initialized) { /* "shared" could in fact be shared, but it's simpler to keep it private * along with "local". It's dummy and tiny anyway. */ if (yescrypt_init_shared(&shared, NULL, 0, 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0)) return -1; if (yescrypt_init_local(&local)) { yescrypt_free_shared(&shared); return -1; } initialized = 1; } retval = yescrypt_kdf(&shared, &local, passwd, passwdlen, salt, saltlen, N, r, p, 0, YESCRYPT_FLAGS, buf, buflen); #if 0 if (yescrypt_free_local(&local)) { yescrypt_free_shared(&shared); return -1; } if (yescrypt_free_shared(&shared)) return -1; initialized = 0; #endif return retval; }
int crypto_scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t * buf, size_t buflen) { yescrypt_local_t local; int retval; if (yescrypt_init_local(&local)) return -1; retval = yescrypt_kdf(NULL, &local, passwd, passwdlen, salt, saltlen, N, r, p, 0, 0, 0, buf, buflen); if (yescrypt_free_local(&local)) return -1; return retval; }
int yescrypt_init_shared(yescrypt_shared_t * shared, const uint8_t * param, size_t paramlen, uint64_t N, uint32_t r, uint32_t p, yescrypt_init_shared_flags_t flags, uint32_t mask, uint8_t * buf, size_t buflen) { yescrypt_shared1_t * shared1 = &shared->shared1; yescrypt_shared_t dummy, half1, half2; uint8_t salt[32]; if (flags & YESCRYPT_SHARED_PREALLOCATED) { if (!shared1->aligned || !shared1->aligned_size) return -1; } else { init_region(shared1); } shared->mask1 = 1; if (!param && !paramlen && !N && !r && !p && !buf && !buflen) return 0; init_region(&dummy.shared1); dummy.mask1 = 1; if (yescrypt_kdf(&dummy, shared1, param, paramlen, NULL, 0, N, r, p, 0, YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1, salt, sizeof(salt))) goto out; half1 = half2 = *shared; half1.shared1.aligned_size /= 2; half2.shared1.aligned += half1.shared1.aligned_size; half2.shared1.aligned_size = half1.shared1.aligned_size; N /= 2; if (p > 1 && yescrypt_kdf(&half1, &half2.shared1, param, paramlen, salt, sizeof(salt), N, r, p, 0, YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_2, salt, sizeof(salt))) goto out; if (yescrypt_kdf(&half2, &half1.shared1, param, paramlen, salt, sizeof(salt), N, r, p, 0, YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1, salt, sizeof(salt))) goto out; if (yescrypt_kdf(&half1, &half2.shared1, param, paramlen, salt, sizeof(salt), N, r, p, 0, YESCRYPT_RW | YESCRYPT_PARALLEL_SMIX | __YESCRYPT_INIT_SHARED_1, buf, buflen)) goto out; shared->mask1 = mask; return 0; out: if (!(flags & YESCRYPT_SHARED_PREALLOCATED)) free_region(shared1); return -1; }
uint8_t* yescrypt_r(const yescrypt_shared_t* shared, yescrypt_local_t* local, const uint8_t* passwd, size_t passwdlen, const uint8_t* setting, uint8_t* buf, size_t buflen) { uint8_t hash[HASH_SIZE]; const uint8_t * src, * salt; uint8_t * dst; size_t prefixlen, saltlen, need; uint8_t version; uint64_t N; uint32_t r, p; yescrypt_flags_t flags = YESCRYPT_WORM; printf("pass1 ..."); fflush(stdout); if (setting[0] != '$' || setting[1] != '7') { printf("died$7 ..."); fflush(stdout); return NULL; } printf("died80 ..."); fflush(stdout); src = setting + 2; printf("hello '%p'\n", (char *)src); fflush(stdout); switch ((version = *src)) { case '$': printf("died2 ..."); fflush(stdout); break; case 'X': src++; flags = YESCRYPT_RW; printf("died3 ..."); fflush(stdout); break; default: printf("died4 ..."); fflush(stdout); return NULL; } printf("pass2 ..."); fflush(stdout); if (*src != '$') { uint32_t decoded_flags; if (decode64_one(&decoded_flags, *src)) { printf("died5 ..."); fflush(stdout); return NULL; } flags = decoded_flags; if (*++src != '$') { printf("died6 ..."); fflush(stdout); return NULL; } } src++; { uint32_t N_log2; if (decode64_one(&N_log2, *src)) { printf("died7 ..."); return NULL; } src++; N = (uint64_t)1 << N_log2; } src = decode64_uint32(&r, 30, src); if (!src) { printf("died6 ..."); return NULL; } src = decode64_uint32(&p, 30, src); if (!src) { printf("died7 ..."); return NULL; } prefixlen = src - setting; salt = src; src = (uint8_t *)strrchr((char *)salt, '$'); if (src) saltlen = src - salt; else saltlen = strlen((char *)salt); need = prefixlen + saltlen + 1 + HASH_LEN + 1; if (need > buflen || need < saltlen) { printf("'%d %d %d'", (int) need, (int) buflen, (int) saltlen); printf("died8killbuf ..."); fflush(stdout); return NULL; } if (yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, N, r, p, 0, flags, hash, sizeof(hash))) { printf("died10 ..."); fflush(stdout); return NULL; } dst = buf; memcpy(dst, setting, prefixlen + saltlen); dst += prefixlen + saltlen; *dst++ = '$'; dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); /* Could zeroize hash[] here, but yescrypt_kdf() doesn't zeroize its * memory allocations yet anyway. */ if (!dst || dst >= buf + buflen) { /* Can't happen */ printf("died11 ..."); return NULL; } *dst = 0; /* NUL termination */ printf("died12 ..."); fflush(stdout); return buf; }
uint8_t * yescrypt_r(const yescrypt_shared_t * shared, yescrypt_local_t * local, const uint8_t * passwd, size_t passwdlen, const uint8_t * setting, uint8_t * buf, size_t buflen) { uint8_t hash[HASH_SIZE]; const uint8_t * src, * salt; uint8_t * dst; size_t prefixlen, saltlen, need; uint8_t version; uint64_t N; uint32_t r, p; yescrypt_flags_t flags = 0; if (setting[0] != '$' || setting[1] != '7') return NULL; src = setting + 2; switch ((version = *src)) { case '$': break; case 'X': src++; flags = YESCRYPT_RW; break; default: return NULL; } if (*src != '$') { uint32_t decoded_flags; if (decode64_one(&decoded_flags, *src)) return NULL; flags = decoded_flags; if (*++src != '$') return NULL; } src++; { uint32_t N_log2; if (decode64_one(&N_log2, *src)) return NULL; src++; N = (uint64_t)1 << N_log2; } src = decode64_uint32(&r, 30, src); if (!src) return NULL; src = decode64_uint32(&p, 30, src); if (!src) return NULL; prefixlen = src - setting; salt = src; src = (uint8_t *)strrchr((char *)salt, '$'); if (src) saltlen = src - salt; else saltlen = strlen((char *)salt); need = prefixlen + saltlen + 1 + HASH_LEN + 1; if (need > buflen || need < saltlen) return NULL; if (yescrypt_kdf(shared, local, passwd, passwdlen, salt, saltlen, N, r, p, 0, 0, flags, hash, sizeof(hash))) return NULL; dst = buf; memcpy(dst, setting, prefixlen + saltlen); dst += prefixlen + saltlen; *dst++ = '$'; dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); /* Could zeroize hash[] here, but yescrypt_kdf() doesn't zeroize its * memory allocations yet anyway. */ if (!dst || dst >= buf + buflen) /* Can't happen */ return NULL; *dst = 0; /* NUL termination */ return buf; }