2 * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
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
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>
18 /* PKCS#5 v2.0 password based encryption structures */
20 ASN1_SEQUENCE(PBE2PARAM
) = {
21 ASN1_SIMPLE(PBE2PARAM
, keyfunc
, X509_ALGOR
),
22 ASN1_SIMPLE(PBE2PARAM
, encryption
, X509_ALGOR
)
23 } ASN1_SEQUENCE_END(PBE2PARAM
)
25 IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM
)
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
)
34 IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM
)
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
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
,
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
;
53 alg_nid
= EVP_CIPHER_type(cipher
);
54 if (alg_nid
== NID_undef
) {
55 ERR_raise(ERR_LIB_ASN1
, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
);
59 if ((pbe2
= PBE2PARAM_new()) == NULL
)
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
)
68 /* Create random IV */
69 ivlen
= EVP_CIPHER_iv_length(cipher
);
72 memcpy(iv
, aiv
, ivlen
);
73 else if (RAND_bytes_ex(libctx
, iv
, ivlen
, 0) <= 0)
77 ctx
= EVP_CIPHER_CTX_new();
81 /* Dummy cipherinit to just setup the IV, and PRF */
82 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, iv
, 0))
84 if (EVP_CIPHER_param_to_asn1(ctx
, scheme
->parameter
) <= 0) {
85 ERR_raise(ERR_LIB_ASN1
, ASN1_R_ERROR_SETTING_CIPHER_PARAMS
);
89 * If prf NID unspecified see if cipher has a preference. An error is OK
90 * here: just means use default PRF.
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
;
98 EVP_CIPHER_CTX_free(ctx
);
101 /* If its RC2 then we'd better setup the key length */
103 if (alg_nid
== NID_rc2_cbc
)
104 keylen
= EVP_CIPHER_key_length(cipher
);
110 X509_ALGOR_free(pbe2
->keyfunc
);
112 pbe2
->keyfunc
= PKCS5_pbkdf2_set_ex(iter
, salt
, saltlen
, prf_nid
, keylen
,
115 if (pbe2
->keyfunc
== NULL
)
118 /* Now set up top level AlgorithmIdentifier */
120 if ((ret
= X509_ALGOR_new()) == NULL
)
123 ret
->algorithm
= OBJ_nid2obj(NID_pbes2
);
125 /* Encode PBE2PARAM into parameter */
127 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM
), pbe2
,
131 PBE2PARAM_free(pbe2
);
137 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
140 EVP_CIPHER_CTX_free(ctx
);
141 PBE2PARAM_free(pbe2
);
142 /* Note 'scheme' is freed as part of pbe2 */
143 X509_ALGOR_free(ret
);
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
)
152 return PKCS5_pbe2_set_iv_ex(cipher
, iter
, salt
, saltlen
, aiv
, prf_nid
,
156 X509_ALGOR
*PKCS5_pbe2_set(const EVP_CIPHER
*cipher
, int iter
,
157 unsigned char *salt
, int saltlen
)
159 return PKCS5_pbe2_set_iv_ex(cipher
, iter
, salt
, saltlen
, NULL
, -1,
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
)
168 X509_ALGOR
*keyfunc
= NULL
;
169 PBKDF2PARAM
*kdf
= NULL
;
170 ASN1_OCTET_STRING
*osalt
= NULL
;
172 if ((kdf
= PBKDF2PARAM_new()) == NULL
)
174 if ((osalt
= ASN1_OCTET_STRING_new()) == NULL
)
177 kdf
->salt
->value
.octet_string
= osalt
;
178 kdf
->salt
->type
= V_ASN1_OCTET_STRING
;
183 saltlen
= PKCS5_SALT_LEN
;
184 if ((osalt
->data
= OPENSSL_malloc(saltlen
)) == NULL
)
187 osalt
->length
= saltlen
;
190 memcpy(osalt
->data
, salt
, saltlen
);
191 else if (RAND_bytes_ex(libctx
, osalt
->data
, saltlen
, 0) <= 0)
195 iter
= PKCS5_DEFAULT_ITER
;
197 if (!ASN1_INTEGER_set(kdf
->iter
, iter
))
200 /* If have a key len set it up */
203 if ((kdf
->keylength
= ASN1_INTEGER_new()) == NULL
)
205 if (!ASN1_INTEGER_set(kdf
->keylength
, keylen
))
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
)
214 X509_ALGOR_set0(kdf
->prf
, OBJ_nid2obj(prf_nid
), V_ASN1_NULL
, NULL
);
217 /* Finally setup the keyfunc structure */
219 keyfunc
= X509_ALGOR_new();
223 keyfunc
->algorithm
= OBJ_nid2obj(NID_id_pbkdf2
);
225 /* Encode PBKDF2PARAM into parameter of pbe2 */
227 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM
), kdf
,
228 &keyfunc
->parameter
))
231 PBKDF2PARAM_free(kdf
);
235 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
236 PBKDF2PARAM_free(kdf
);
237 X509_ALGOR_free(keyfunc
);
241 X509_ALGOR
*PKCS5_pbkdf2_set(int iter
, unsigned char *salt
, int saltlen
,
242 int prf_nid
, int keylen
)
244 return PKCS5_pbkdf2_set_ex(iter
, salt
, saltlen
, prf_nid
, keylen
, NULL
);