2 * Copyright 1999-2018 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/x509.h>
14 #include <openssl/rand.h>
16 /* PKCS#5 v2.0 password based encryption structures */
18 ASN1_SEQUENCE(PBE2PARAM
) = {
19 ASN1_SIMPLE(PBE2PARAM
, keyfunc
, X509_ALGOR
),
20 ASN1_SIMPLE(PBE2PARAM
, encryption
, X509_ALGOR
)
21 } ASN1_SEQUENCE_END(PBE2PARAM
)
23 IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM
)
25 ASN1_SEQUENCE(PBKDF2PARAM
) = {
26 ASN1_SIMPLE(PBKDF2PARAM
, salt
, ASN1_ANY
),
27 ASN1_SIMPLE(PBKDF2PARAM
, iter
, ASN1_INTEGER
),
28 ASN1_OPT(PBKDF2PARAM
, keylength
, ASN1_INTEGER
),
29 ASN1_OPT(PBKDF2PARAM
, prf
, X509_ALGOR
)
30 } ASN1_SEQUENCE_END(PBKDF2PARAM
)
32 IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM
)
35 * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
36 * this is horrible! Extended version to allow application supplied PRF NID
40 X509_ALGOR
*PKCS5_pbe2_set_iv(const EVP_CIPHER
*cipher
, int iter
,
41 unsigned char *salt
, int saltlen
,
42 unsigned char *aiv
, int prf_nid
)
44 X509_ALGOR
*scheme
= NULL
, *ret
= NULL
;
46 EVP_CIPHER_CTX
*ctx
= NULL
;
47 unsigned char iv
[EVP_MAX_IV_LENGTH
];
48 PBE2PARAM
*pbe2
= NULL
;
50 alg_nid
= EVP_CIPHER_type(cipher
);
51 if (alg_nid
== NID_undef
) {
52 ASN1err(ASN1_F_PKCS5_PBE2_SET_IV
,
53 ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
);
57 if ((pbe2
= PBE2PARAM_new()) == NULL
)
60 /* Setup the AlgorithmIdentifier for the encryption scheme */
61 scheme
= pbe2
->encryption
;
62 scheme
->algorithm
= OBJ_nid2obj(alg_nid
);
63 if ((scheme
->parameter
= ASN1_TYPE_new()) == NULL
)
66 /* Create random IV */
67 if (EVP_CIPHER_iv_length(cipher
)) {
69 memcpy(iv
, aiv
, EVP_CIPHER_iv_length(cipher
));
70 else if (RAND_bytes(iv
, EVP_CIPHER_iv_length(cipher
)) <= 0)
74 ctx
= EVP_CIPHER_CTX_new();
78 /* Dummy cipherinit to just setup the IV, and PRF */
79 if (!EVP_CipherInit_ex(ctx
, cipher
, NULL
, NULL
, iv
, 0))
81 if (EVP_CIPHER_param_to_asn1(ctx
, scheme
->parameter
) <= 0) {
82 ASN1err(ASN1_F_PKCS5_PBE2_SET_IV
, ASN1_R_ERROR_SETTING_CIPHER_PARAMS
);
86 * If prf NID unspecified see if cipher has a preference. An error is OK
87 * here: just means use default PRF.
89 if ((prf_nid
== -1) &&
90 EVP_CIPHER_CTX_ctrl(ctx
, EVP_CTRL_PBE_PRF_NID
, 0, &prf_nid
) <= 0) {
92 prf_nid
= NID_hmacWithSHA256
;
94 EVP_CIPHER_CTX_free(ctx
);
97 /* If its RC2 then we'd better setup the key length */
99 if (alg_nid
== NID_rc2_cbc
)
100 keylen
= EVP_CIPHER_key_length(cipher
);
106 X509_ALGOR_free(pbe2
->keyfunc
);
108 pbe2
->keyfunc
= PKCS5_pbkdf2_set(iter
, salt
, saltlen
, prf_nid
, keylen
);
110 if (pbe2
->keyfunc
== NULL
)
113 /* Now set up top level AlgorithmIdentifier */
115 if ((ret
= X509_ALGOR_new()) == NULL
)
118 ret
->algorithm
= OBJ_nid2obj(NID_pbes2
);
120 /* Encode PBE2PARAM into parameter */
122 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM
), pbe2
,
126 PBE2PARAM_free(pbe2
);
132 ASN1err(ASN1_F_PKCS5_PBE2_SET_IV
, ERR_R_MALLOC_FAILURE
);
135 EVP_CIPHER_CTX_free(ctx
);
136 PBE2PARAM_free(pbe2
);
137 /* Note 'scheme' is freed as part of pbe2 */
138 X509_ALGOR_free(ret
);
143 X509_ALGOR
*PKCS5_pbe2_set(const EVP_CIPHER
*cipher
, int iter
,
144 unsigned char *salt
, int saltlen
)
146 return PKCS5_pbe2_set_iv(cipher
, iter
, salt
, saltlen
, NULL
, -1);
149 X509_ALGOR
*PKCS5_pbkdf2_set(int iter
, unsigned char *salt
, int saltlen
,
150 int prf_nid
, int keylen
)
152 X509_ALGOR
*keyfunc
= NULL
;
153 PBKDF2PARAM
*kdf
= NULL
;
154 ASN1_OCTET_STRING
*osalt
= NULL
;
156 if ((kdf
= PBKDF2PARAM_new()) == NULL
)
158 if ((osalt
= ASN1_OCTET_STRING_new()) == NULL
)
161 kdf
->salt
->value
.octet_string
= osalt
;
162 kdf
->salt
->type
= V_ASN1_OCTET_STRING
;
165 saltlen
= PKCS5_SALT_LEN
;
166 if ((osalt
->data
= OPENSSL_malloc(saltlen
)) == NULL
)
169 osalt
->length
= saltlen
;
172 memcpy(osalt
->data
, salt
, saltlen
);
173 else if (RAND_bytes(osalt
->data
, saltlen
) <= 0)
177 iter
= PKCS5_DEFAULT_ITER
;
179 if (!ASN1_INTEGER_set(kdf
->iter
, iter
))
182 /* If have a key len set it up */
185 if ((kdf
->keylength
= ASN1_INTEGER_new()) == NULL
)
187 if (!ASN1_INTEGER_set(kdf
->keylength
, keylen
))
191 /* prf can stay NULL if we are using hmacWithSHA1 */
192 if (prf_nid
> 0 && prf_nid
!= NID_hmacWithSHA1
) {
193 kdf
->prf
= X509_ALGOR_new();
194 if (kdf
->prf
== NULL
)
196 X509_ALGOR_set0(kdf
->prf
, OBJ_nid2obj(prf_nid
), V_ASN1_NULL
, NULL
);
199 /* Finally setup the keyfunc structure */
201 keyfunc
= X509_ALGOR_new();
205 keyfunc
->algorithm
= OBJ_nid2obj(NID_id_pbkdf2
);
207 /* Encode PBKDF2PARAM into parameter of pbe2 */
209 if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM
), kdf
,
210 &keyfunc
->parameter
))
213 PBKDF2PARAM_free(kdf
);
217 ASN1err(ASN1_F_PKCS5_PBKDF2_SET
, ERR_R_MALLOC_FAILURE
);
218 PBKDF2PARAM_free(kdf
);
219 X509_ALGOR_free(keyfunc
);