1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * HMAC low level APIs are deprecated for public use, but still ok for internal 12e1051a39Sopenharmony_ci * use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 18e1051a39Sopenharmony_ci#include <openssl/crypto.h> 19e1051a39Sopenharmony_ci#include <openssl/hmac.h> 20e1051a39Sopenharmony_ci#include <openssl/rand.h> 21e1051a39Sopenharmony_ci#include <openssl/pkcs12.h> 22e1051a39Sopenharmony_ci#include "p12_local.h" 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ciint PKCS12_mac_present(const PKCS12 *p12) 25e1051a39Sopenharmony_ci{ 26e1051a39Sopenharmony_ci return p12->mac ? 1 : 0; 27e1051a39Sopenharmony_ci} 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_civoid PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, 30e1051a39Sopenharmony_ci const X509_ALGOR **pmacalg, 31e1051a39Sopenharmony_ci const ASN1_OCTET_STRING **psalt, 32e1051a39Sopenharmony_ci const ASN1_INTEGER **piter, 33e1051a39Sopenharmony_ci const PKCS12 *p12) 34e1051a39Sopenharmony_ci{ 35e1051a39Sopenharmony_ci if (p12->mac) { 36e1051a39Sopenharmony_ci X509_SIG_get0(p12->mac->dinfo, pmacalg, pmac); 37e1051a39Sopenharmony_ci if (psalt) 38e1051a39Sopenharmony_ci *psalt = p12->mac->salt; 39e1051a39Sopenharmony_ci if (piter) 40e1051a39Sopenharmony_ci *piter = p12->mac->iter; 41e1051a39Sopenharmony_ci } else { 42e1051a39Sopenharmony_ci if (pmac) 43e1051a39Sopenharmony_ci *pmac = NULL; 44e1051a39Sopenharmony_ci if (pmacalg) 45e1051a39Sopenharmony_ci *pmacalg = NULL; 46e1051a39Sopenharmony_ci if (psalt) 47e1051a39Sopenharmony_ci *psalt = NULL; 48e1051a39Sopenharmony_ci if (piter) 49e1051a39Sopenharmony_ci *piter = NULL; 50e1051a39Sopenharmony_ci } 51e1051a39Sopenharmony_ci} 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci#define TK26_MAC_KEY_LEN 32 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_cistatic int pkcs12_gen_gost_mac_key(const char *pass, int passlen, 56e1051a39Sopenharmony_ci const unsigned char *salt, int saltlen, 57e1051a39Sopenharmony_ci int iter, int keylen, unsigned char *key, 58e1051a39Sopenharmony_ci const EVP_MD *digest) 59e1051a39Sopenharmony_ci{ 60e1051a39Sopenharmony_ci unsigned char out[96]; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci if (keylen != TK26_MAC_KEY_LEN) { 63e1051a39Sopenharmony_ci return 0; 64e1051a39Sopenharmony_ci } 65e1051a39Sopenharmony_ci 66e1051a39Sopenharmony_ci if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, 67e1051a39Sopenharmony_ci digest, sizeof(out), out)) { 68e1051a39Sopenharmony_ci return 0; 69e1051a39Sopenharmony_ci } 70e1051a39Sopenharmony_ci memcpy(key, out + sizeof(out) - TK26_MAC_KEY_LEN, TK26_MAC_KEY_LEN); 71e1051a39Sopenharmony_ci OPENSSL_cleanse(out, sizeof(out)); 72e1051a39Sopenharmony_ci return 1; 73e1051a39Sopenharmony_ci} 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci/* Generate a MAC */ 76e1051a39Sopenharmony_cistatic int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, 77e1051a39Sopenharmony_ci unsigned char *mac, unsigned int *maclen, 78e1051a39Sopenharmony_ci int (*pkcs12_key_gen)(const char *pass, int passlen, 79e1051a39Sopenharmony_ci unsigned char *salt, int slen, 80e1051a39Sopenharmony_ci int id, int iter, int n, 81e1051a39Sopenharmony_ci unsigned char *out, 82e1051a39Sopenharmony_ci const EVP_MD *md_type)) 83e1051a39Sopenharmony_ci{ 84e1051a39Sopenharmony_ci int ret = 0; 85e1051a39Sopenharmony_ci const EVP_MD *md; 86e1051a39Sopenharmony_ci EVP_MD *md_fetch; 87e1051a39Sopenharmony_ci HMAC_CTX *hmac = NULL; 88e1051a39Sopenharmony_ci unsigned char key[EVP_MAX_MD_SIZE], *salt; 89e1051a39Sopenharmony_ci int saltlen, iter; 90e1051a39Sopenharmony_ci char md_name[80]; 91e1051a39Sopenharmony_ci int md_size = 0; 92e1051a39Sopenharmony_ci int md_nid; 93e1051a39Sopenharmony_ci const X509_ALGOR *macalg; 94e1051a39Sopenharmony_ci const ASN1_OBJECT *macoid; 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci if (!PKCS7_type_is_data(p12->authsafes)) { 97e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA); 98e1051a39Sopenharmony_ci return 0; 99e1051a39Sopenharmony_ci } 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci if (p12->authsafes->d.data == NULL) { 102e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); 103e1051a39Sopenharmony_ci return 0; 104e1051a39Sopenharmony_ci } 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci salt = p12->mac->salt->data; 107e1051a39Sopenharmony_ci saltlen = p12->mac->salt->length; 108e1051a39Sopenharmony_ci if (p12->mac->iter == NULL) 109e1051a39Sopenharmony_ci iter = 1; 110e1051a39Sopenharmony_ci else 111e1051a39Sopenharmony_ci iter = ASN1_INTEGER_get(p12->mac->iter); 112e1051a39Sopenharmony_ci X509_SIG_get0(p12->mac->dinfo, &macalg, NULL); 113e1051a39Sopenharmony_ci X509_ALGOR_get0(&macoid, NULL, NULL, macalg); 114e1051a39Sopenharmony_ci if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0) 115e1051a39Sopenharmony_ci return 0; 116e1051a39Sopenharmony_ci md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name, 117e1051a39Sopenharmony_ci p12->authsafes->ctx.propq); 118e1051a39Sopenharmony_ci if (md == NULL) 119e1051a39Sopenharmony_ci md = EVP_get_digestbynid(OBJ_obj2nid(macoid)); 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci if (md == NULL) { 122e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); 123e1051a39Sopenharmony_ci return 0; 124e1051a39Sopenharmony_ci } 125e1051a39Sopenharmony_ci md_size = EVP_MD_get_size(md); 126e1051a39Sopenharmony_ci md_nid = EVP_MD_get_type(md); 127e1051a39Sopenharmony_ci if (md_size < 0) 128e1051a39Sopenharmony_ci goto err; 129e1051a39Sopenharmony_ci if ((md_nid == NID_id_GostR3411_94 130e1051a39Sopenharmony_ci || md_nid == NID_id_GostR3411_2012_256 131e1051a39Sopenharmony_ci || md_nid == NID_id_GostR3411_2012_512) 132e1051a39Sopenharmony_ci && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) { 133e1051a39Sopenharmony_ci md_size = TK26_MAC_KEY_LEN; 134e1051a39Sopenharmony_ci if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, 135e1051a39Sopenharmony_ci md_size, key, md)) { 136e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); 137e1051a39Sopenharmony_ci goto err; 138e1051a39Sopenharmony_ci } 139e1051a39Sopenharmony_ci } else { 140e1051a39Sopenharmony_ci if (pkcs12_key_gen != NULL) { 141e1051a39Sopenharmony_ci if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, 142e1051a39Sopenharmony_ci iter, md_size, key, md)) { 143e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); 144e1051a39Sopenharmony_ci goto err; 145e1051a39Sopenharmony_ci } 146e1051a39Sopenharmony_ci } else { 147e1051a39Sopenharmony_ci /* Default to UTF-8 password */ 148e1051a39Sopenharmony_ci if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_MAC_ID, 149e1051a39Sopenharmony_ci iter, md_size, key, md, 150e1051a39Sopenharmony_ci p12->authsafes->ctx.libctx, 151e1051a39Sopenharmony_ci p12->authsafes->ctx.propq)) { 152e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); 153e1051a39Sopenharmony_ci goto err; 154e1051a39Sopenharmony_ci } 155e1051a39Sopenharmony_ci } 156e1051a39Sopenharmony_ci } 157e1051a39Sopenharmony_ci if ((hmac = HMAC_CTX_new()) == NULL 158e1051a39Sopenharmony_ci || !HMAC_Init_ex(hmac, key, md_size, md, NULL) 159e1051a39Sopenharmony_ci || !HMAC_Update(hmac, p12->authsafes->d.data->data, 160e1051a39Sopenharmony_ci p12->authsafes->d.data->length) 161e1051a39Sopenharmony_ci || !HMAC_Final(hmac, mac, maclen)) { 162e1051a39Sopenharmony_ci goto err; 163e1051a39Sopenharmony_ci } 164e1051a39Sopenharmony_ci ret = 1; 165e1051a39Sopenharmony_ci 166e1051a39Sopenharmony_cierr: 167e1051a39Sopenharmony_ci OPENSSL_cleanse(key, sizeof(key)); 168e1051a39Sopenharmony_ci HMAC_CTX_free(hmac); 169e1051a39Sopenharmony_ci EVP_MD_free(md_fetch); 170e1051a39Sopenharmony_ci return ret; 171e1051a39Sopenharmony_ci} 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ciint PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, 174e1051a39Sopenharmony_ci unsigned char *mac, unsigned int *maclen) 175e1051a39Sopenharmony_ci{ 176e1051a39Sopenharmony_ci return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NULL); 177e1051a39Sopenharmony_ci} 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_ci/* Verify the mac */ 180e1051a39Sopenharmony_ciint PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) 181e1051a39Sopenharmony_ci{ 182e1051a39Sopenharmony_ci unsigned char mac[EVP_MAX_MD_SIZE]; 183e1051a39Sopenharmony_ci unsigned int maclen; 184e1051a39Sopenharmony_ci const ASN1_OCTET_STRING *macoct; 185e1051a39Sopenharmony_ci 186e1051a39Sopenharmony_ci if (p12->mac == NULL) { 187e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT); 188e1051a39Sopenharmony_ci return 0; 189e1051a39Sopenharmony_ci } 190e1051a39Sopenharmony_ci if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { 191e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); 192e1051a39Sopenharmony_ci return 0; 193e1051a39Sopenharmony_ci } 194e1051a39Sopenharmony_ci X509_SIG_get0(p12->mac->dinfo, NULL, &macoct); 195e1051a39Sopenharmony_ci if ((maclen != (unsigned int)ASN1_STRING_length(macoct)) 196e1051a39Sopenharmony_ci || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen) != 0) 197e1051a39Sopenharmony_ci return 0; 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci return 1; 200e1051a39Sopenharmony_ci} 201e1051a39Sopenharmony_ci 202e1051a39Sopenharmony_ci/* Set a mac */ 203e1051a39Sopenharmony_ci 204e1051a39Sopenharmony_ciint PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, 205e1051a39Sopenharmony_ci unsigned char *salt, int saltlen, int iter, 206e1051a39Sopenharmony_ci const EVP_MD *md_type) 207e1051a39Sopenharmony_ci{ 208e1051a39Sopenharmony_ci unsigned char mac[EVP_MAX_MD_SIZE]; 209e1051a39Sopenharmony_ci unsigned int maclen; 210e1051a39Sopenharmony_ci ASN1_OCTET_STRING *macoct; 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci if (md_type == NULL) 213e1051a39Sopenharmony_ci /* No need to do a fetch as the md_type is used only to get a NID */ 214e1051a39Sopenharmony_ci md_type = EVP_sha256(); 215e1051a39Sopenharmony_ci if (!iter) 216e1051a39Sopenharmony_ci iter = PKCS12_DEFAULT_ITER; 217e1051a39Sopenharmony_ci if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { 218e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR); 219e1051a39Sopenharmony_ci return 0; 220e1051a39Sopenharmony_ci } 221e1051a39Sopenharmony_ci /* 222e1051a39Sopenharmony_ci * Note that output mac is forced to UTF-8... 223e1051a39Sopenharmony_ci */ 224e1051a39Sopenharmony_ci if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { 225e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); 226e1051a39Sopenharmony_ci return 0; 227e1051a39Sopenharmony_ci } 228e1051a39Sopenharmony_ci X509_SIG_getm(p12->mac->dinfo, NULL, &macoct); 229e1051a39Sopenharmony_ci if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) { 230e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR); 231e1051a39Sopenharmony_ci return 0; 232e1051a39Sopenharmony_ci } 233e1051a39Sopenharmony_ci return 1; 234e1051a39Sopenharmony_ci} 235e1051a39Sopenharmony_ci 236e1051a39Sopenharmony_ci/* Set up a mac structure */ 237e1051a39Sopenharmony_ciint PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, 238e1051a39Sopenharmony_ci const EVP_MD *md_type) 239e1051a39Sopenharmony_ci{ 240e1051a39Sopenharmony_ci X509_ALGOR *macalg; 241e1051a39Sopenharmony_ci 242e1051a39Sopenharmony_ci PKCS12_MAC_DATA_free(p12->mac); 243e1051a39Sopenharmony_ci p12->mac = NULL; 244e1051a39Sopenharmony_ci 245e1051a39Sopenharmony_ci if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) 246e1051a39Sopenharmony_ci return PKCS12_ERROR; 247e1051a39Sopenharmony_ci if (iter > 1) { 248e1051a39Sopenharmony_ci if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) { 249e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 250e1051a39Sopenharmony_ci return 0; 251e1051a39Sopenharmony_ci } 252e1051a39Sopenharmony_ci if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { 253e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 254e1051a39Sopenharmony_ci return 0; 255e1051a39Sopenharmony_ci } 256e1051a39Sopenharmony_ci } 257e1051a39Sopenharmony_ci if (saltlen == 0) 258e1051a39Sopenharmony_ci saltlen = PKCS12_SALT_LEN; 259e1051a39Sopenharmony_ci else if (saltlen < 0) 260e1051a39Sopenharmony_ci return 0; 261e1051a39Sopenharmony_ci if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { 262e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 263e1051a39Sopenharmony_ci return 0; 264e1051a39Sopenharmony_ci } 265e1051a39Sopenharmony_ci p12->mac->salt->length = saltlen; 266e1051a39Sopenharmony_ci if (salt == NULL) { 267e1051a39Sopenharmony_ci if (RAND_bytes_ex(p12->authsafes->ctx.libctx, p12->mac->salt->data, 268e1051a39Sopenharmony_ci (size_t)saltlen, 0) <= 0) 269e1051a39Sopenharmony_ci return 0; 270e1051a39Sopenharmony_ci } else { 271e1051a39Sopenharmony_ci memcpy(p12->mac->salt->data, salt, saltlen); 272e1051a39Sopenharmony_ci } 273e1051a39Sopenharmony_ci X509_SIG_getm(p12->mac->dinfo, &macalg, NULL); 274e1051a39Sopenharmony_ci if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_get_type(md_type)), 275e1051a39Sopenharmony_ci V_ASN1_NULL, NULL)) { 276e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 277e1051a39Sopenharmony_ci return 0; 278e1051a39Sopenharmony_ci } 279e1051a39Sopenharmony_ci 280e1051a39Sopenharmony_ci return 1; 281e1051a39Sopenharmony_ci} 282