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