Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssl/src/crypto/evp/p5_crpt2.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||||||||
2 | * Copyright 1999-2016 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 <stdlib.h> | - | ||||||||||||
12 | #include "internal/cryptlib.h" | - | ||||||||||||
13 | # include <openssl/x509.h> | - | ||||||||||||
14 | # include <openssl/evp.h> | - | ||||||||||||
15 | # include <openssl/hmac.h> | - | ||||||||||||
16 | # include "evp_locl.h" | - | ||||||||||||
17 | - | |||||||||||||
18 | /* set this to print out info about the keygen algorithm */ | - | ||||||||||||
19 | /* #define OPENSSL_DEBUG_PKCS5V2 */ | - | ||||||||||||
20 | - | |||||||||||||
21 | # ifdef OPENSSL_DEBUG_PKCS5V2 | - | ||||||||||||
22 | static void h__dump(const unsigned char *p, int len); | - | ||||||||||||
23 | # endif | - | ||||||||||||
24 | - | |||||||||||||
25 | /* | - | ||||||||||||
26 | * This is an implementation of PKCS#5 v2.0 password based encryption key | - | ||||||||||||
27 | * derivation function PBKDF2. SHA1 version verified against test vectors | - | ||||||||||||
28 | * posted by Peter Gutmann to the PKCS-TNG mailing list. | - | ||||||||||||
29 | */ | - | ||||||||||||
30 | - | |||||||||||||
31 | int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, | - | ||||||||||||
32 | const unsigned char *salt, int saltlen, int iter, | - | ||||||||||||
33 | const EVP_MD *digest, int keylen, unsigned char *out) | - | ||||||||||||
34 | { | - | ||||||||||||
35 | const char *empty = ""; | - | ||||||||||||
36 | unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; | - | ||||||||||||
37 | int cplen, j, k, tkeylen, mdlen; | - | ||||||||||||
38 | unsigned long i = 1; | - | ||||||||||||
39 | HMAC_CTX *hctx_tpl = NULL, *hctx = NULL; | - | ||||||||||||
40 | - | |||||||||||||
41 | mdlen = EVP_MD_size(digest); | - | ||||||||||||
42 | if (mdlen < 0)
| 0-39 | ||||||||||||
43 | return 0; never executed: return 0; | 0 | ||||||||||||
44 | - | |||||||||||||
45 | hctx_tpl = HMAC_CTX_new(); | - | ||||||||||||
46 | if (hctx_tpl == NULL)
| 0-39 | ||||||||||||
47 | return 0; never executed: return 0; | 0 | ||||||||||||
48 | p = out; | - | ||||||||||||
49 | tkeylen = keylen; | - | ||||||||||||
50 | if (pass == NULL) {
| 3-36 | ||||||||||||
51 | pass = empty; | - | ||||||||||||
52 | passlen = 0; | - | ||||||||||||
53 | } else if (passlen == -1) { executed 3 times by 1 test: end of block Executed by:
| 0-36 | ||||||||||||
54 | passlen = strlen(pass); | - | ||||||||||||
55 | } never executed: end of block | 0 | ||||||||||||
56 | if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
| 0-39 | ||||||||||||
57 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
58 | return 0; never executed: return 0; | 0 | ||||||||||||
59 | } | - | ||||||||||||
60 | hctx = HMAC_CTX_new(); | - | ||||||||||||
61 | if (hctx == NULL) {
| 0-39 | ||||||||||||
62 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
63 | return 0; never executed: return 0; | 0 | ||||||||||||
64 | } | - | ||||||||||||
65 | while (tkeylen) {
| 39-2673 | ||||||||||||
66 | if (tkeylen > mdlen)
| 39-2634 | ||||||||||||
67 | cplen = mdlen; executed 2634 times by 1 test: cplen = mdlen; Executed by:
| 2634 | ||||||||||||
68 | else | - | ||||||||||||
69 | cplen = tkeylen; executed 39 times by 1 test: cplen = tkeylen; Executed by:
| 39 | ||||||||||||
70 | /* | - | ||||||||||||
71 | * We are unlikely to ever use more than 256 blocks (5120 bits!) but | - | ||||||||||||
72 | * just in case... | - | ||||||||||||
73 | */ | - | ||||||||||||
74 | itmp[0] = (unsigned char)((i >> 24) & 0xff); | - | ||||||||||||
75 | itmp[1] = (unsigned char)((i >> 16) & 0xff); | - | ||||||||||||
76 | itmp[2] = (unsigned char)((i >> 8) & 0xff); | - | ||||||||||||
77 | itmp[3] = (unsigned char)(i & 0xff); | - | ||||||||||||
78 | if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
| 0-2673 | ||||||||||||
79 | HMAC_CTX_free(hctx); | - | ||||||||||||
80 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
81 | return 0; never executed: return 0; | 0 | ||||||||||||
82 | } | - | ||||||||||||
83 | if (!HMAC_Update(hctx, salt, saltlen)
| 0-2673 | ||||||||||||
84 | || !HMAC_Update(hctx, itmp, 4)
| 0-2673 | ||||||||||||
85 | || !HMAC_Final(hctx, digtmp, NULL)) {
| 0-2673 | ||||||||||||
86 | HMAC_CTX_free(hctx); | - | ||||||||||||
87 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
88 | return 0; never executed: return 0; | 0 | ||||||||||||
89 | } | - | ||||||||||||
90 | memcpy(p, digtmp, cplen); | - | ||||||||||||
91 | for (j = 1; j < iter; j++) {
| 2673-45048 | ||||||||||||
92 | if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
| 0-45048 | ||||||||||||
93 | HMAC_CTX_free(hctx); | - | ||||||||||||
94 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
95 | return 0; never executed: return 0; | 0 | ||||||||||||
96 | } | - | ||||||||||||
97 | if (!HMAC_Update(hctx, digtmp, mdlen)
| 0-45048 | ||||||||||||
98 | || !HMAC_Final(hctx, digtmp, NULL)) {
| 0-45048 | ||||||||||||
99 | HMAC_CTX_free(hctx); | - | ||||||||||||
100 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
101 | return 0; never executed: return 0; | 0 | ||||||||||||
102 | } | - | ||||||||||||
103 | for (k = 0; k < cplen; k++)
| 45048-1199951 | ||||||||||||
104 | p[k] ^= digtmp[k]; executed 1199951 times by 1 test: p[k] ^= digtmp[k]; Executed by:
| 1199951 | ||||||||||||
105 | } executed 45048 times by 1 test: end of block Executed by:
| 45048 | ||||||||||||
106 | tkeylen -= cplen; | - | ||||||||||||
107 | i++; | - | ||||||||||||
108 | p += cplen; | - | ||||||||||||
109 | } executed 2673 times by 1 test: end of block Executed by:
| 2673 | ||||||||||||
110 | HMAC_CTX_free(hctx); | - | ||||||||||||
111 | HMAC_CTX_free(hctx_tpl); | - | ||||||||||||
112 | # ifdef OPENSSL_DEBUG_PKCS5V2 | - | ||||||||||||
113 | fprintf(stderr, "Password:\n"); | - | ||||||||||||
114 | h__dump(pass, passlen); | - | ||||||||||||
115 | fprintf(stderr, "Salt:\n"); | - | ||||||||||||
116 | h__dump(salt, saltlen); | - | ||||||||||||
117 | fprintf(stderr, "Iteration count %d\n", iter); | - | ||||||||||||
118 | fprintf(stderr, "Key:\n"); | - | ||||||||||||
119 | h__dump(out, keylen); | - | ||||||||||||
120 | # endif | - | ||||||||||||
121 | return 1; executed 39 times by 1 test: return 1; Executed by:
| 39 | ||||||||||||
122 | } | - | ||||||||||||
123 | - | |||||||||||||
124 | int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, | - | ||||||||||||
125 | const unsigned char *salt, int saltlen, int iter, | - | ||||||||||||
126 | int keylen, unsigned char *out) | - | ||||||||||||
127 | { | - | ||||||||||||
128 | return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), never executed: return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), keylen, out); | 0 | ||||||||||||
129 | keylen, out); never executed: return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), keylen, out); | 0 | ||||||||||||
130 | } | - | ||||||||||||
131 | - | |||||||||||||
132 | /* | - | ||||||||||||
133 | * Now the key derivation function itself. This is a bit evil because it has | - | ||||||||||||
134 | * to check the ASN1 parameters are valid: and there are quite a few of | - | ||||||||||||
135 | * them... | - | ||||||||||||
136 | */ | - | ||||||||||||
137 | - | |||||||||||||
138 | int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, | - | ||||||||||||
139 | ASN1_TYPE *param, const EVP_CIPHER *c, | - | ||||||||||||
140 | const EVP_MD *md, int en_de) | - | ||||||||||||
141 | { | - | ||||||||||||
142 | PBE2PARAM *pbe2 = NULL; | - | ||||||||||||
143 | const EVP_CIPHER *cipher; | - | ||||||||||||
144 | EVP_PBE_KEYGEN *kdf; | - | ||||||||||||
145 | - | |||||||||||||
146 | int rv = 0; | - | ||||||||||||
147 | - | |||||||||||||
148 | pbe2 = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBE2PARAM), param); | - | ||||||||||||
149 | if (pbe2 == NULL) {
| 0 | ||||||||||||
150 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); | - | ||||||||||||
151 | goto err; never executed: goto err; | 0 | ||||||||||||
152 | } | - | ||||||||||||
153 | - | |||||||||||||
154 | /* See if we recognise the key derivation function */ | - | ||||||||||||
155 | if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
| 0 | ||||||||||||
156 | NULL, NULL, &kdf)) {
| 0 | ||||||||||||
157 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | - | ||||||||||||
158 | EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); | - | ||||||||||||
159 | goto err; never executed: goto err; | 0 | ||||||||||||
160 | } | - | ||||||||||||
161 | - | |||||||||||||
162 | /* | - | ||||||||||||
163 | * lets see if we recognise the encryption algorithm. | - | ||||||||||||
164 | */ | - | ||||||||||||
165 | - | |||||||||||||
166 | cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); | - | ||||||||||||
167 | - | |||||||||||||
168 | if (!cipher) {
| 0 | ||||||||||||
169 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER); | - | ||||||||||||
170 | goto err; never executed: goto err; | 0 | ||||||||||||
171 | } | - | ||||||||||||
172 | - | |||||||||||||
173 | /* Fixup cipher based on AlgorithmIdentifier */ | - | ||||||||||||
174 | if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
| 0 | ||||||||||||
175 | goto err; never executed: goto err; | 0 | ||||||||||||
176 | if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
| 0 | ||||||||||||
177 | EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR); | - | ||||||||||||
178 | goto err; never executed: goto err; | 0 | ||||||||||||
179 | } | - | ||||||||||||
180 | rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de); | - | ||||||||||||
181 | err: code before this statement never executed: err: | 0 | ||||||||||||
182 | PBE2PARAM_free(pbe2); | - | ||||||||||||
183 | return rv; never executed: return rv; | 0 | ||||||||||||
184 | } | - | ||||||||||||
185 | - | |||||||||||||
186 | int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, | - | ||||||||||||
187 | int passlen, ASN1_TYPE *param, | - | ||||||||||||
188 | const EVP_CIPHER *c, const EVP_MD *md, int en_de) | - | ||||||||||||
189 | { | - | ||||||||||||
190 | unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; | - | ||||||||||||
191 | int saltlen, iter; | - | ||||||||||||
192 | int rv = 0; | - | ||||||||||||
193 | unsigned int keylen = 0; | - | ||||||||||||
194 | int prf_nid, hmac_md_nid; | - | ||||||||||||
195 | PBKDF2PARAM *kdf = NULL; | - | ||||||||||||
196 | const EVP_MD *prfmd; | - | ||||||||||||
197 | - | |||||||||||||
198 | if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
| 0 | ||||||||||||
199 | EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET); | - | ||||||||||||
200 | goto err; never executed: goto err; | 0 | ||||||||||||
201 | } | - | ||||||||||||
202 | keylen = EVP_CIPHER_CTX_key_length(ctx); | - | ||||||||||||
203 | OPENSSL_assert(keylen <= sizeof(key)); | - | ||||||||||||
204 | - | |||||||||||||
205 | /* Decode parameter */ | - | ||||||||||||
206 | - | |||||||||||||
207 | kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param); | - | ||||||||||||
208 | - | |||||||||||||
209 | if (kdf == NULL) {
| 0 | ||||||||||||
210 | EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); | - | ||||||||||||
211 | goto err; never executed: goto err; | 0 | ||||||||||||
212 | } | - | ||||||||||||
213 | - | |||||||||||||
214 | keylen = EVP_CIPHER_CTX_key_length(ctx); | - | ||||||||||||
215 | - | |||||||||||||
216 | /* Now check the parameters of the kdf */ | - | ||||||||||||
217 | - | |||||||||||||
218 | if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {
| 0 | ||||||||||||
219 | EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH); | - | ||||||||||||
220 | goto err; never executed: goto err; | 0 | ||||||||||||
221 | } | - | ||||||||||||
222 | - | |||||||||||||
223 | if (kdf->prf)
| 0 | ||||||||||||
224 | prf_nid = OBJ_obj2nid(kdf->prf->algorithm); never executed: prf_nid = OBJ_obj2nid(kdf->prf->algorithm); | 0 | ||||||||||||
225 | else | - | ||||||||||||
226 | prf_nid = NID_hmacWithSHA1; never executed: prf_nid = 163; | 0 | ||||||||||||
227 | - | |||||||||||||
228 | if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
| 0 | ||||||||||||
229 | EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); | - | ||||||||||||
230 | goto err; never executed: goto err; | 0 | ||||||||||||
231 | } | - | ||||||||||||
232 | - | |||||||||||||
233 | prfmd = EVP_get_digestbynid(hmac_md_nid); | - | ||||||||||||
234 | if (prfmd == NULL) {
| 0 | ||||||||||||
235 | EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); | - | ||||||||||||
236 | goto err; never executed: goto err; | 0 | ||||||||||||
237 | } | - | ||||||||||||
238 | - | |||||||||||||
239 | if (kdf->salt->type != V_ASN1_OCTET_STRING) {
| 0 | ||||||||||||
240 | EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE); | - | ||||||||||||
241 | goto err; never executed: goto err; | 0 | ||||||||||||
242 | } | - | ||||||||||||
243 | - | |||||||||||||
244 | /* it seems that its all OK */ | - | ||||||||||||
245 | salt = kdf->salt->value.octet_string->data; | - | ||||||||||||
246 | saltlen = kdf->salt->value.octet_string->length; | - | ||||||||||||
247 | iter = ASN1_INTEGER_get(kdf->iter); | - | ||||||||||||
248 | if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
| 0 | ||||||||||||
249 | keylen, key))
| 0 | ||||||||||||
250 | goto err; never executed: goto err; | 0 | ||||||||||||
251 | rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); | - | ||||||||||||
252 | err: code before this statement never executed: err: | 0 | ||||||||||||
253 | OPENSSL_cleanse(key, keylen); | - | ||||||||||||
254 | PBKDF2PARAM_free(kdf); | - | ||||||||||||
255 | return rv; never executed: return rv; | 0 | ||||||||||||
256 | } | - | ||||||||||||
257 | - | |||||||||||||
258 | # ifdef OPENSSL_DEBUG_PKCS5V2 | - | ||||||||||||
259 | static void h__dump(const unsigned char *p, int len) | - | ||||||||||||
260 | { | - | ||||||||||||
261 | for (; len--; p++) | - | ||||||||||||
262 | fprintf(stderr, "%02X ", *p); | - | ||||||||||||
263 | fprintf(stderr, "\n"); | - | ||||||||||||
264 | } | - | ||||||||||||
265 | # endif | - | ||||||||||||
Source code | Switch to Preprocessed file |