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); }
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 }