/* Provenance: openssl/openssl PBMAC1_PBKDF2_HMAC (fixed). * repo: openssl/openssl * commit: 205e3a55e16e4bd08c12fdbd3416ab829c0f6206 * parent: b8654779e3b3b4eb0bda7623c0891d394e068187 * commit_url: https://github.com/openssl/openssl/commit/205e3a55e16e4bd08c12fdbd3416ab829c0f6206 * cve: CVE-2025-11187 * 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(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR); goto err; } pbkdf2_salt = pbkdf2_param->salt->value.octet_string; /* RFC 9579 specifies missing key length as invalid */ if (pbkdf2_param->keylength != NULL) keylen = ASN1_INTEGER_get(pbkdf2_param->keylength); if (keylen <= 0 || keylen > EVP_MAX_MD_SIZE) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR); 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; }