/* * Special version where N = 1 * - mikaelh */ static void scrypt_pbkdf2_1(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint8_t *out, size_t bytes) { scrypt_hmac_state hmac_pw, hmac_pw_salt, work; scrypt_hash_digest ti, u; uint8_t be[4]; uint32_t i, /*j,*/ blocks; // uint64_t c; /* bytes must be <= (0xffffffff - (SCRYPT_HASH_DIGEST_SIZE - 1)), which they will always be under scrypt */ /* hmac(password, ...) */ scrypt_hmac_init(&hmac_pw, password, password_len); /* hmac(password, salt...) */ hmac_pw_salt = hmac_pw; scrypt_hmac_update(&hmac_pw_salt, salt, salt_len); blocks = ((uint32_t)bytes + (SCRYPT_HASH_DIGEST_SIZE - 1)) / SCRYPT_HASH_DIGEST_SIZE; for (i = 1; i <= blocks; i++) { /* U1 = hmac(password, salt || be(i)) */ U32TO8_BE(be, i); work = hmac_pw_salt; scrypt_hmac_update(&work, be, 4); scrypt_hmac_finish(&work, ti); memcpy(u, ti, sizeof(u)); memcpy(out, ti, (bytes > SCRYPT_HASH_DIGEST_SIZE) ? SCRYPT_HASH_DIGEST_SIZE : bytes); out += SCRYPT_HASH_DIGEST_SIZE; bytes -= SCRYPT_HASH_DIGEST_SIZE; } }
void scrypt_pbkdf2_sha256(const uint8_t* password, size_t password_len, const uint8_t* salt, size_t salt_len, unsigned int c, uint8_t* out, size_t out_len) { /* * Terminology: * P = password * S = salt * DK = out * dkLen = out_len */ /* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop. */ /* (skip) */ /* 2. Let l be the number of hLen-octet blocks in the derived key, * rounding up, and let r be the number of octets in the last * block: * * l = CEIL (dkLen / hLen) , * r = dkLen - (l - 1) * hLen . * * Here, CEIL (x) is the "ceiling" function, i.e. the smallest * integer greater than, or equal to, x. */ size_t i; size_t l; size_t r; l = (out_len + kSha256DigestSize - 1) / kSha256DigestSize; r = out_len - (l - 1) * kSha256DigestSize; /* 3. For each block of the derived key apply the function F defined * below to the password P, the salt S, the iteration count c, and * the block index to compute the block: * * T_1 = F (P, S, c, 1) , * T_2 = F (P, S, c, 2) , * ... * T_l = F (P, S, c, l) , * * where the function F is defined as the exclusive-or sum of the * first c iterates of the underlying pseudorandom function PRF * applied to the password P and the concatenation of the salt S * and the block index i: * * F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c * * where * * U_1 = PRF (P, S || INT (i)) , * U_2 = PRF (P, U_1) , * ... * U_c = PRF (P, U_{c-1}) . * * Here, INT (i) is a four-octet encoding of the integer i, most * significant octet first. */ for (i = 1; i <= l; i++) { unsigned int j; uint8_t t[kSha256DigestSize]; uint8_t u[kSha256DigestSize]; uint8_t ctr[4]; scrypt_hmac_t hmac; ctr[0] = i >> 24; ctr[1] = i >> 16; ctr[2] = i >> 8; ctr[3] = i; /* U_1 = PRF (P, S || INT (i)) */ scrypt_hmac_init(&hmac, password, password_len); scrypt_hmac_update(&hmac, salt, salt_len); scrypt_hmac_update(&hmac, ctr, sizeof(ctr)); scrypt_hmac_digest(&hmac, u); memcpy(t, u, sizeof(u)); for (j = 2; j <= c; j++) { size_t u_len; size_t k; u_len = sizeof(u); /* U_c = PRF (P, U_{c-1}) */ scrypt_hmac_init(&hmac, password, password_len); scrypt_hmac_update(&hmac, u, u_len); scrypt_hmac_digest(&hmac, u); /* Xor Us */ for (k = 0; k < kSha256DigestSize; k++) t[k] ^= u[k]; } /* Copy out the results */ memcpy(&out[(i - 1) * kSha256DigestSize], t, MIN(out_len - (i - 1) * kSha256DigestSize, kSha256DigestSize)); } }