1 /* 2 * Copyright 1999-2021 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/asn1t.h> 13 #include <openssl/core.h> 14 #include <openssl/core_names.h> 15 #include <openssl/x509.h> 16 #include <openssl/rand.h> 17 18 /* PKCS#5 v2.0 password based encryption structures */ 19 20 ASN1_SEQUENCE(PBE2PARAM) = { 21 ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR), 22 ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR) 23 } ASN1_SEQUENCE_END(PBE2PARAM) 24 25 IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM) 26 27 ASN1_SEQUENCE(PBKDF2PARAM) = { 28 ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY), 29 ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER), 30 ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER), 31 ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR) 32 } ASN1_SEQUENCE_END(PBKDF2PARAM) 33 34 IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) 35 36 /* 37 * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know 38 * this is horrible! Extended version to allow application supplied PRF NID 39 * and IV. 40 */ 41 42 X509_ALGOR *PKCS5_pbe2_set_iv_ex(const EVP_CIPHER *cipher, int iter, 43 unsigned char *salt, int saltlen, 44 unsigned char *aiv, int prf_nid, 45 OSSL_LIB_CTX *libctx) 46 { 47 X509_ALGOR *scheme = NULL, *ret = NULL; 48 int alg_nid, keylen, ivlen; 49 EVP_CIPHER_CTX *ctx = NULL; 50 unsigned char iv[EVP_MAX_IV_LENGTH]; 51 PBE2PARAM *pbe2 = NULL; 52 53 alg_nid = EVP_CIPHER_get_type(cipher); 54 if (alg_nid == NID_undef) { 55 ERR_raise(ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); 56 goto err; 57 } 58 59 if ((pbe2 = PBE2PARAM_new()) == NULL) 60 goto merr; 61 62 /* Setup the AlgorithmIdentifier for the encryption scheme */ 63 scheme = pbe2->encryption; 64 scheme->algorithm = OBJ_nid2obj(alg_nid); 65 if ((scheme->parameter = ASN1_TYPE_new()) == NULL) 66 goto merr; 67 68 /* Create random IV */ 69 ivlen = EVP_CIPHER_get_iv_length(cipher); 70 if (ivlen > 0) { 71 if (aiv) 72 memcpy(iv, aiv, ivlen); 73 else if (RAND_bytes_ex(libctx, iv, ivlen, 0) <= 0) 74 goto err; 75 } 76 77 ctx = EVP_CIPHER_CTX_new(); 78 if (ctx == NULL) 79 goto merr; 80 81 /* Dummy cipherinit to just setup the IV, and PRF */ 82 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0)) 83 goto err; 84 if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) { 85 ERR_raise(ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); 86 goto err; 87 } 88 /* 89 * If prf NID unspecified see if cipher has a preference. An error is OK 90 * here: just means use default PRF. 91 */ 92 ERR_set_mark(); 93 if ((prf_nid == -1) && 94 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { 95 prf_nid = NID_hmacWithSHA256; 96 } 97 ERR_pop_to_mark(); 98 EVP_CIPHER_CTX_free(ctx); 99 ctx = NULL; 100 101 /* If its RC2 then we'd better setup the key length */ 102 103 if (alg_nid == NID_rc2_cbc) 104 keylen = EVP_CIPHER_get_key_length(cipher); 105 else 106 keylen = -1; 107 108 /* Setup keyfunc */ 109 110 X509_ALGOR_free(pbe2->keyfunc); 111 112 pbe2->keyfunc = PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen, 113 libctx); 114 115 if (pbe2->keyfunc == NULL) 116 goto merr; 117 118 /* Now set up top level AlgorithmIdentifier */ 119 120 if ((ret = X509_ALGOR_new()) == NULL) 121 goto merr; 122 123 ret->algorithm = OBJ_nid2obj(NID_pbes2); 124 125 /* Encode PBE2PARAM into parameter */ 126 127 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2, 128 &ret->parameter)) 129 goto merr; 130 131 PBE2PARAM_free(pbe2); 132 pbe2 = NULL; 133 134 return ret; 135 136 merr: 137 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 138 139 err: 140 EVP_CIPHER_CTX_free(ctx); 141 PBE2PARAM_free(pbe2); 142 /* Note 'scheme' is freed as part of pbe2 */ 143 X509_ALGOR_free(ret); 144 145 return NULL; 146 } 147 148 X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, 149 unsigned char *salt, int saltlen, 150 unsigned char *aiv, int prf_nid) 151 { 152 return PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, aiv, prf_nid, 153 NULL); 154 } 155 156 X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, 157 unsigned char *salt, int saltlen) 158 { 159 return PKCS5_pbe2_set_iv_ex(cipher, iter, salt, saltlen, NULL, -1, 160 NULL); 161 } 162 163 164 X509_ALGOR *PKCS5_pbkdf2_set_ex(int iter, unsigned char *salt, int saltlen, 165 int prf_nid, int keylen, 166 OSSL_LIB_CTX *libctx) 167 { 168 X509_ALGOR *keyfunc = NULL; 169 PBKDF2PARAM *kdf = NULL; 170 ASN1_OCTET_STRING *osalt = NULL; 171 172 if ((kdf = PBKDF2PARAM_new()) == NULL) 173 goto merr; 174 if ((osalt = ASN1_OCTET_STRING_new()) == NULL) 175 goto merr; 176 177 kdf->salt->value.octet_string = osalt; 178 kdf->salt->type = V_ASN1_OCTET_STRING; 179 180 if (saltlen < 0) 181 goto merr; 182 if (saltlen == 0) 183 saltlen = PKCS5_SALT_LEN; 184 if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL) 185 goto merr; 186 187 osalt->length = saltlen; 188 189 if (salt) 190 memcpy(osalt->data, salt, saltlen); 191 else if (RAND_bytes_ex(libctx, osalt->data, saltlen, 0) <= 0) 192 goto merr; 193 194 if (iter <= 0) 195 iter = PKCS5_DEFAULT_ITER; 196 197 if (!ASN1_INTEGER_set(kdf->iter, iter)) 198 goto merr; 199 200 /* If have a key len set it up */ 201 202 if (keylen > 0) { 203 if ((kdf->keylength = ASN1_INTEGER_new()) == NULL) 204 goto merr; 205 if (!ASN1_INTEGER_set(kdf->keylength, keylen)) 206 goto merr; 207 } 208 209 /* prf can stay NULL if we are using hmacWithSHA1 */ 210 if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { 211 kdf->prf = X509_ALGOR_new(); 212 if (kdf->prf == NULL) 213 goto merr; 214 X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); 215 } 216 217 /* Finally setup the keyfunc structure */ 218 219 keyfunc = X509_ALGOR_new(); 220 if (keyfunc == NULL) 221 goto merr; 222 223 keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); 224 225 /* Encode PBKDF2PARAM into parameter of pbe2 */ 226 227 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf, 228 &keyfunc->parameter)) 229 goto merr; 230 231 PBKDF2PARAM_free(kdf); 232 return keyfunc; 233 234 merr: 235 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 236 PBKDF2PARAM_free(kdf); 237 X509_ALGOR_free(keyfunc); 238 return NULL; 239 } 240 241 X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, 242 int prf_nid, int keylen) 243 { 244 return PKCS5_pbkdf2_set_ex(iter, salt, saltlen, prf_nid, keylen, NULL); 245 } 246 247