void hmac_final(u_char *output, struct hmac_ctx *ctx) { unsigned int outlen = 0; SECStatus status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); ctx->ctx_nss = NULL; ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(ctx->h)); PR_ASSERT(ctx->ctx_nss != NULL); status = PK11_DigestBegin(ctx->ctx_nss); PR_ASSERT(status == SECSuccess); status = PK11_DigestKey(ctx->ctx_nss, ctx->okey); PR_ASSERT(status == SECSuccess); status = PK11_DigestOp(ctx->ctx_nss, output, outlen); PR_ASSERT(status == SECSuccess); status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); if (ctx->ikey != NULL) PK11_FreeSymKey(ctx->ikey); if (ctx->okey != NULL) PK11_FreeSymKey(ctx->okey); /* DBG(DBG_CRYPT, DBG_log("NSS: hmac final end")); */ }
PK11SymKey * PK11_Derive_osw(PK11SymKey *base, CK_MECHANISM_TYPE mechanism , SECItem *param, CK_MECHANISM_TYPE target , CK_ATTRIBUTE_TYPE operation, int keysize) { SECOidTag oid; PK11Context *ctx; unsigned char dkey[HMAC_BUFSIZE]; SECItem dkey_param; SECStatus status; unsigned int len=0; CK_EXTRACT_PARAMS bs; chunk_t dkey_chunk; if( ((mechanism == CKM_SHA256_KEY_DERIVATION) || (mechanism == CKM_SHA384_KEY_DERIVATION)|| (mechanism == CKM_SHA512_KEY_DERIVATION)) && (param == NULL) && (keysize ==0)) { switch (mechanism) { case CKM_SHA256_KEY_DERIVATION: oid = SEC_OID_SHA256; break; case CKM_SHA384_KEY_DERIVATION: oid = SEC_OID_SHA384; break; case CKM_SHA512_KEY_DERIVATION: oid = SEC_OID_SHA512; break; default: DBG(DBG_CRYPT, DBG_log("PK11_Derive_osw: Invalid NSS mechanism ")); break; /*should not reach here*/ } ctx = PK11_CreateDigestContext(oid); PR_ASSERT(ctx!=NULL); status=PK11_DigestBegin(ctx); PR_ASSERT(status == SECSuccess); status=PK11_DigestKey(ctx, base); PR_ASSERT(status == SECSuccess); PK11_DigestFinal(ctx, dkey, &len, sizeof dkey); PK11_DestroyContext(ctx, PR_TRUE); dkey_chunk.ptr = dkey; dkey_chunk.len = len; PK11SymKey *tkey1 = pk11_derive_wrapper_osw(base, CKM_CONCATENATE_DATA_AND_BASE, dkey_chunk, CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE, 0); PR_ASSERT(tkey1!=NULL); bs=0; dkey_param.data = (unsigned char*)&bs; dkey_param.len = sizeof (bs); PK11SymKey *tkey2 = PK11_Derive(tkey1, CKM_EXTRACT_KEY_FROM_KEY, &dkey_param, target, operation, len); PR_ASSERT(tkey2!=NULL); if(tkey1!=NULL) { PK11_FreeSymKey(tkey1); } return tkey2; } else { return PK11_Derive(base, mechanism, param, target, operation, keysize); } }
void hmac_final(u_char *output, struct hmac_ctx *ctx) { #ifndef HAVE_LIBNSS const struct hash_desc *h = ctx->h; h->hash_final(output, &ctx->hash_ctx); h->hash_init(&ctx->hash_ctx); h->hash_update(&ctx->hash_ctx, ctx->buf2, HMAC_BUFSIZE); h->hash_update(&ctx->hash_ctx, output, h->hash_digest_len); h->hash_final(output, &ctx->hash_ctx); #else unsigned int outlen = 0; SECStatus status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); ctx->ctx_nss = NULL; ctx->ctx_nss = PK11_CreateDigestContext(nss_hash_oid(ctx->h)); PR_ASSERT(ctx->ctx_nss!=NULL); status=PK11_DigestBegin(ctx->ctx_nss); PR_ASSERT(status==SECSuccess); status=PK11_DigestKey(ctx->ctx_nss, ctx->okey); PR_ASSERT(status==SECSuccess); status = PK11_DigestOp(ctx->ctx_nss, output, outlen); PR_ASSERT(status == SECSuccess); status = PK11_DigestFinal(ctx->ctx_nss, output, &outlen, ctx->hmac_digest_len); PR_ASSERT(status == SECSuccess); PR_ASSERT(outlen == ctx->hmac_digest_len); PK11_DestroyContext(ctx->ctx_nss, PR_TRUE); if(ctx->ikey !=NULL) { PK11_FreeSymKey(ctx->ikey); } if(ctx->okey != NULL) { PK11_FreeSymKey(ctx->okey); } /* DBG(DBG_CRYPT, DBG_log("NSS: hmac final end")); */ #endif }
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 }
void hmac_init(struct hmac_ctx *ctx, const struct hash_desc *h, const u_char *key, size_t key_len) { ctx->h = h; ctx->hmac_digest_len = h->hash_digest_len; /* 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, h->hash_block_size); hmac_ipad = hmac_pads(HMAC_IPAD, h->hash_block_size); hmac_pad = hmac_pads(0x00, h->hash_block_size - klen); if (klen > h->hash_block_size) { tkey1 = PK11_Derive_lsw(symkey, nss_key_derivation_mech( h), NULL, CKM_CONCATENATE_BASE_AND_DATA, CKA_DERIVE, 0); } else { tkey1 = symkey; } PK11SymKey *tkey2 = pk11_derive_wrapper_lsw(tkey1, CKM_CONCATENATE_BASE_AND_DATA, hmac_pad, CKM_XOR_BASE_AND_DATA, CKA_DERIVE, h->hash_block_size); PR_ASSERT(tkey2 != NULL); ctx->ikey = pk11_derive_wrapper_lsw(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_lsw(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); }