uint8_t* yescrypt(const uint8_t* passwd, const uint8_t* setting) { static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1 + HASH_LEN + 1]; yescrypt_shared_t shared; yescrypt_local_t local; uint8_t * retval; if (yescrypt_init_shared(&shared, NULL, 0, 0, 0, 0, YESCRYPT_SHARED_DEFAULTS, 0, NULL, 0)) return NULL; if (yescrypt_init_local(&local)) { yescrypt_free_shared(&shared); return NULL; } retval = yescrypt_r(&shared, &local, passwd, 80, setting, buf, sizeof(buf)); //printf("hashse='%s'\n", (char *)retval); if (yescrypt_free_local(&local)) { yescrypt_free_shared(&shared); return NULL; } if (yescrypt_free_shared(&shared)) return NULL; return retval; }
uint8_t * yescrypt(const uint8_t * passwd, const uint8_t * setting) { static uint8_t buf[4 + 1 + 5 + 5 + BYTES2CHARS(32) + 1 + HASH_LEN + 1]; yescrypt_local_t local; uint8_t * retval; if (yescrypt_init_local(&local)) return NULL; retval = yescrypt_r(NULL, &local, passwd, strlen((char *)passwd), setting, buf, sizeof(buf)); if (yescrypt_free_local(&local)) return NULL; return retval; }
void crypt_gost_yescrypt_rn (const char *phrase, size_t phr_size, const char *setting, size_t set_size, uint8_t *output, size_t o_size, void *scratch, size_t s_size) { if (o_size < set_size + 1 + 43 + 1 || CRYPT_OUTPUT_SIZE < set_size + 1 + 43 + 1 || s_size < sizeof (crypt_gost_yescrypt_internal_t)) { errno = ERANGE; return; } /* Fail when called with wrong prefix. */ if (strncmp (setting, "$gy$", 4)) { errno = EINVAL; return; } crypt_gost_yescrypt_internal_t *intbuf = scratch; if (yescrypt_init_local (&intbuf->local)) return; /* convert gost setting to yescrypt setting */ intbuf->gsetting[0] = '$'; intbuf->gsetting[1] = 'y'; intbuf->gsetting[2] = '$'; XCRYPT_STRCPY_OR_ABORT (&intbuf->gsetting[3], set_size - 3, setting + 4); intbuf->retval = yescrypt_r (NULL, &intbuf->local, (const uint8_t *) phrase, phr_size, intbuf->gsetting, NULL, intbuf->outbuf + 1, o_size - 1); if (!intbuf->retval) errno = EINVAL; if (yescrypt_free_local (&intbuf->local) || !intbuf->retval) return; intbuf->outbuf[0] = '$'; intbuf->outbuf[1] = 'g'; /* extract yescrypt output from "$y$param$salt$output" */ char *hptr = strchr ((const char *) intbuf->retval + 3, '$'); if (!hptr) { errno = EINVAL; return; } hptr = strchr (hptr + 1, '$'); if (!hptr) { errno = EINVAL; return; } hptr++; /* start of output */ /* decode yescrypt output into its raw 256-bit form */ size_t ylen = sizeof (intbuf->y); if (!decode64 (intbuf->y, &ylen, (uint8_t *) hptr, strlen (hptr)) || ylen != sizeof (intbuf->y)) { errno = EINVAL; return; } /* * HMAC_GOSTR3411_2012_256( * HMAC_GOSTR3411_2012_256(GOST2012_256(K), S), * yescrypt(K, S) * ) * yescrypt output is used in place of message, * thus, its crypto properties are superseded by GOST. * Password is always hashed for inner hmac to avoid * collisions between hashed and unhashed passwords. */ gost_hash256 ((const uint8_t *) phrase, phr_size, intbuf->hk, &intbuf->gostbuf.ctx); gost_hmac256 (intbuf->hk, sizeof (intbuf->hk), (const uint8_t *) setting, (size_t) ((uint8_t *) hptr - intbuf->retval), intbuf->interm, &intbuf->gostbuf); outer_gost_hmac256 (intbuf->interm, sizeof (intbuf->interm), intbuf->y, sizeof (intbuf->y), intbuf->y, &intbuf->gostbuf); encode64 ((uint8_t *) hptr, o_size - (size_t) ((uint8_t *) hptr - intbuf->retval), intbuf->y, sizeof (intbuf->y)); XCRYPT_STRCPY_OR_ABORT (output, o_size, intbuf->outbuf); return; }