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