]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
38fc02a7 | 2 | * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved. |
ef8335d9 | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
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 | |
ef8335d9 DSH |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
11 | #include <stdlib.h> | |
b39fc560 | 12 | #include "internal/cryptlib.h" |
ef8335d9 DSH |
13 | #include <openssl/x509.h> |
14 | #include <openssl/evp.h> | |
0f183675 JS |
15 | #include <openssl/core_names.h> |
16 | #include <openssl/kdf.h> | |
17 | ||
0f113f3e MC |
18 | /* |
19 | * Doesn't do anything now: Builtin PBE algorithms in static table. | |
ef8335d9 DSH |
20 | */ |
21 | ||
22 | void PKCS5_PBE_add(void) | |
23 | { | |
ef8335d9 DSH |
24 | } |
25 | ||
8bb6fdfc JS |
26 | int PKCS5_PBE_keyivgen_ex(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, |
27 | ASN1_TYPE *param, const EVP_CIPHER *cipher, | |
28 | const EVP_MD *md, int en_de, OSSL_LIB_CTX *libctx, | |
29 | const char *propq) | |
ef8335d9 | 30 | { |
8bb6fdfc JS |
31 | unsigned char md_tmp[EVP_MAX_MD_SIZE]; |
32 | unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; | |
0f183675 JS |
33 | int ivl, kl; |
34 | PBEPARAM *pbe = NULL; | |
0f113f3e MC |
35 | int saltlen, iter; |
36 | unsigned char *salt; | |
8bb6fdfc | 37 | int mdsize; |
0f113f3e | 38 | int rv = 0; |
0f183675 JS |
39 | EVP_KDF *kdf; |
40 | EVP_KDF_CTX *kctx = NULL; | |
41 | OSSL_PARAM params[5], *p = params; | |
42 | const char *mdname = EVP_MD_name(md); | |
69cbf468 | 43 | |
0f113f3e MC |
44 | /* Extract useful info from parameter */ |
45 | if (param == NULL || param->type != V_ASN1_SEQUENCE || | |
46 | param->value.sequence == NULL) { | |
9311d0c4 | 47 | ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); |
0f113f3e MC |
48 | return 0; |
49 | } | |
c755c5fd | 50 | |
e93c8748 DSH |
51 | pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param); |
52 | if (pbe == NULL) { | |
9311d0c4 | 53 | ERR_raise(ERR_LIB_EVP, EVP_R_DECODE_ERROR); |
0f113f3e MC |
54 | return 0; |
55 | } | |
69cbf468 | 56 | |
ed576acd | 57 | ivl = EVP_CIPHER_get_iv_length(cipher); |
8bb6fdfc | 58 | if (ivl < 0 || ivl > 16) { |
9311d0c4 | 59 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH); |
0f183675 | 60 | goto err; |
a05bf83c | 61 | } |
ed576acd | 62 | kl = EVP_CIPHER_get_key_length(cipher); |
8bb6fdfc | 63 | if (kl < 0 || kl > (int)sizeof(md_tmp)) { |
9311d0c4 | 64 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH); |
0f183675 | 65 | goto err; |
a05bf83c P |
66 | } |
67 | ||
12a765a5 | 68 | if (pbe->iter == NULL) |
0f113f3e MC |
69 | iter = 1; |
70 | else | |
71 | iter = ASN1_INTEGER_get(pbe->iter); | |
72 | salt = pbe->salt->data; | |
73 | saltlen = pbe->salt->length; | |
69cbf468 | 74 | |
12a765a5 | 75 | if (pass == NULL) |
0f113f3e MC |
76 | passlen = 0; |
77 | else if (passlen == -1) | |
78 | passlen = strlen(pass); | |
a331a305 | 79 | |
ed576acd | 80 | mdsize = EVP_MD_get_size(md); |
8bb6fdfc JS |
81 | if (mdsize < 0) |
82 | goto err; | |
83 | ||
84 | kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF1, propq); | |
0f183675 JS |
85 | kctx = EVP_KDF_CTX_new(kdf); |
86 | EVP_KDF_free(kdf); | |
87 | if (kctx == NULL) | |
0f113f3e | 88 | goto err; |
0f183675 JS |
89 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, |
90 | (char *)pass, (size_t)passlen); | |
91 | *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, | |
92 | salt, saltlen); | |
93 | *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); | |
94 | *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, | |
95 | (char *)mdname, 0); | |
96 | *p = OSSL_PARAM_construct_end(); | |
8bb6fdfc | 97 | if (EVP_KDF_derive(kctx, md_tmp, mdsize, params) != 1) |
0f113f3e | 98 | goto err; |
8bb6fdfc JS |
99 | memcpy(key, md_tmp, kl); |
100 | memcpy(iv, md_tmp + (16 - ivl), ivl); | |
101 | if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) | |
0f113f3e | 102 | goto err; |
8bb6fdfc JS |
103 | OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); |
104 | OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); | |
105 | OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); | |
0f113f3e MC |
106 | rv = 1; |
107 | err: | |
0f183675 | 108 | EVP_KDF_CTX_free(kctx); |
adc9086b | 109 | PBEPARAM_free(pbe); |
0f113f3e | 110 | return rv; |
ef8335d9 | 111 | } |
8bb6fdfc JS |
112 | |
113 | int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, | |
114 | ASN1_TYPE *param, const EVP_CIPHER *cipher, | |
115 | const EVP_MD *md, int en_de) | |
116 | { | |
117 | return PKCS5_PBE_keyivgen_ex(cctx, pass, passlen, param, cipher, md, en_de, | |
118 | NULL, NULL); | |
119 | } | |
120 |