int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, int en_de) { PBEPARAM *pbe; int saltlen, iter, ret; unsigned char *salt; const unsigned char *pbuf; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; if (cipher == NULL) return 0; /* Extract useful info from parameter */ if (param == NULL || param->type != V_ASN1_SEQUENCE || param->value.sequence == NULL) { PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); return 0; } pbuf = param->value.sequence->data; if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); return 0; } if (!pbe->iter) iter = 1; else iter = ASN1_INTEGER_get(pbe->iter); salt = pbe->salt->data; saltlen = pbe->salt->length; if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID, iter, EVP_CIPHER_key_length(cipher), key, md)) { PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR); PBEPARAM_free(pbe); return 0; } if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID, iter, EVP_CIPHER_iv_length(cipher), iv, md)) { PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR); PBEPARAM_free(pbe); return 0; } PBEPARAM_free(pbe); ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); return ret; }
static int test_pkcs12_pbe(struct tests *t) { void *key; size_t pwlen = 0; key = malloc(t->keylen); if (t->password) pwlen = strlen(t->password); if (!PKCS12_key_gen(t->password, pwlen, t->salt, t->saltsize, t->id, t->iterations, t->keylen, key, t->md())) { printf("key_gen failed\n"); return 1; } if (memcmp(t->key, key, t->keylen) != 0) { printf("incorrect key\n"); free(key); return 1; } free(key); return 0; }
/* Generate a MAC */ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *mac, unsigned int *maclen) { const EVP_MD *md_type; HMAC_CTX hmac; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; int md_size = 0; int md_type_nid; if (!PKCS7_type_is_data(p12->authsafes)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); return 0; } salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (!p12->mac->iter) iter = 1; else iter = ASN1_INTEGER_get(p12->mac->iter); if ((md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm)) == NULL) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } md_size = EVP_MD_size(md_type); md_type_nid = EVP_MD_type(md_type); if (md_size < 0) return 0; if ((md_type_nid == NID_id_GostR3411_94 || md_type_nid == NID_id_GostR3411_2012_256 || md_type_nid == NID_id_GostR3411_2012_512) && !getenv("LEGACY_GOST_PKCS12")) { md_size = TK26_MAC_KEY_LEN; if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, md_size, key, md_type)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); return 0; } } else if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, md_size, key, md_type)) { PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); return 0; } HMAC_CTX_init(&hmac); if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) || !HMAC_Update(&hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length) || !HMAC_Final(&hmac, mac, maclen)) { HMAC_CTX_cleanup(&hmac); return 0; } HMAC_CTX_cleanup(&hmac); return 1; }
/* Generate a MAC */ int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *mac, unsigned int *maclen) { const EVP_MD *md_type; HMAC_CTX hmac; unsigned char key[EVP_MAX_MD_SIZE], *salt; int saltlen, iter; int md_size; if (!PKCS7_type_is_data(p12->authsafes)) { PKCS12error(PKCS12_R_CONTENT_TYPE_NOT_DATA); return 0; } salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (!p12->mac->iter) iter = 1; else if ((iter = ASN1_INTEGER_get(p12->mac->iter)) <= 0) { PKCS12error(PKCS12_R_DECODE_ERROR); return 0; } if (!(md_type = EVP_get_digestbyobj( p12->mac->dinfo->algor->algorithm))) { PKCS12error(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); return 0; } md_size = EVP_MD_size(md_type); if (md_size < 0) return 0; if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, md_size, key, md_type)) { PKCS12error(PKCS12_R_KEY_GEN_ERROR); return 0; } HMAC_CTX_init(&hmac); if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) || !HMAC_Update(&hmac, p12->authsafes->d.data->data, p12->authsafes->d.data->length) || !HMAC_Final(&hmac, mac, maclen)) { HMAC_CTX_cleanup(&hmac); return 0; } HMAC_CTX_cleanup(&hmac); return 1; }