/* Provenance: openssl/openssl PBMAC1_PBKDF2_HMAC (fixed). * repo: openssl/openssl * commit: 5a0230b6cc95a576b0c2b7b5b2ba7c74232e7b7c * parent: fcb23806047f5afbe55d5d601a527fc24bf7ca2c * commit_url: https://github.com/openssl/openssl/commit/5a0230b6cc95a576b0c2b7b5b2ba7c74232e7b7c * cve: CVE-2026-34181 * license: Apache-2.0 * function: PBMAC1_PBKDF2_HMAC * relpath: crypto/pkcs12/p12_mutl.c */ static int PBMAC1_PBKDF2_HMAC(OSSL_LIB_CTX *ctx, const char *propq, const char *pass, int passlen, const X509_ALGOR *macalg, unsigned char *key) { PBKDF2PARAM *pbkdf2_param = NULL; const ASN1_OBJECT *kdf_hmac_oid; int kdf_hmac_nid; int ret = -1; int keylen = 0; EVP_MD *kdf_md = NULL; const ASN1_OCTET_STRING *pbkdf2_salt = NULL; pbkdf2_param = PBMAC1_get1_pbkdf2_param(macalg); if (pbkdf2_param == NULL) { ERR_raise(ERR_LIB_PKCS12, ERR_R_UNSUPPORTED); goto err; } if (pbkdf2_param->prf == NULL) { kdf_hmac_nid = NID_hmacWithSHA1; } else { X509_ALGOR_get0(&kdf_hmac_oid, NULL, NULL, pbkdf2_param->prf); kdf_hmac_nid = OBJ_obj2nid(kdf_hmac_oid); } kdf_md = EVP_MD_fetch(ctx, OBJ_nid2sn(ossl_hmac2mdnid(kdf_hmac_nid)), propq); if (kdf_md == NULL) { ERR_raise(ERR_LIB_PKCS12, ERR_R_FETCH_FAILED); goto err; } /* Validate salt is an OCTET STRING choice */ if (pbkdf2_param->salt == NULL || pbkdf2_param->salt->type != V_ASN1_OCTET_STRING) { ERR_raise_data(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR, "Invalid Salt"); goto err; } pbkdf2_salt = pbkdf2_param->salt->value.octet_string; /* RFC 9879 specifies missing key length as invalid */ if (pbkdf2_param->keylength != NULL) keylen = ASN1_INTEGER_get(pbkdf2_param->keylength); /* RFC 9879 specifies too short key length as untrustworthy too */ if (keylen < 20 || keylen > EVP_MAX_MD_SIZE) { ERR_raise_data(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR, "Invalid Key length (%d is not in the range 20..64)", keylen); goto err; } if (PKCS5_PBKDF2_HMAC(pass, passlen, pbkdf2_salt->data, pbkdf2_salt->length, ASN1_INTEGER_get(pbkdf2_param->iter), kdf_md, keylen, key) <= 0) { ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); goto err; } ret = keylen; err: EVP_MD_free(kdf_md); PBKDF2PARAM_free(pbkdf2_param); return ret; }