/src/openssl30/crypto/evp/evp_pbe.c
| Line | Count | Source (jump to first uncovered line) | 
| 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 |  | #include <stdio.h> | 
| 11 |  | #include "internal/cryptlib.h" | 
| 12 |  | #include <openssl/evp.h> | 
| 13 |  | #include <openssl/core.h> | 
| 14 |  | #include <openssl/core_names.h> | 
| 15 |  | #include <openssl/pkcs12.h> | 
| 16 |  | #include <openssl/x509.h> | 
| 17 |  | #include "crypto/evp.h" | 
| 18 |  | #include "evp_local.h" | 
| 19 |  |  | 
| 20 |  | /* Password based encryption (PBE) functions */ | 
| 21 |  |  | 
| 22 |  | /* Setup a cipher context from a PBE algorithm */ | 
| 23 |  |  | 
| 24 |  | struct evp_pbe_st { | 
| 25 |  |     int pbe_type; | 
| 26 |  |     int pbe_nid; | 
| 27 |  |     int cipher_nid; | 
| 28 |  |     int md_nid; | 
| 29 |  |     EVP_PBE_KEYGEN *keygen; | 
| 30 |  |     EVP_PBE_KEYGEN_EX *keygen_ex; | 
| 31 |  | }; | 
| 32 |  |  | 
| 33 |  | static STACK_OF(EVP_PBE_CTL) *pbe_algs; | 
| 34 |  |  | 
| 35 |  | static const EVP_PBE_CTL builtin_pbe[] = { | 
| 36 |  |     {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, | 
| 37 |  |      NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, | 
| 38 |  |     {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, | 
| 39 |  |      NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, | 
| 40 |  |     {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, | 
| 41 |  |      NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, | 
| 42 |  |  | 
| 43 |  |     {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, | 
| 44 |  |  | 
| 45 |  |     {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, | 
| 46 |  |      NID_rc4, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, | 
| 47 |  |     {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, | 
| 48 |  |      NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, | 
| 49 |  |     {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, | 
| 50 |  |      NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, | 
| 51 |  |     {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, | 
| 52 |  |      NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, | 
| 53 |  |     {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, | 
| 54 |  |      NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, | 
| 55 |  |     {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, | 
| 56 |  |      NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen, &PKCS12_PBE_keyivgen_ex}, | 
| 57 |  |  | 
| 58 |  |     {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen, &PKCS5_v2_PBE_keyivgen_ex}, | 
| 59 |  |  | 
| 60 |  |     {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, | 
| 61 |  |      NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, | 
| 62 |  |     {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, | 
| 63 |  |      NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, | 
| 64 |  |     {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, | 
| 65 |  |      NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen, PKCS5_PBE_keyivgen_ex}, | 
| 66 |  |  | 
| 67 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, | 
| 68 |  |     {EVP_PBE_TYPE_PRF, NID_hmac_md5, -1, NID_md5, 0}, | 
| 69 |  |     {EVP_PBE_TYPE_PRF, NID_hmac_sha1, -1, NID_sha1, 0}, | 
| 70 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, | 
| 71 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, | 
| 72 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, | 
| 73 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, | 
| 74 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, | 
| 75 |  |     {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, | 
| 76 |  |     {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_256, -1, | 
| 77 |  |      NID_id_GostR3411_2012_256, 0}, | 
| 78 |  |     {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_512, -1, | 
| 79 |  |      NID_id_GostR3411_2012_512, 0}, | 
| 80 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_224, -1, NID_sha512_224, 0}, | 
| 81 |  |     {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512_256, -1, NID_sha512_256, 0}, | 
| 82 |  |     {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen, &PKCS5_v2_PBKDF2_keyivgen_ex}, | 
| 83 |  | #ifndef OPENSSL_NO_SCRYPT | 
| 84 |  |     {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen, &PKCS5_v2_scrypt_keyivgen_ex} | 
| 85 |  | #endif | 
| 86 |  | }; | 
| 87 |  |  | 
| 88 |  |  | 
| 89 |  | int EVP_PBE_CipherInit_ex(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, | 
| 90 |  |                           ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de, | 
| 91 |  |                           OSSL_LIB_CTX *libctx, const char *propq) | 
| 92 | 0 | { | 
| 93 | 0 |     const EVP_CIPHER *cipher = NULL; | 
| 94 | 0 |     EVP_CIPHER *cipher_fetch = NULL; | 
| 95 | 0 |     const EVP_MD *md = NULL; | 
| 96 | 0 |     EVP_MD *md_fetch = NULL; | 
| 97 | 0 |     int ret = 0, cipher_nid, md_nid; | 
| 98 | 0 |     EVP_PBE_KEYGEN_EX *keygen_ex; | 
| 99 | 0 |     EVP_PBE_KEYGEN *keygen; | 
| 100 |  | 
 | 
| 101 | 0 |     if (!EVP_PBE_find_ex(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), | 
| 102 | 0 |                          &cipher_nid, &md_nid, &keygen, &keygen_ex)) { | 
| 103 | 0 |         char obj_tmp[80]; | 
| 104 |  | 
 | 
| 105 | 0 |         if (pbe_obj == NULL) | 
| 106 | 0 |             OPENSSL_strlcpy(obj_tmp, "NULL", sizeof(obj_tmp)); | 
| 107 | 0 |         else | 
| 108 | 0 |             i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), pbe_obj); | 
| 109 | 0 |         ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM, | 
| 110 | 0 |                        "TYPE=%s", obj_tmp); | 
| 111 | 0 |         goto err; | 
| 112 | 0 |     } | 
| 113 |  |  | 
| 114 | 0 |     if (pass == NULL) | 
| 115 | 0 |         passlen = 0; | 
| 116 | 0 |     else if (passlen == -1) | 
| 117 | 0 |         passlen = strlen(pass); | 
| 118 |  | 
 | 
| 119 | 0 |     if (cipher_nid != -1) { | 
| 120 | 0 |         (void)ERR_set_mark(); | 
| 121 | 0 |         cipher = cipher_fetch = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(cipher_nid), propq); | 
| 122 |  |         /* Fallback to legacy method */ | 
| 123 | 0 |         if (cipher == NULL) | 
| 124 | 0 |             cipher = EVP_get_cipherbynid(cipher_nid); | 
| 125 | 0 |         if (cipher == NULL) { | 
| 126 | 0 |             (void)ERR_clear_last_mark(); | 
| 127 | 0 |             ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER, | 
| 128 | 0 |                            OBJ_nid2sn(cipher_nid)); | 
| 129 | 0 |             goto err; | 
| 130 | 0 |         } | 
| 131 | 0 |         (void)ERR_pop_to_mark(); | 
| 132 | 0 |     } | 
| 133 |  |  | 
| 134 | 0 |     if (md_nid != -1) { | 
| 135 | 0 |         (void)ERR_set_mark(); | 
| 136 | 0 |         md = md_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(md_nid), propq); | 
| 137 |  |         /* Fallback to legacy method */ | 
| 138 | 0 |         if (md == NULL) | 
| 139 | 0 |             md = EVP_get_digestbynid(md_nid); | 
| 140 |  | 
 | 
| 141 | 0 |         if (md == NULL) { | 
| 142 | 0 |             (void)ERR_clear_last_mark(); | 
| 143 | 0 |             ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST); | 
| 144 | 0 |             goto err; | 
| 145 | 0 |         } | 
| 146 | 0 |         (void)ERR_pop_to_mark(); | 
| 147 | 0 |     } | 
| 148 |  |  | 
| 149 |  |     /* Try extended keygen with libctx/propq first, fall back to legacy keygen */ | 
| 150 | 0 |     if (keygen_ex != NULL) | 
| 151 | 0 |         ret = keygen_ex(ctx, pass, passlen, param, cipher, md, en_de, libctx, propq); | 
| 152 | 0 |     else | 
| 153 | 0 |         ret = keygen(ctx, pass, passlen, param, cipher, md, en_de); | 
| 154 |  | 
 | 
| 155 | 0 | err: | 
| 156 | 0 |     EVP_CIPHER_free(cipher_fetch); | 
| 157 | 0 |     EVP_MD_free(md_fetch); | 
| 158 |  | 
 | 
| 159 | 0 |     return ret; | 
| 160 | 0 | } | 
| 161 |  |  | 
| 162 |  | int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, | 
| 163 |  |                        ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) | 
| 164 | 0 | { | 
| 165 | 0 |     return EVP_PBE_CipherInit_ex(pbe_obj, pass, passlen, param, ctx, en_de, NULL, NULL); | 
| 166 | 0 | } | 
| 167 |  |  | 
| 168 |  | DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); | 
| 169 |  |  | 
| 170 |  | static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) | 
| 171 | 650 | { | 
| 172 | 650 |     int ret = pbe1->pbe_type - pbe2->pbe_type; | 
| 173 | 650 |     if (ret) | 
| 174 | 142 |         return ret; | 
| 175 | 508 |     else | 
| 176 | 508 |         return pbe1->pbe_nid - pbe2->pbe_nid; | 
| 177 | 650 | } | 
| 178 |  |  | 
| 179 |  | IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); | 
| 180 |  |  | 
| 181 |  | static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b) | 
| 182 | 0 | { | 
| 183 | 0 |     int ret = (*a)->pbe_type - (*b)->pbe_type; | 
| 184 | 0 |     if (ret) | 
| 185 | 0 |         return ret; | 
| 186 | 0 |     else | 
| 187 | 0 |         return (*a)->pbe_nid - (*b)->pbe_nid; | 
| 188 | 0 | } | 
| 189 |  |  | 
| 190 |  | /* Add a PBE algorithm */ | 
| 191 |  |  | 
| 192 |  | int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, | 
| 193 |  |                          int md_nid, EVP_PBE_KEYGEN *keygen) | 
| 194 | 0 | { | 
| 195 | 0 |     EVP_PBE_CTL *pbe_tmp; | 
| 196 |  | 
 | 
| 197 | 0 |     if (pbe_algs == NULL) { | 
| 198 | 0 |         pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); | 
| 199 | 0 |         if (pbe_algs == NULL) | 
| 200 | 0 |             goto err; | 
| 201 | 0 |     } | 
| 202 |  |  | 
| 203 | 0 |     if ((pbe_tmp = OPENSSL_zalloc(sizeof(*pbe_tmp))) == NULL) | 
| 204 | 0 |         goto err; | 
| 205 |  |  | 
| 206 | 0 |     pbe_tmp->pbe_type = pbe_type; | 
| 207 | 0 |     pbe_tmp->pbe_nid = pbe_nid; | 
| 208 | 0 |     pbe_tmp->cipher_nid = cipher_nid; | 
| 209 | 0 |     pbe_tmp->md_nid = md_nid; | 
| 210 | 0 |     pbe_tmp->keygen = keygen; | 
| 211 |  | 
 | 
| 212 | 0 |     if (!sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp)) { | 
| 213 | 0 |         OPENSSL_free(pbe_tmp); | 
| 214 | 0 |         goto err; | 
| 215 | 0 |     } | 
| 216 | 0 |     return 1; | 
| 217 |  |  | 
| 218 | 0 |  err: | 
| 219 | 0 |     ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); | 
| 220 | 0 |     return 0; | 
| 221 | 0 | } | 
| 222 |  |  | 
| 223 |  | int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, | 
| 224 |  |                     EVP_PBE_KEYGEN *keygen) | 
| 225 | 0 | { | 
| 226 | 0 |     int cipher_nid, md_nid; | 
| 227 |  | 
 | 
| 228 | 0 |     if (cipher) | 
| 229 | 0 |         cipher_nid = EVP_CIPHER_get_nid(cipher); | 
| 230 | 0 |     else | 
| 231 | 0 |         cipher_nid = -1; | 
| 232 | 0 |     if (md) | 
| 233 | 0 |         md_nid = EVP_MD_get_type(md); | 
| 234 | 0 |     else | 
| 235 | 0 |         md_nid = -1; | 
| 236 |  | 
 | 
| 237 | 0 |     return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, | 
| 238 | 0 |                                 cipher_nid, md_nid, keygen); | 
| 239 | 0 | } | 
| 240 |  |  | 
| 241 |  | int EVP_PBE_find_ex(int type, int pbe_nid, int *pcnid, int *pmnid, | 
| 242 |  |                     EVP_PBE_KEYGEN **pkeygen, EVP_PBE_KEYGEN_EX **pkeygen_ex) | 
| 243 | 259 | { | 
| 244 | 259 |     EVP_PBE_CTL *pbetmp = NULL, pbelu; | 
| 245 | 259 |     int i; | 
| 246 | 259 |     if (pbe_nid == NID_undef) | 
| 247 | 111 |         return 0; | 
| 248 |  |  | 
| 249 | 148 |     pbelu.pbe_type = type; | 
| 250 | 148 |     pbelu.pbe_nid = pbe_nid; | 
| 251 |  |  | 
| 252 | 148 |     if (pbe_algs != NULL) { | 
| 253 | 0 |         i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); | 
| 254 | 0 |         pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i); | 
| 255 | 0 |     } | 
| 256 | 148 |     if (pbetmp == NULL) { | 
| 257 | 148 |         pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, OSSL_NELEM(builtin_pbe)); | 
| 258 | 148 |     } | 
| 259 | 148 |     if (pbetmp == NULL) | 
| 260 | 25 |         return 0; | 
| 261 | 123 |     if (pcnid != NULL) | 
| 262 | 0 |         *pcnid = pbetmp->cipher_nid; | 
| 263 | 123 |     if (pmnid != NULL) | 
| 264 | 123 |         *pmnid = pbetmp->md_nid; | 
| 265 | 123 |     if (pkeygen != NULL) | 
| 266 | 0 |         *pkeygen = pbetmp->keygen; | 
| 267 | 123 |     if (pkeygen_ex != NULL) | 
| 268 | 0 |         *pkeygen_ex = pbetmp->keygen_ex; | 
| 269 | 123 |     return 1; | 
| 270 | 148 | } | 
| 271 |  |  | 
| 272 |  | int EVP_PBE_find(int type, int pbe_nid, | 
| 273 |  |                  int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) | 
| 274 | 259 | { | 
| 275 | 259 |     return EVP_PBE_find_ex(type, pbe_nid, pcnid, pmnid, pkeygen, NULL); | 
| 276 | 259 | } | 
| 277 |  |  | 
| 278 |  | static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) | 
| 279 | 0 | { | 
| 280 | 0 |     OPENSSL_free(pbe); | 
| 281 | 0 | } | 
| 282 |  |  | 
| 283 |  | void EVP_PBE_cleanup(void) | 
| 284 | 76 | { | 
| 285 | 76 |     sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); | 
| 286 | 76 |     pbe_algs = NULL; | 
| 287 | 76 | } | 
| 288 |  |  | 
| 289 |  | int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num) | 
| 290 | 0 | { | 
| 291 | 0 |     const EVP_PBE_CTL *tpbe; | 
| 292 |  | 
 | 
| 293 | 0 |     if (num >= OSSL_NELEM(builtin_pbe)) | 
| 294 | 0 |         return 0; | 
| 295 |  |  | 
| 296 | 0 |     tpbe = builtin_pbe + num; | 
| 297 | 0 |     if (ptype) | 
| 298 | 0 |         *ptype = tpbe->pbe_type; | 
| 299 | 0 |     if (ppbe_nid) | 
| 300 | 0 |         *ppbe_nid = tpbe->pbe_nid; | 
| 301 | 0 |     return 1; | 
| 302 | 0 | } |