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 <stdlib.h> 12 #include "internal/cryptlib.h" 13 #include <openssl/x509.h> 14 #include <openssl/evp.h> 15 #include <openssl/kdf.h> 16 #include <openssl/hmac.h> 17 #include <openssl/trace.h> 18 #include <openssl/core_names.h> 19 #include "crypto/evp.h" 20 #include "evp_local.h" 21 22 int ossl_pkcs5_pbkdf2_hmac_ex(const char *pass, int passlen, 23 const unsigned char *salt, int saltlen, int iter, 24 const EVP_MD *digest, int keylen, unsigned char *out, 25 OSSL_LIB_CTX *libctx, const char *propq) 26 { 27 const char *empty = ""; 28 int rv = 1, mode = 1; 29 EVP_KDF *kdf; 30 EVP_KDF_CTX *kctx; 31 const char *mdname = EVP_MD_get0_name(digest); 32 OSSL_PARAM params[6], *p = params; 33 34 /* Keep documented behaviour. */ 35 if (pass == NULL) { 36 pass = empty; 37 passlen = 0; 38 } else if (passlen == -1) { 39 passlen = strlen(pass); 40 } 41 if (salt == NULL && saltlen == 0) 42 salt = (unsigned char *)empty; 43 44 kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, propq); 45 if (kdf == NULL) 46 return 0; 47 kctx = EVP_KDF_CTX_new(kdf); 48 EVP_KDF_free(kdf); 49 if (kctx == NULL) 50 return 0; 51 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, 52 (char *)pass, (size_t)passlen); 53 *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &mode); 54 *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, 55 (unsigned char *)salt, saltlen); 56 *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); 57 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, 58 (char *)mdname, 0); 59 *p = OSSL_PARAM_construct_end(); 60 if (EVP_KDF_derive(kctx, out, keylen, params) != 1) 61 rv = 0; 62 63 EVP_KDF_CTX_free(kctx); 64 65 OSSL_TRACE_BEGIN(PKCS5V2) { 66 BIO_printf(trc_out, "Password:\n"); 67 BIO_hex_string(trc_out, 68 0, passlen, pass, passlen); 69 BIO_printf(trc_out, "\n"); 70 BIO_printf(trc_out, "Salt:\n"); 71 BIO_hex_string(trc_out, 72 0, saltlen, salt, saltlen); 73 BIO_printf(trc_out, "\n"); 74 BIO_printf(trc_out, "Iteration count %d\n", iter); 75 BIO_printf(trc_out, "Key:\n"); 76 BIO_hex_string(trc_out, 77 0, keylen, out, keylen); 78 BIO_printf(trc_out, "\n"); 79 } OSSL_TRACE_END(PKCS5V2); 80 return rv; 81 } 82 83 int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, 84 int saltlen, int iter, const EVP_MD *digest, int keylen, 85 unsigned char *out) 86 { 87 return ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, digest, 88 keylen, out, NULL, NULL); 89 } 90 91 92 int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, 93 const unsigned char *salt, int saltlen, int iter, 94 int keylen, unsigned char *out) 95 { 96 EVP_MD *digest; 97 int r = 0; 98 99 if ((digest = EVP_MD_fetch(NULL, SN_sha1, NULL)) != NULL) 100 r = ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, 101 digest, keylen, out, NULL, NULL); 102 EVP_MD_free(digest); 103 return r; 104 } 105 106 /* 107 * Now the key derivation function itself. This is a bit evil because it has 108 * to check the ASN1 parameters are valid: and there are quite a few of 109 * them... 110 */ 111 112 int PKCS5_v2_PBE_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, 113 ASN1_TYPE *param, const EVP_CIPHER *c, 114 const EVP_MD *md, int en_de, 115 OSSL_LIB_CTX *libctx, const char *propq) 116 { 117 PBE2PARAM *pbe2 = NULL; 118 char ciph_name[80]; 119 const EVP_CIPHER *cipher = NULL; 120 EVP_CIPHER *cipher_fetch = NULL; 121 EVP_PBE_KEYGEN_EX *kdf; 122 123 int rv = 0; 124 125 pbe2 = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBE2PARAM), param); 126 if (pbe2 == NULL) { 127 ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); 128 goto err; 129 } 130 131 /* See if we recognise the key derivation function */ 132 if (!EVP_PBE_find_ex(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm), 133 NULL, NULL, NULL, &kdf)) { 134 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); 135 goto err; 136 } 137 138 /* 139 * lets see if we recognise the encryption algorithm. 140 */ 141 if (OBJ_obj2txt(ciph_name, sizeof(ciph_name), pbe2->encryption->algorithm, 0) <= 0) { 142 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER); 143 goto err; 144 } 145 146 (void)ERR_set_mark(); 147 cipher = cipher_fetch = EVP_CIPHER_fetch(libctx, ciph_name, propq); 148 /* Fallback to legacy method */ 149 if (cipher == NULL) 150 cipher = EVP_get_cipherbyname(ciph_name); 151 152 if (cipher == NULL) { 153 (void)ERR_clear_last_mark(); 154 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER); 155 goto err; 156 } 157 (void)ERR_pop_to_mark(); 158 159 /* Fixup cipher based on AlgorithmIdentifier */ 160 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) 161 goto err; 162 if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) <= 0) { 163 ERR_raise(ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR); 164 goto err; 165 } 166 rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de, libctx, propq); 167 err: 168 EVP_CIPHER_free(cipher_fetch); 169 PBE2PARAM_free(pbe2); 170 return rv; 171 } 172 173 int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, 174 ASN1_TYPE *param, const EVP_CIPHER *c, 175 const EVP_MD *md, int en_de) 176 { 177 return PKCS5_v2_PBE_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, NULL, NULL); 178 } 179 180 int PKCS5_v2_PBKDF2_keyivgen_ex(EVP_CIPHER_CTX *ctx, const char *pass, 181 int passlen, ASN1_TYPE *param, 182 const EVP_CIPHER *c, const EVP_MD *md, int en_de, 183 OSSL_LIB_CTX *libctx, const char *propq) 184 { 185 unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; 186 int saltlen, iter, t; 187 int rv = 0; 188 unsigned int keylen = 0; 189 int prf_nid, hmac_md_nid; 190 PBKDF2PARAM *kdf = NULL; 191 const EVP_MD *prfmd = NULL; 192 EVP_MD *prfmd_fetch = NULL; 193 194 if (EVP_CIPHER_CTX_get0_cipher(ctx) == NULL) { 195 ERR_raise(ERR_LIB_EVP, EVP_R_NO_CIPHER_SET); 196 goto err; 197 } 198 keylen = EVP_CIPHER_CTX_get_key_length(ctx); 199 OPENSSL_assert(keylen <= sizeof(key)); 200 201 /* Decode parameter */ 202 203 kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param); 204 205 if (kdf == NULL) { 206 ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); 207 goto err; 208 } 209 210 t = EVP_CIPHER_CTX_get_key_length(ctx); 211 if (t < 0) { 212 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); 213 goto err; 214 } 215 keylen = t; 216 217 /* Now check the parameters of the kdf */ 218 219 if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) { 220 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH); 221 goto err; 222 } 223 224 if (kdf->prf) 225 prf_nid = OBJ_obj2nid(kdf->prf->algorithm); 226 else 227 prf_nid = NID_hmacWithSHA1; 228 229 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) { 230 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF); 231 goto err; 232 } 233 234 (void)ERR_set_mark(); 235 prfmd = prfmd_fetch = EVP_MD_fetch(libctx, OBJ_nid2sn(hmac_md_nid), propq); 236 if (prfmd == NULL) 237 prfmd = EVP_get_digestbynid(hmac_md_nid); 238 if (prfmd == NULL) { 239 (void)ERR_clear_last_mark(); 240 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF); 241 goto err; 242 } 243 (void)ERR_pop_to_mark(); 244 245 if (kdf->salt->type != V_ASN1_OCTET_STRING) { 246 ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE); 247 goto err; 248 } 249 250 /* it seems that its all OK */ 251 salt = kdf->salt->value.octet_string->data; 252 saltlen = kdf->salt->value.octet_string->length; 253 iter = ASN1_INTEGER_get(kdf->iter); 254 if (!ossl_pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, prfmd, 255 keylen, key, libctx, propq)) 256 goto err; 257 rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); 258 err: 259 OPENSSL_cleanse(key, keylen); 260 PBKDF2PARAM_free(kdf); 261 EVP_MD_free(prfmd_fetch); 262 return rv; 263 } 264 265 int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, 266 int passlen, ASN1_TYPE *param, 267 const EVP_CIPHER *c, const EVP_MD *md, int en_de) 268 { 269 return PKCS5_v2_PBKDF2_keyivgen_ex(ctx, pass, passlen, param, c, md, en_de, 270 NULL, NULL); 271 } 272