Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/asn1/p5_scrypt.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||||||||
2 | * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. | - | ||||||||||||
3 | * | - | ||||||||||||
4 | * Licensed under the OpenSSL license (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 <openssl/asn1t.h> | - | ||||||||||||
13 | #include <openssl/err.h> | - | ||||||||||||
14 | #include <openssl/evp.h> | - | ||||||||||||
15 | #include <openssl/x509.h> | - | ||||||||||||
16 | #include <openssl/rand.h> | - | ||||||||||||
17 | - | |||||||||||||
18 | #ifndef OPENSSL_NO_SCRYPT | - | ||||||||||||
19 | /* PKCS#5 scrypt password based encryption structures */ | - | ||||||||||||
20 | - | |||||||||||||
21 | ASN1_SEQUENCE(SCRYPT_PARAMS) = { | - | ||||||||||||
22 | ASN1_SIMPLE(SCRYPT_PARAMS, salt, ASN1_OCTET_STRING), | - | ||||||||||||
23 | ASN1_SIMPLE(SCRYPT_PARAMS, costParameter, ASN1_INTEGER), | - | ||||||||||||
24 | ASN1_SIMPLE(SCRYPT_PARAMS, blockSize, ASN1_INTEGER), | - | ||||||||||||
25 | ASN1_SIMPLE(SCRYPT_PARAMS, parallelizationParameter, ASN1_INTEGER), | - | ||||||||||||
26 | ASN1_OPT(SCRYPT_PARAMS, keyLength, ASN1_INTEGER), | - | ||||||||||||
27 | } ASN1_SEQUENCE_END(SCRYPT_PARAMS) | - | ||||||||||||
28 | - | |||||||||||||
29 | IMPLEMENT_ASN1_FUNCTIONS(SCRYPT_PARAMS) never executed: end of block never executed: return (SCRYPT_PARAMS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (&(SCRYPT_PARAMS_it))); never executed: return ASN1_item_i2d((ASN1_VALUE *)a, out, (&(SCRYPT_PARAMS_it))); never executed: return (SCRYPT_PARAMS *)ASN1_item_new((&(SCRYPT_PARAMS_it))); | 0 | ||||||||||||
30 | - | |||||||||||||
31 | static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, | - | ||||||||||||
32 | size_t keylen, uint64_t N, uint64_t r, | - | ||||||||||||
33 | uint64_t p); | - | ||||||||||||
34 | - | |||||||||||||
35 | /* | - | ||||||||||||
36 | * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm using scrypt | - | ||||||||||||
37 | */ | - | ||||||||||||
38 | - | |||||||||||||
39 | X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, | - | ||||||||||||
40 | const unsigned char *salt, int saltlen, | - | ||||||||||||
41 | unsigned char *aiv, uint64_t N, uint64_t r, | - | ||||||||||||
42 | uint64_t p) | - | ||||||||||||
43 | { | - | ||||||||||||
44 | X509_ALGOR *scheme = NULL, *ret = NULL; | - | ||||||||||||
45 | int alg_nid; | - | ||||||||||||
46 | size_t keylen = 0; | - | ||||||||||||
47 | EVP_CIPHER_CTX *ctx = NULL; | - | ||||||||||||
48 | unsigned char iv[EVP_MAX_IV_LENGTH]; | - | ||||||||||||
49 | PBE2PARAM *pbe2 = NULL; | - | ||||||||||||
50 | - | |||||||||||||
51 | if (!cipher) {
| 0 | ||||||||||||
52 | ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER); | - | ||||||||||||
53 | goto err; never executed: goto err; | 0 | ||||||||||||
54 | } | - | ||||||||||||
55 | - | |||||||||||||
56 | if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
| 0 | ||||||||||||
57 | ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, | - | ||||||||||||
58 | ASN1_R_INVALID_SCRYPT_PARAMETERS); | - | ||||||||||||
59 | goto err; never executed: goto err; | 0 | ||||||||||||
60 | } | - | ||||||||||||
61 | - | |||||||||||||
62 | alg_nid = EVP_CIPHER_type(cipher); | - | ||||||||||||
63 | if (alg_nid == NID_undef) {
| 0 | ||||||||||||
64 | ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, | - | ||||||||||||
65 | ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); | - | ||||||||||||
66 | goto err; never executed: goto err; | 0 | ||||||||||||
67 | } | - | ||||||||||||
68 | - | |||||||||||||
69 | pbe2 = PBE2PARAM_new(); | - | ||||||||||||
70 | if (pbe2 == NULL)
| 0 | ||||||||||||
71 | goto merr; never executed: goto merr; | 0 | ||||||||||||
72 | - | |||||||||||||
73 | /* Setup the AlgorithmIdentifier for the encryption scheme */ | - | ||||||||||||
74 | scheme = pbe2->encryption; | - | ||||||||||||
75 | - | |||||||||||||
76 | scheme->algorithm = OBJ_nid2obj(alg_nid); | - | ||||||||||||
77 | scheme->parameter = ASN1_TYPE_new(); | - | ||||||||||||
78 | if (scheme->parameter == NULL)
| 0 | ||||||||||||
79 | goto merr; never executed: goto merr; | 0 | ||||||||||||
80 | - | |||||||||||||
81 | /* Create random IV */ | - | ||||||||||||
82 | if (EVP_CIPHER_iv_length(cipher)) {
| 0 | ||||||||||||
83 | if (aiv)
| 0 | ||||||||||||
84 | memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); never executed: memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); | 0 | ||||||||||||
85 | else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
| 0 | ||||||||||||
86 | goto err; never executed: goto err; | 0 | ||||||||||||
87 | } never executed: end of block | 0 | ||||||||||||
88 | - | |||||||||||||
89 | ctx = EVP_CIPHER_CTX_new(); | - | ||||||||||||
90 | if (ctx == NULL)
| 0 | ||||||||||||
91 | goto merr; never executed: goto merr; | 0 | ||||||||||||
92 | - | |||||||||||||
93 | /* Dummy cipherinit to just setup the IV */ | - | ||||||||||||
94 | if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
| 0 | ||||||||||||
95 | goto err; never executed: goto err; | 0 | ||||||||||||
96 | if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) <= 0) {
| 0 | ||||||||||||
97 | ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, | - | ||||||||||||
98 | ASN1_R_ERROR_SETTING_CIPHER_PARAMS); | - | ||||||||||||
99 | goto err; never executed: goto err; | 0 | ||||||||||||
100 | } | - | ||||||||||||
101 | EVP_CIPHER_CTX_free(ctx); | - | ||||||||||||
102 | ctx = NULL; | - | ||||||||||||
103 | - | |||||||||||||
104 | /* If its RC2 then we'd better setup the key length */ | - | ||||||||||||
105 | - | |||||||||||||
106 | if (alg_nid == NID_rc2_cbc)
| 0 | ||||||||||||
107 | keylen = EVP_CIPHER_key_length(cipher); never executed: keylen = EVP_CIPHER_key_length(cipher); | 0 | ||||||||||||
108 | - | |||||||||||||
109 | /* Setup keyfunc */ | - | ||||||||||||
110 | - | |||||||||||||
111 | X509_ALGOR_free(pbe2->keyfunc); | - | ||||||||||||
112 | - | |||||||||||||
113 | pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p); | - | ||||||||||||
114 | - | |||||||||||||
115 | if (pbe2->keyfunc == NULL)
| 0 | ||||||||||||
116 | goto merr; never executed: goto merr; | 0 | ||||||||||||
117 | - | |||||||||||||
118 | /* Now set up top level AlgorithmIdentifier */ | - | ||||||||||||
119 | - | |||||||||||||
120 | ret = X509_ALGOR_new(); | - | ||||||||||||
121 | if (ret == NULL)
| 0 | ||||||||||||
122 | goto merr; never executed: goto merr; | 0 | ||||||||||||
123 | - | |||||||||||||
124 | ret->algorithm = OBJ_nid2obj(NID_pbes2); | - | ||||||||||||
125 | - | |||||||||||||
126 | /* Encode PBE2PARAM into parameter */ | - | ||||||||||||
127 | - | |||||||||||||
128 | if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
| 0 | ||||||||||||
129 | &ret->parameter) == NULL)
| 0 | ||||||||||||
130 | goto merr; never executed: goto merr; | 0 | ||||||||||||
131 | - | |||||||||||||
132 | PBE2PARAM_free(pbe2); | - | ||||||||||||
133 | pbe2 = NULL; | - | ||||||||||||
134 | - | |||||||||||||
135 | return ret; never executed: return ret; | 0 | ||||||||||||
136 | - | |||||||||||||
137 | merr: | - | ||||||||||||
138 | ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
139 | - | |||||||||||||
140 | err: code before this statement never executed: err: | 0 | ||||||||||||
141 | PBE2PARAM_free(pbe2); | - | ||||||||||||
142 | X509_ALGOR_free(ret); | - | ||||||||||||
143 | EVP_CIPHER_CTX_free(ctx); | - | ||||||||||||
144 | - | |||||||||||||
145 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
146 | } | - | ||||||||||||
147 | - | |||||||||||||
148 | static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen, | - | ||||||||||||
149 | size_t keylen, uint64_t N, uint64_t r, | - | ||||||||||||
150 | uint64_t p) | - | ||||||||||||
151 | { | - | ||||||||||||
152 | X509_ALGOR *keyfunc = NULL; | - | ||||||||||||
153 | SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new(); | - | ||||||||||||
154 | - | |||||||||||||
155 | if (sparam == NULL)
| 0 | ||||||||||||
156 | goto merr; never executed: goto merr; | 0 | ||||||||||||
157 | - | |||||||||||||
158 | if (!saltlen)
| 0 | ||||||||||||
159 | saltlen = PKCS5_SALT_LEN; never executed: saltlen = 8; | 0 | ||||||||||||
160 | - | |||||||||||||
161 | /* This will either copy salt or grow the buffer */ | - | ||||||||||||
162 | if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0)
| 0 | ||||||||||||
163 | goto merr; never executed: goto merr; | 0 | ||||||||||||
164 | - | |||||||||||||
165 | if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0)
| 0 | ||||||||||||
166 | goto err; never executed: goto err; | 0 | ||||||||||||
167 | - | |||||||||||||
168 | if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0)
| 0 | ||||||||||||
169 | goto merr; never executed: goto merr; | 0 | ||||||||||||
170 | - | |||||||||||||
171 | if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0)
| 0 | ||||||||||||
172 | goto merr; never executed: goto merr; | 0 | ||||||||||||
173 | - | |||||||||||||
174 | if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0)
| 0 | ||||||||||||
175 | goto merr; never executed: goto merr; | 0 | ||||||||||||
176 | - | |||||||||||||
177 | /* If have a key len set it up */ | - | ||||||||||||
178 | - | |||||||||||||
179 | if (keylen > 0) {
| 0 | ||||||||||||
180 | sparam->keyLength = ASN1_INTEGER_new(); | - | ||||||||||||
181 | if (sparam->keyLength == NULL)
| 0 | ||||||||||||
182 | goto merr; never executed: goto merr; | 0 | ||||||||||||
183 | if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0)
| 0 | ||||||||||||
184 | goto merr; never executed: goto merr; | 0 | ||||||||||||
185 | } never executed: end of block | 0 | ||||||||||||
186 | - | |||||||||||||
187 | /* Finally setup the keyfunc structure */ | - | ||||||||||||
188 | - | |||||||||||||
189 | keyfunc = X509_ALGOR_new(); | - | ||||||||||||
190 | if (keyfunc == NULL)
| 0 | ||||||||||||
191 | goto merr; never executed: goto merr; | 0 | ||||||||||||
192 | - | |||||||||||||
193 | keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt); | - | ||||||||||||
194 | - | |||||||||||||
195 | /* Encode SCRYPT_PARAMS into parameter of pbe2 */ | - | ||||||||||||
196 | - | |||||||||||||
197 | if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam,
| 0 | ||||||||||||
198 | &keyfunc->parameter) == NULL)
| 0 | ||||||||||||
199 | goto merr; never executed: goto merr; | 0 | ||||||||||||
200 | - | |||||||||||||
201 | SCRYPT_PARAMS_free(sparam); | - | ||||||||||||
202 | return keyfunc; never executed: return keyfunc; | 0 | ||||||||||||
203 | - | |||||||||||||
204 | merr: | - | ||||||||||||
205 | ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE); | - | ||||||||||||
206 | err: code before this statement never executed: err: | 0 | ||||||||||||
207 | SCRYPT_PARAMS_free(sparam); | - | ||||||||||||
208 | X509_ALGOR_free(keyfunc); | - | ||||||||||||
209 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
210 | } | - | ||||||||||||
211 | - | |||||||||||||
212 | int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, | - | ||||||||||||
213 | int passlen, ASN1_TYPE *param, | - | ||||||||||||
214 | const EVP_CIPHER *c, const EVP_MD *md, int en_de) | - | ||||||||||||
215 | { | - | ||||||||||||
216 | unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; | - | ||||||||||||
217 | uint64_t p, r, N; | - | ||||||||||||
218 | size_t saltlen; | - | ||||||||||||
219 | size_t keylen = 0; | - | ||||||||||||
220 | int rv = 0; | - | ||||||||||||
221 | SCRYPT_PARAMS *sparam = NULL; | - | ||||||||||||
222 | - | |||||||||||||
223 | if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
| 0 | ||||||||||||
224 | EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_NO_CIPHER_SET); | - | ||||||||||||
225 | goto err; never executed: goto err; | 0 | ||||||||||||
226 | } | - | ||||||||||||
227 | - | |||||||||||||
228 | /* Decode parameter */ | - | ||||||||||||
229 | - | |||||||||||||
230 | sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param); | - | ||||||||||||
231 | - | |||||||||||||
232 | if (sparam == NULL) {
| 0 | ||||||||||||
233 | EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_DECODE_ERROR); | - | ||||||||||||
234 | goto err; never executed: goto err; | 0 | ||||||||||||
235 | } | - | ||||||||||||
236 | - | |||||||||||||
237 | keylen = EVP_CIPHER_CTX_key_length(ctx); | - | ||||||||||||
238 | - | |||||||||||||
239 | /* Now check the parameters of sparam */ | - | ||||||||||||
240 | - | |||||||||||||
241 | if (sparam->keyLength) {
| 0 | ||||||||||||
242 | uint64_t spkeylen; | - | ||||||||||||
243 | if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0)
| 0 | ||||||||||||
244 | || (spkeylen != keylen)) {
| 0 | ||||||||||||
245 | EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, | - | ||||||||||||
246 | EVP_R_UNSUPPORTED_KEYLENGTH); | - | ||||||||||||
247 | goto err; never executed: goto err; | 0 | ||||||||||||
248 | } | - | ||||||||||||
249 | } never executed: end of block | 0 | ||||||||||||
250 | /* Check all parameters fit in uint64_t and are acceptable to scrypt */ | - | ||||||||||||
251 | if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0
| 0 | ||||||||||||
252 | || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0
| 0 | ||||||||||||
253 | || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0
| 0 | ||||||||||||
254 | || EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
| 0 | ||||||||||||
255 | EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, | - | ||||||||||||
256 | EVP_R_ILLEGAL_SCRYPT_PARAMETERS); | - | ||||||||||||
257 | goto err; never executed: goto err; | 0 | ||||||||||||
258 | } | - | ||||||||||||
259 | - | |||||||||||||
260 | /* it seems that its all OK */ | - | ||||||||||||
261 | - | |||||||||||||
262 | salt = sparam->salt->data; | - | ||||||||||||
263 | saltlen = sparam->salt->length; | - | ||||||||||||
264 | if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen)
| 0 | ||||||||||||
265 | == 0)
| 0 | ||||||||||||
266 | goto err; never executed: goto err; | 0 | ||||||||||||
267 | rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); | - | ||||||||||||
268 | err: code before this statement never executed: err: | 0 | ||||||||||||
269 | if (keylen)
| 0 | ||||||||||||
270 | OPENSSL_cleanse(key, keylen); never executed: OPENSSL_cleanse(key, keylen); | 0 | ||||||||||||
271 | SCRYPT_PARAMS_free(sparam); | - | ||||||||||||
272 | return rv; never executed: return rv; | 0 | ||||||||||||
273 | } | - | ||||||||||||
274 | #endif /* OPENSSL_NO_SCRYPT */ | - | ||||||||||||
Source code | Switch to Preprocessed file |