2 * Copyright 1999-2022 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 "crypto/asn1.h"
13 #include <openssl/asn1t.h>
14 #include <openssl/core.h>
15 #include <openssl/core_names.h>
16 #include <openssl/x509.h>
17 #include <openssl/rand.h>
19 /* PKCS#5 v2.0 password based encryption structures */
21 ASN1_SEQUENCE(PBE2PARAM
) = {
22 ASN1_SIMPLE(PBE2PARAM
, keyfunc
, X509_ALGOR
),
23 ASN1_SIMPLE(PBE2PARAM
, encryption
, X509_ALGOR
)
24 } ASN1_SEQUENCE_END(PBE2PARAM
)
26 IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM
)
28 ASN1_SEQUENCE(PBKDF2PARAM
) = {
29 ASN1_SIMPLE(PBKDF2PARAM
, salt
, ASN1_ANY
),
30 ASN1_SIMPLE(PBKDF2PARAM
, iter
, ASN1_INTEGER
),
31 ASN1_OPT(PBKDF2PARAM
, keylength
, ASN1_INTEGER
),
32 ASN1_OPT(PBKDF2PARAM
, prf
, X509_ALGOR
)
33 } ASN1_SEQUENCE_END(PBKDF2PARAM
)
35 IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM
)
38 * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
39 * this is horrible! Extended version to allow application supplied PRF NID
43 X509_ALGOR
*PKCS5_pbe2_set_iv_ex(const EVP_CIPHER
*cipher
, int iter
,
44 unsigned char *salt
, int saltlen
,
45 unsigned char *aiv
, int prf_nid
,
48 X509_ALGOR
*scheme
= NULL
, *ret
= NULL
;
49 int alg_nid
, keylen
, ivlen
;
50 EVP_CIPHER_CTX
*ctx
= NULL
;
51 unsigned char iv
[EVP_MAX_IV_LENGTH
];
52 PBE2PARAM
*pbe2
= NULL
;
54 alg_nid
= EVP_CIPHER_get_type(cipher
);
55 if (alg_nid
== NID_undef
) {
56 ERR_raise(ERR_LIB_ASN1
, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
);
60 if ((pbe2
= PBE2PARAM_new()) == NULL
) {
61 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
65 /* Setup the AlgorithmIdentifier for the encryption scheme */
66 scheme
= pbe2
->encryption
;
67 scheme
->algorithm
= OBJ_nid2obj(alg_nid
);
68 if ((scheme
->parameter
= ASN1_TYPE_new()) == NULL
) {
69 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
73 /* Create random IV */
74 ivlen
= EVP_CIPHER_get_iv_length(cipher
);
77 memcpy(iv
, aiv
, ivlen
);
78 else if (RAND_bytes_ex(libctx
, iv
, ivlen
, 0) <= 0)
82 ctx
= EVP_CIPHER_CTX_new();
84 ERR_raise(ERR_LIB_ASN1
, ERR_R_EVP_LIB
);
88 /* Dummy cipherinit to just setup the IV, and PRF */
89 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, iv
, 0))
91 if (EVP_CIPHER_param_to_asn1(ctx
, scheme
->parameter
) <= 0) {
92 ERR_raise(ERR_LIB_ASN1
, ASN1_R_ERROR_SETTING_CIPHER_PARAMS
);
96 * If prf NID unspecified see if cipher has a preference. An error is OK
97 * here: just means use default PRF.
100 if ((prf_nid
== -1) &&
101 EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_PBE_PRF_NID
, 0, &prf_nid
) <= 0) {
102 prf_nid
= NID_hmacWithSHA256
;
105 EVP_CIPHER_CTX_free(ctx
);
108 /* If its RC2 then we'd better setup the key length */
110 if (alg_nid
== NID_rc2_cbc
)
111 keylen
= EVP_CIPHER_get_key_length(cipher
);
117 X509_ALGOR_free(pbe2
->keyfunc
);
119 pbe2
->keyfunc
= PKCS5_pbkdf2_set_ex(iter
, salt
, saltlen
, prf_nid
, keylen
,
122 if (pbe2
->keyfunc
== NULL
) {
123 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
127 /* Now set up top level AlgorithmIdentifier */
129 if ((ret
= X509_ALGOR_new()) == NULL
) {
130 ERR_raise(ERR_LIB_ASN1
, ERR_R_X509_LIB
);
134 ret
->algorithm
= OBJ_nid2obj(NID_pbes2
);
136 /* Encode PBE2PARAM into parameter */
138 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM
), pbe2
,
140 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
144 PBE2PARAM_free(pbe2
);
150 EVP_CIPHER_CTX_free(ctx
);
151 PBE2PARAM_free(pbe2
);
152 /* Note 'scheme' is freed as part of pbe2 */
153 X509_ALGOR_free(ret
);
158 X509_ALGOR
*PKCS5_pbe2_set_iv(const EVP_CIPHER
*cipher
, int iter
,
159 unsigned char *salt
, int saltlen
,
160 unsigned char *aiv
, int prf_nid
)
162 return PKCS5_pbe2_set_iv_ex(cipher
, iter
, salt
, saltlen
, aiv
, prf_nid
,
166 X509_ALGOR
*PKCS5_pbe2_set(const EVP_CIPHER
*cipher
, int iter
,
167 unsigned char *salt
, int saltlen
)
169 return PKCS5_pbe2_set_iv_ex(cipher
, iter
, salt
, saltlen
, NULL
, -1,
174 X509_ALGOR
*PKCS5_pbkdf2_set_ex(int iter
, unsigned char *salt
, int saltlen
,
175 int prf_nid
, int keylen
,
176 OSSL_LIB_CTX
*libctx
)
178 X509_ALGOR
*keyfunc
= NULL
;
179 PBKDF2PARAM
*kdf
= NULL
;
180 ASN1_OCTET_STRING
*osalt
= NULL
;
182 if ((kdf
= PBKDF2PARAM_new()) == NULL
) {
183 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
186 if ((osalt
= ASN1_OCTET_STRING_new()) == NULL
) {
187 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
191 kdf
->salt
->value
.octet_string
= osalt
;
192 kdf
->salt
->type
= V_ASN1_OCTET_STRING
;
195 ERR_raise(ERR_LIB_ASN1
, ERR_R_PASSED_INVALID_ARGUMENT
);
199 saltlen
= PKCS5_SALT_LEN
;
200 if ((osalt
->data
= OPENSSL_malloc(saltlen
)) == NULL
)
204 osalt
->length
= saltlen
;
207 memcpy(osalt
->data
, salt
, saltlen
);
208 } else if (RAND_bytes_ex(libctx
, osalt
->data
, saltlen
, 0) <= 0) {
209 ERR_raise(ERR_LIB_ASN1
, ERR_R_RAND_LIB
);
214 iter
= PKCS5_DEFAULT_ITER
;
216 if (!ASN1_INTEGER_set(kdf
->iter
, iter
)) {
217 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
221 /* If have a key len set it up */
224 if ((kdf
->keylength
= ASN1_INTEGER_new()) == NULL
) {
225 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
228 if (!ASN1_INTEGER_set(kdf
->keylength
, keylen
)) {
229 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
234 /* prf can stay NULL if we are using hmacWithSHA1 */
235 if (prf_nid
> 0 && prf_nid
!= NID_hmacWithSHA1
) {
236 kdf
->prf
= ossl_X509_ALGOR_from_nid(prf_nid
, V_ASN1_NULL
, NULL
);
237 if (kdf
->prf
== NULL
) {
238 ERR_raise(ERR_LIB_ASN1
, ERR_R_X509_LIB
);
243 /* Finally setup the keyfunc structure */
245 keyfunc
= X509_ALGOR_new();
246 if (keyfunc
== NULL
) {
247 ERR_raise(ERR_LIB_ASN1
, ERR_R_X509_LIB
);
251 keyfunc
->algorithm
= OBJ_nid2obj(NID_id_pbkdf2
);
253 /* Encode PBKDF2PARAM into parameter of pbe2 */
255 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM
), kdf
,
256 &keyfunc
->parameter
)) {
257 ERR_raise(ERR_LIB_ASN1
, ERR_R_ASN1_LIB
);
261 PBKDF2PARAM_free(kdf
);
265 PBKDF2PARAM_free(kdf
);
266 X509_ALGOR_free(keyfunc
);
270 X509_ALGOR
*PKCS5_pbkdf2_set(int iter
, unsigned char *salt
, int saltlen
,
271 int prf_nid
, int keylen
)
273 return PKCS5_pbkdf2_set_ex(iter
, salt
, saltlen
, prf_nid
, keylen
, NULL
);