1 /* 2 * Copyright 1999-2024 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 if (p12->authsafes->d.data == NULL) { 102 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR); 103 return 0; 104 } 105 106 salt = p12->mac->salt->data; 107 saltlen = p12->mac->salt->length; 108 if (p12->mac->iter == NULL) 109 iter = 1; 110 else 111 iter = ASN1_INTEGER_get(p12->mac->iter); 112 X509_SIG_get0(p12->mac->dinfo, &macalg, NULL); 113 X509_ALGOR_get0(&macoid, NULL, NULL, macalg); 114 if (OBJ_obj2txt(md_name, sizeof(md_name), macoid, 0) < 0) 115 return 0; 116 117 (void)ERR_set_mark(); 118 md = md_fetch = EVP_MD_fetch(p12->authsafes->ctx.libctx, md_name, 119 p12->authsafes->ctx.propq); 120 if (md == NULL) 121 md = EVP_get_digestbynid(OBJ_obj2nid(macoid)); 122 123 if (md == NULL) { 124 (void)ERR_clear_last_mark(); 125 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); 126 return 0; 127 } 128 (void)ERR_pop_to_mark(); 129 130 md_size = EVP_MD_get_size(md); 131 md_nid = EVP_MD_get_type(md); 132 if (md_size < 0) 133 goto err; 134 if ((md_nid == NID_id_GostR3411_94 135 || md_nid == NID_id_GostR3411_2012_256 136 || md_nid == NID_id_GostR3411_2012_512) 137 && ossl_safe_getenv("LEGACY_GOST_PKCS12") == NULL) { 138 md_size = TK26_MAC_KEY_LEN; 139 if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter, 140 md_size, key, md)) { 141 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); 142 goto err; 143 } 144 } else { 145 if (pkcs12_key_gen != NULL) { 146 if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID, 147 iter, md_size, key, md)) { 148 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); 149 goto err; 150 } 151 } else { 152 /* Default to UTF-8 password */ 153 if (!PKCS12_key_gen_utf8_ex(pass, passlen, salt, saltlen, PKCS12_MAC_ID, 154 iter, md_size, key, md, 155 p12->authsafes->ctx.libctx, 156 p12->authsafes->ctx.propq)) { 157 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR); 158 goto err; 159 } 160 } 161 } 162 if ((hmac = HMAC_CTX_new()) == NULL 163 || !HMAC_Init_ex(hmac, key, md_size, md, NULL) 164 || !HMAC_Update(hmac, p12->authsafes->d.data->data, 165 p12->authsafes->d.data->length) 166 || !HMAC_Final(hmac, mac, maclen)) { 167 goto err; 168 } 169 ret = 1; 170 171 err: 172 OPENSSL_cleanse(key, sizeof(key)); 173 HMAC_CTX_free(hmac); 174 EVP_MD_free(md_fetch); 175 return ret; 176 } 177 178 int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, 179 unsigned char *mac, unsigned int *maclen) 180 { 181 return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NULL); 182 } 183 184 /* Verify the mac */ 185 int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) 186 { 187 unsigned char mac[EVP_MAX_MD_SIZE]; 188 unsigned int maclen; 189 const ASN1_OCTET_STRING *macoct; 190 191 if (p12->mac == NULL) { 192 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT); 193 return 0; 194 } 195 if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { 196 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); 197 return 0; 198 } 199 X509_SIG_get0(p12->mac->dinfo, NULL, &macoct); 200 if ((maclen != (unsigned int)ASN1_STRING_length(macoct)) 201 || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen) != 0) 202 return 0; 203 204 return 1; 205 } 206 207 /* Set a mac */ 208 209 int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, 210 unsigned char *salt, int saltlen, int iter, 211 const EVP_MD *md_type) 212 { 213 unsigned char mac[EVP_MAX_MD_SIZE]; 214 unsigned int maclen; 215 ASN1_OCTET_STRING *macoct; 216 217 if (md_type == NULL) 218 /* No need to do a fetch as the md_type is used only to get a NID */ 219 md_type = EVP_sha256(); 220 if (!iter) 221 iter = PKCS12_DEFAULT_ITER; 222 if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { 223 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR); 224 return 0; 225 } 226 /* 227 * Note that output mac is forced to UTF-8... 228 */ 229 if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NULL)) { 230 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); 231 return 0; 232 } 233 X509_SIG_getm(p12->mac->dinfo, NULL, &macoct); 234 if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) { 235 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR); 236 return 0; 237 } 238 return 1; 239 } 240 241 /* Set up a mac structure */ 242 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, 243 const EVP_MD *md_type) 244 { 245 X509_ALGOR *macalg; 246 247 PKCS12_MAC_DATA_free(p12->mac); 248 p12->mac = NULL; 249 250 if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) 251 return PKCS12_ERROR; 252 if (iter > 1) { 253 if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) { 254 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 255 return 0; 256 } 257 if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { 258 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 259 return 0; 260 } 261 } 262 if (saltlen == 0) 263 saltlen = PKCS12_SALT_LEN; 264 else if (saltlen < 0) 265 return 0; 266 if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { 267 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 268 return 0; 269 } 270 p12->mac->salt->length = saltlen; 271 if (salt == NULL) { 272 if (RAND_bytes_ex(p12->authsafes->ctx.libctx, p12->mac->salt->data, 273 (size_t)saltlen, 0) <= 0) 274 return 0; 275 } else { 276 memcpy(p12->mac->salt->data, salt, saltlen); 277 } 278 X509_SIG_getm(p12->mac->dinfo, &macalg, NULL); 279 if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_get_type(md_type)), 280 V_ASN1_NULL, NULL)) { 281 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE); 282 return 0; 283 } 284 285 return 1; 286 } 287