Path: blob/linux/scryptjane/scrypt-jane-pbkdf2.h
1201 views
typedef struct scrypt_hmac_state_t {1scrypt_hash_state inner, outer;2} scrypt_hmac_state;345static void6scrypt_hash(scrypt_hash_digest hash, const uint8_t *m, size_t mlen) {7scrypt_hash_state st;8scrypt_hash_init(&st);9scrypt_hash_update(&st, m, mlen);10scrypt_hash_finish(&st, hash);11}1213/* hmac */14static void15scrypt_hmac_init(scrypt_hmac_state *st, const uint8_t *key, size_t keylen) {16uint8_t pad[SCRYPT_HASH_BLOCK_SIZE] = {0};17size_t i;1819scrypt_hash_init(&st->inner);20scrypt_hash_init(&st->outer);2122if (keylen <= SCRYPT_HASH_BLOCK_SIZE) {23/* use the key directly if it's <= blocksize bytes */24memcpy(pad, key, keylen);25} else {26/* if it's > blocksize bytes, hash it */27scrypt_hash(pad, key, keylen);28}2930/* inner = (key ^ 0x36) */31/* h(inner || ...) */32for (i = 0; i < SCRYPT_HASH_BLOCK_SIZE; i++)33pad[i] ^= 0x36;34scrypt_hash_update(&st->inner, pad, SCRYPT_HASH_BLOCK_SIZE);3536/* outer = (key ^ 0x5c) */37/* h(outer || ...) */38for (i = 0; i < SCRYPT_HASH_BLOCK_SIZE; i++)39pad[i] ^= (0x5c ^ 0x36);40scrypt_hash_update(&st->outer, pad, SCRYPT_HASH_BLOCK_SIZE);4142#ifdef SCRYPT_PREVENT_STATE_LEAK43scrypt_ensure_zero(pad, sizeof(pad));44#endif45}4647static void48scrypt_hmac_update(scrypt_hmac_state *st, const uint8_t *m, size_t mlen) {49/* h(inner || m...) */50scrypt_hash_update(&st->inner, m, mlen);51}5253static void54scrypt_hmac_finish(scrypt_hmac_state *st, scrypt_hash_digest mac) {55/* h(inner || m) */56scrypt_hash_digest innerhash;57scrypt_hash_finish(&st->inner, innerhash);5859/* h(outer || h(inner || m)) */60scrypt_hash_update(&st->outer, innerhash, sizeof(innerhash));61scrypt_hash_finish(&st->outer, mac);6263#ifdef SCRYPT_PREVENT_STATE_LEAK64scrypt_ensure_zero(st, sizeof(*st));65#endif66}6768static void69scrypt_pbkdf2(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint64_t N, uint8_t *out, size_t bytes) {70scrypt_hmac_state hmac_pw, hmac_pw_salt, work;71scrypt_hash_digest ti, u;72uint8_t be[4];73uint32_t i, j, blocks;74uint64_t c;7576/* bytes must be <= (0xffffffff - (SCRYPT_HASH_DIGEST_SIZE - 1)), which they will always be under scrypt */7778/* hmac(password, ...) */79scrypt_hmac_init(&hmac_pw, password, password_len);8081/* hmac(password, salt...) */82hmac_pw_salt = hmac_pw;83scrypt_hmac_update(&hmac_pw_salt, salt, salt_len);8485blocks = ((uint32_t)bytes + (SCRYPT_HASH_DIGEST_SIZE - 1)) / SCRYPT_HASH_DIGEST_SIZE;86for (i = 1; i <= blocks; i++) {87/* U1 = hmac(password, salt || be(i)) */88U32TO8_BE(be, i);89work = hmac_pw_salt;90scrypt_hmac_update(&work, be, 4);91scrypt_hmac_finish(&work, ti);92memcpy(u, ti, sizeof(u));9394/* T[i] = U1 ^ U2 ^ U3... */95for (c = 0; c < N - 1; c++) {96/* UX = hmac(password, U{X-1}) */97work = hmac_pw;98scrypt_hmac_update(&work, u, SCRYPT_HASH_DIGEST_SIZE);99scrypt_hmac_finish(&work, u);100101/* T[i] ^= UX */102for (j = 0; j < sizeof(u); j++)103ti[j] ^= u[j];104}105106memcpy(out, ti, (bytes > SCRYPT_HASH_DIGEST_SIZE) ? SCRYPT_HASH_DIGEST_SIZE : bytes);107out += SCRYPT_HASH_DIGEST_SIZE;108bytes -= SCRYPT_HASH_DIGEST_SIZE;109}110111#ifdef SCRYPT_PREVENT_STATE_LEAK112scrypt_ensure_zero(ti, sizeof(ti));113scrypt_ensure_zero(u, sizeof(u));114scrypt_ensure_zero(&hmac_pw, sizeof(hmac_pw));115scrypt_ensure_zero(&hmac_pw_salt, sizeof(hmac_pw_salt));116#endif117}118119/*120* Special version where N = 1121* - mikaelh122*/123static void124scrypt_pbkdf2_1(const uint8_t *password, size_t password_len, const uint8_t *salt, size_t salt_len, uint8_t *out, size_t bytes) {125scrypt_hmac_state hmac_pw, hmac_pw_salt, work;126scrypt_hash_digest ti, u;127uint8_t be[4];128uint32_t i, /*j,*/ blocks;129//uint64_t c;130131/* bytes must be <= (0xffffffff - (SCRYPT_HASH_DIGEST_SIZE - 1)), which they will always be under scrypt */132133/* hmac(password, ...) */134scrypt_hmac_init(&hmac_pw, password, password_len);135136/* hmac(password, salt...) */137hmac_pw_salt = hmac_pw;138scrypt_hmac_update(&hmac_pw_salt, salt, salt_len);139140blocks = ((uint32_t)bytes + (SCRYPT_HASH_DIGEST_SIZE - 1)) / SCRYPT_HASH_DIGEST_SIZE;141for (i = 1; i <= blocks; i++) {142/* U1 = hmac(password, salt || be(i)) */143U32TO8_BE(be, i);144work = hmac_pw_salt;145scrypt_hmac_update(&work, be, 4);146scrypt_hmac_finish(&work, ti);147memcpy(u, ti, sizeof(u));148149memcpy(out, ti, (bytes > SCRYPT_HASH_DIGEST_SIZE) ? SCRYPT_HASH_DIGEST_SIZE : bytes);150out += SCRYPT_HASH_DIGEST_SIZE;151bytes -= SCRYPT_HASH_DIGEST_SIZE;152}153154#ifdef SCRYPT_PREVENT_STATE_LEAK155scrypt_ensure_zero(ti, sizeof(ti));156scrypt_ensure_zero(u, sizeof(u));157scrypt_ensure_zero(&hmac_pw, sizeof(hmac_pw));158scrypt_ensure_zero(&hmac_pw_salt, sizeof(hmac_pw_salt));159#endif160}161162163