/**
 * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
 * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
 * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).
 */
void
PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt,
              size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen)
{
    crypto_auth_hmacsha256_state PShctx, hctx;
    size_t                       i;
    uint8_t                      ivec[4];
    uint8_t                      U[32];
    uint8_t                      T[32];
    uint64_t                     j;
    int                          k;
    size_t                       clen;

#if SIZE_MAX > 0x1fffffffe0ULL
    if (dkLen > 0x1fffffffe0ULL) {
        abort();
    }
#endif
    crypto_auth_hmacsha256_init(&PShctx, passwd, passwdlen);
    crypto_auth_hmacsha256_update(&PShctx, salt, saltlen);

    for (i = 0; i * 32 < dkLen; i++) {
        STORE32_BE(ivec, (uint32_t)(i + 1));
        memcpy(&hctx, &PShctx, sizeof(crypto_auth_hmacsha256_state));
        crypto_auth_hmacsha256_update(&hctx, ivec, 4);
        crypto_auth_hmacsha256_final(&hctx, U);

        memcpy(T, U, 32);
        /* LCOV_EXCL_START */
        for (j = 2; j <= c; j++) {
            crypto_auth_hmacsha256_init(&hctx, passwd, passwdlen);
            crypto_auth_hmacsha256_update(&hctx, U, 32);
            crypto_auth_hmacsha256_final(&hctx, U);

            for (k = 0; k < 32; k++) {
                T[k] ^= U[k];
            }
        }
        /* LCOV_EXCL_STOP */

        clen = dkLen - i * 32;
        if (clen > 32) {
            clen = 32;
        }
        memcpy(&buf[i * 32], T, clen);
    }
    sodium_memzero((void *) &PShctx, sizeof PShctx);
}
Esempio n. 2
0
static int hkdf_extract(unsigned char* out, const unsigned char* salt, const size_t saltlen,
		const unsigned char* in, const size_t inlen)
{
	crypto_auth_hmacsha256_state state;
	crypto_auth_hmacsha256_init(&state, salt, saltlen);
	crypto_auth_hmacsha256_update(&state, in, inlen);
	return crypto_auth_hmacsha256_final(&state, out);
}
Esempio n. 3
0
static void
mm_hmacsha256(void)
{
    crypto_auth_hmacsha256_state st;
    unsigned char *h, *h2;
    unsigned char *k;
    unsigned char *m;
    size_t         mlen;
    size_t         l1, l2;
    int            i;

    for (i = 0; i < MAX_ITER; i++) {
        mlen = randombytes_uniform(MAXLEN);
        m = (unsigned char *) sodium_malloc(mlen);
        k = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_KEYBYTES);
        h = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_BYTES);
        h2 = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_BYTES);

        crypto_auth_hmacsha256_keygen(k);
        randombytes_buf(m, mlen);

        crypto_auth_hmacsha256_init(&st, k, crypto_auth_hmacsha256_KEYBYTES);
        l1 = randombytes_uniform(mlen);
        l2 = randombytes_uniform(mlen - l1);
        crypto_auth_hmacsha256_update(&st, m, l1);
        crypto_auth_hmacsha256_update(&st, m + l1, l2);
        crypto_auth_hmacsha256_update(&st, m + l1 + l2, mlen - l1 - l2);
        crypto_auth_hmacsha256_final(&st, h);

        crypto_auth_hmacsha256(h2, m, mlen, k);

        assert(memcmp(h, h2, crypto_auth_hmacsha256_BYTES) == 0);

        sodium_free(h2);
        sodium_free(h);
        sodium_free(k);
        sodium_free(m);
    }
}
Esempio n. 4
0
static int hkdf_expand(unsigned char* out, enum hkdf_msg_ver_t offset,
		const unsigned char* prk, const size_t prklen,
		const unsigned char* info, const size_t infolen,
		const unsigned outlen)
{
	unsigned iters = (unsigned) ceil( (double)outlen / (double)HASH_OUTSZ );
	unsigned char mixin[crypto_auth_hmacsha256_BYTES];
	unsigned remaining_bytes = outlen;

	sodium_memzero(out, outlen);
	sodium_memzero(mixin, sizeof mixin);

	unsigned char* tmp_res = out;
	for (unsigned i = offset; i < iters + offset; i++){

		crypto_auth_hmacsha256_state state;
		crypto_auth_hmacsha256_init(&state, prk, prklen);

		if (i != offset)
			crypto_auth_hmacsha256_update(&state, mixin, sizeof mixin);
		if (info != NULL)
			crypto_auth_hmacsha256_update(&state, info, infolen);

		unsigned char ii = (unsigned char)i;
		crypto_auth_hmacsha256_update(&state, &ii, sizeof ii);

		unsigned char step_out[crypto_auth_hmacsha256_BYTES];
		crypto_auth_hmacsha256_final(&state, step_out);

		int steplen = min(remaining_bytes, sizeof step_out);
		memcpy(tmp_res, step_out, steplen);
		tmp_res += steplen;

		memcpy(mixin, step_out, sizeof step_out);
		remaining_bytes -= steplen;
	}

	return 0;
}