void
hmac_init(struct hmac_ctx *ctx,
    const struct hash_desc *h,
    const u_char *key, size_t key_len)
{
    int k;

    ctx->h = h;
    ctx->hmac_digest_size = h->hash_digest_size;

    /* Prepare the two pads for the HMAC */

    memset(ctx->buf1, '\0', h->hash_block_size);

    if (key_len <= h->hash_block_size)
    {
	memcpy(ctx->buf1, key, key_len);
    }
    else
    {
	h->hash_init(&ctx->hash_ctx);
	h->hash_update(&ctx->hash_ctx, key, key_len);
	h->hash_final(ctx->buf1, &ctx->hash_ctx);
    }

    memcpy(ctx->buf2, ctx->buf1, h->hash_block_size);

    for (k = 0; k < h->hash_block_size; k++)
    {
	ctx->buf1[k] ^= HMAC_IPAD;
	ctx->buf2[k] ^= HMAC_OPAD;
    }

    hmac_reinit(ctx);
}
Example #2
0
void
hmac_init(struct hmac_ctx *ctx,
    const struct hash_desc *h,
    const u_char *key, size_t key_len)
{
#ifndef HAVE_LIBNSS
    int k;
#endif
    ctx->h = h;
    ctx->hmac_digest_len = h->hash_digest_len;

#ifdef HAVE_LIBNSS
    /* DBG(DBG_CRYPT, DBG_log("NSS: hmac init")); */
    SECStatus status;
    PK11SymKey *symkey=NULL, *tkey1=NULL;
    /* PK11SymKey *tkey1=NULL; */
    unsigned int klen;
    chunk_t hmac_opad, hmac_ipad, hmac_pad;

    memcpy(&symkey, key, key_len);
    klen =  PK11_GetKeyLength(symkey);

    hmac_opad = hmac_pads(HMAC_OPAD,HMAC_BUFSIZE);
    hmac_ipad = hmac_pads(HMAC_IPAD,HMAC_BUFSIZE);
    hmac_pad  = hmac_pads(0x00,HMAC_BUFSIZE-klen);

    if(klen > HMAC_BUFSIZE)
    {
	tkey1 = PK11_Derive_osw(symkey, nss_key_derivation_mech(h)
				, NULL, CKM_CONCATENATE_BASE_AND_DATA, CKA_DERIVE, 0);
    }
    else
    {
	tkey1 = symkey;
    }

    PK11SymKey *tkey2 = pk11_derive_wrapper_osw(tkey1, CKM_CONCATENATE_BASE_AND_DATA
				, hmac_pad,CKM_XOR_BASE_AND_DATA, CKA_DERIVE, HMAC_BUFSIZE);

    PR_ASSERT(tkey2!=NULL);
    ctx->ikey = pk11_derive_wrapper_osw(tkey2, CKM_XOR_BASE_AND_DATA
					, hmac_ipad,nss_hash_mech(h), CKA_DIGEST, 0);

    PR_ASSERT(ctx->ikey !=NULL);
    ctx->okey = pk11_derive_wrapper_osw(tkey2, CKM_XOR_BASE_AND_DATA
					, hmac_opad,nss_hash_mech(h), CKA_DIGEST, 0);

    PR_ASSERT(ctx->okey !=NULL);

    if(tkey1!=symkey) {
	PK11_FreeSymKey(tkey1);
    }
    PK11_FreeSymKey(tkey2);

    freeanychunk(hmac_opad);
    freeanychunk(hmac_ipad);
    freeanychunk(hmac_pad);
    ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(h));
    PR_ASSERT(ctx->ctx_nss!=NULL);

    status=PK11_DigestBegin(ctx->ctx_nss);
    PR_ASSERT(status==SECSuccess);

    status=PK11_DigestKey(ctx->ctx_nss, ctx->ikey);
    PR_ASSERT(status==SECSuccess);

#else

    /* Prepare the two pads for the HMAC */

    memset(ctx->buf1, '\0', HMAC_BUFSIZE);

    if (key_len <= HMAC_BUFSIZE)
    {
	memcpy(ctx->buf1, key, key_len);
    }
    else
    {
	h->hash_init(&ctx->hash_ctx);
	h->hash_update(&ctx->hash_ctx, key, key_len);
	h->hash_final(ctx->buf1, &ctx->hash_ctx);
    }

    memcpy(ctx->buf2, ctx->buf1, HMAC_BUFSIZE);

    for (k = 0; k < HMAC_BUFSIZE; k++)
    {
	ctx->buf1[k] ^= HMAC_IPAD;
	ctx->buf2[k] ^= HMAC_OPAD;
    }

    hmac_reinit(ctx);
#endif
}