summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp/p5_crpt2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/evp/p5_crpt2.c')
-rw-r--r--src/lib/libcrypto/evp/p5_crpt2.c169
1 files changed, 80 insertions, 89 deletions
diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c
index fe3c6c8813..c276cd28b8 100644
--- a/src/lib/libcrypto/evp/p5_crpt2.c
+++ b/src/lib/libcrypto/evp/p5_crpt2.c
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -68,7 +68,7 @@
68/* #define DEBUG_PKCS5V2 */ 68/* #define DEBUG_PKCS5V2 */
69 69
70#ifdef DEBUG_PKCS5V2 70#ifdef DEBUG_PKCS5V2
71 static void h__dump (const unsigned char *p, int len); 71static void h__dump (const unsigned char *p, int len);
72#endif 72#endif
73 73
74/* This is an implementation of PKCS#5 v2.0 password based encryption key 74/* This is an implementation of PKCS#5 v2.0 password based encryption key
@@ -77,11 +77,10 @@
77 * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list. 77 * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
78 */ 78 */
79 79
80int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, 80int
81 const unsigned char *salt, int saltlen, int iter, 81PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt,
82 const EVP_MD *digest, 82 int saltlen, int iter, const EVP_MD *digest, int keylen, unsigned char *out)
83 int keylen, unsigned char *out) 83{
84 {
85 unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; 84 unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
86 int cplen, j, k, tkeylen, mdlen; 85 int cplen, j, k, tkeylen, mdlen;
87 unsigned long i = 1; 86 unsigned long i = 1;
@@ -94,18 +93,16 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
94 HMAC_CTX_init(&hctx_tpl); 93 HMAC_CTX_init(&hctx_tpl);
95 p = out; 94 p = out;
96 tkeylen = keylen; 95 tkeylen = keylen;
97 if(!pass) 96 if (!pass)
98 passlen = 0; 97 passlen = 0;
99 else if(passlen == -1) 98 else if (passlen == -1)
100 passlen = strlen(pass); 99 passlen = strlen(pass);
101 if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) 100 if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) {
102 {
103 HMAC_CTX_cleanup(&hctx_tpl); 101 HMAC_CTX_cleanup(&hctx_tpl);
104 return 0; 102 return 0;
105 } 103 }
106 while(tkeylen) 104 while (tkeylen) {
107 { 105 if (tkeylen > mdlen)
108 if(tkeylen > mdlen)
109 cplen = mdlen; 106 cplen = mdlen;
110 else 107 else
111 cplen = tkeylen; 108 cplen = tkeylen;
@@ -116,43 +113,38 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
116 itmp[1] = (unsigned char)((i >> 16) & 0xff); 113 itmp[1] = (unsigned char)((i >> 16) & 0xff);
117 itmp[2] = (unsigned char)((i >> 8) & 0xff); 114 itmp[2] = (unsigned char)((i >> 8) & 0xff);
118 itmp[3] = (unsigned char)(i & 0xff); 115 itmp[3] = (unsigned char)(i & 0xff);
119 if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) 116 if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
120 {
121 HMAC_CTX_cleanup(&hctx_tpl); 117 HMAC_CTX_cleanup(&hctx_tpl);
122 return 0; 118 return 0;
123 } 119 }
124 if (!HMAC_Update(&hctx, salt, saltlen) 120 if (!HMAC_Update(&hctx, salt, saltlen) ||
125 || !HMAC_Update(&hctx, itmp, 4) 121 !HMAC_Update(&hctx, itmp, 4) ||
126 || !HMAC_Final(&hctx, digtmp, NULL)) 122 !HMAC_Final(&hctx, digtmp, NULL)) {
127 {
128 HMAC_CTX_cleanup(&hctx_tpl); 123 HMAC_CTX_cleanup(&hctx_tpl);
129 HMAC_CTX_cleanup(&hctx); 124 HMAC_CTX_cleanup(&hctx);
130 return 0; 125 return 0;
131 } 126 }
132 HMAC_CTX_cleanup(&hctx); 127 HMAC_CTX_cleanup(&hctx);
133 memcpy(p, digtmp, cplen); 128 memcpy(p, digtmp, cplen);
134 for(j = 1; j < iter; j++) 129 for (j = 1; j < iter; j++) {
135 { 130 if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) {
136 if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
137 {
138 HMAC_CTX_cleanup(&hctx_tpl); 131 HMAC_CTX_cleanup(&hctx_tpl);
139 return 0; 132 return 0;
140 } 133 }
141 if (!HMAC_Update(&hctx, digtmp, mdlen) 134 if (!HMAC_Update(&hctx, digtmp, mdlen) ||
142 || !HMAC_Final(&hctx, digtmp, NULL)) 135 !HMAC_Final(&hctx, digtmp, NULL)) {
143 {
144 HMAC_CTX_cleanup(&hctx_tpl); 136 HMAC_CTX_cleanup(&hctx_tpl);
145 HMAC_CTX_cleanup(&hctx); 137 HMAC_CTX_cleanup(&hctx);
146 return 0; 138 return 0;
147 } 139 }
148 HMAC_CTX_cleanup(&hctx); 140 HMAC_CTX_cleanup(&hctx);
149 for(k = 0; k < cplen; k++) 141 for (k = 0; k < cplen; k++)
150 p[k] ^= digtmp[k]; 142 p[k] ^= digtmp[k];
151 }
152 tkeylen-= cplen;
153 i++;
154 p+= cplen;
155 } 143 }
144 tkeylen -= cplen;
145 i++;
146 p += cplen;
147 }
156 HMAC_CTX_cleanup(&hctx_tpl); 148 HMAC_CTX_cleanup(&hctx_tpl);
157#ifdef DEBUG_PKCS5V2 149#ifdef DEBUG_PKCS5V2
158 fprintf(stderr, "Password:\n"); 150 fprintf(stderr, "Password:\n");
@@ -164,15 +156,15 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
164 h__dump (out, keylen); 156 h__dump (out, keylen);
165#endif 157#endif
166 return 1; 158 return 1;
167 } 159}
168 160
169int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, 161int
170 const unsigned char *salt, int saltlen, int iter, 162PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt,
171 int keylen, unsigned char *out) 163 int saltlen, int iter, int keylen, unsigned char *out)
172 { 164{
173 return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), 165 return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
174 keylen, out); 166 EVP_sha1(), keylen, out);
175 } 167}
176 168
177#ifdef DO_TEST 169#ifdef DO_TEST
178main() 170main()
@@ -181,9 +173,8 @@ main()
181 unsigned char salt[] = {0x12, 0x34, 0x56, 0x78}; 173 unsigned char salt[] = {0x12, 0x34, 0x56, 0x78};
182 PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); 174 PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
183 fprintf(stderr, "Out %02X %02X %02X %02X\n", 175 fprintf(stderr, "Out %02X %02X %02X %02X\n",
184 out[0], out[1], out[2], out[3]); 176 out[0], out[1], out[2], out[3]);
185} 177}
186
187#endif 178#endif
188 179
189/* Now the key derivation function itself. This is a bit evil because 180/* Now the key derivation function itself. This is a bit evil because
@@ -191,9 +182,9 @@ main()
191 * few of them... 182 * few of them...
192 */ 183 */
193 184
194int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, 185int
195 ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, 186PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
196 int en_de) 187 ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de)
197{ 188{
198 const unsigned char *pbuf; 189 const unsigned char *pbuf;
199 int plen; 190 int plen;
@@ -204,22 +195,22 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
204 195
205 if (param == NULL || param->type != V_ASN1_SEQUENCE || 196 if (param == NULL || param->type != V_ASN1_SEQUENCE ||
206 param->value.sequence == NULL) { 197 param->value.sequence == NULL) {
207 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); 198 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
208 goto err; 199 goto err;
209 } 200 }
210 201
211 pbuf = param->value.sequence->data; 202 pbuf = param->value.sequence->data;
212 plen = param->value.sequence->length; 203 plen = param->value.sequence->length;
213 if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { 204 if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) {
214 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); 205 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
215 goto err; 206 goto err;
216 } 207 }
217 208
218 /* See if we recognise the key derivation function */ 209 /* See if we recognise the key derivation function */
219 210
220 if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { 211 if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) {
221 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 212 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
222 EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); 213 EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
223 goto err; 214 goto err;
224 } 215 }
225 216
@@ -228,30 +219,31 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
228 219
229 cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); 220 cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
230 221
231 if(!cipher) { 222 if (!cipher) {
232 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 223 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
233 EVP_R_UNSUPPORTED_CIPHER); 224 EVP_R_UNSUPPORTED_CIPHER);
234 goto err; 225 goto err;
235 } 226 }
236 227
237 /* Fixup cipher based on AlgorithmIdentifier */ 228 /* Fixup cipher based on AlgorithmIdentifier */
238 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) 229 if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
239 goto err; 230 goto err;
240 if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { 231 if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
241 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 232 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
242 EVP_R_CIPHER_PARAMETER_ERROR); 233 EVP_R_CIPHER_PARAMETER_ERROR);
243 goto err; 234 goto err;
244 } 235 }
245 rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen, 236 rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen,
246 pbe2->keyfunc->parameter, c, md, en_de); 237 pbe2->keyfunc->parameter, c, md, en_de);
247 err: 238
239err:
248 PBE2PARAM_free(pbe2); 240 PBE2PARAM_free(pbe2);
249 return rv; 241 return rv;
250} 242}
251 243
252int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, 244int
253 ASN1_TYPE *param, 245PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
254 const EVP_CIPHER *c, const EVP_MD *md, int en_de) 246 ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, int en_de)
255{ 247{
256 unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; 248 unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
257 const unsigned char *pbuf; 249 const unsigned char *pbuf;
@@ -262,27 +254,25 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
262 PBKDF2PARAM *kdf = NULL; 254 PBKDF2PARAM *kdf = NULL;
263 const EVP_MD *prfmd; 255 const EVP_MD *prfmd;
264 256
265 if (EVP_CIPHER_CTX_cipher(ctx) == NULL) 257 if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
266 { 258 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
267 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_NO_CIPHER_SET);
268 goto err; 259 goto err;
269 } 260 }
270 keylen = EVP_CIPHER_CTX_key_length(ctx); 261 keylen = EVP_CIPHER_CTX_key_length(ctx);
271 OPENSSL_assert(keylen <= sizeof key); 262 OPENSSL_assert(keylen <= sizeof key);
272 263
273 /* Decode parameter */ 264 /* Decode parameter */
274 265
275 if(!param || (param->type != V_ASN1_SEQUENCE)) 266 if (!param || (param->type != V_ASN1_SEQUENCE)) {
276 { 267 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
277 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR);
278 goto err; 268 goto err;
279 } 269 }
280 270
281 pbuf = param->value.sequence->data; 271 pbuf = param->value.sequence->data;
282 plen = param->value.sequence->length; 272 plen = param->value.sequence->length;
283 273
284 if(!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) { 274 if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen)) ) {
285 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,EVP_R_DECODE_ERROR); 275 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
286 goto err; 276 goto err;
287 } 277 }
288 278
@@ -290,9 +280,10 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
290 280
291 /* Now check the parameters of the kdf */ 281 /* Now check the parameters of the kdf */
292 282
293 if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){ 283 if (kdf->keylength &&
284 (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){
294 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, 285 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
295 EVP_R_UNSUPPORTED_KEYLENGTH); 286 EVP_R_UNSUPPORTED_KEYLENGTH);
296 goto err; 287 goto err;
297 } 288 }
298 289
@@ -301,22 +292,20 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
301 else 292 else
302 prf_nid = NID_hmacWithSHA1; 293 prf_nid = NID_hmacWithSHA1;
303 294
304 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) 295 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
305 {
306 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); 296 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
307 goto err; 297 goto err;
308 } 298 }
309 299
310 prfmd = EVP_get_digestbynid(hmac_md_nid); 300 prfmd = EVP_get_digestbynid(hmac_md_nid);
311 if (prfmd == NULL) 301 if (prfmd == NULL) {
312 {
313 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); 302 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
314 goto err; 303 goto err;
315 } 304 }
316 305
317 if(kdf->salt->type != V_ASN1_OCTET_STRING) { 306 if (kdf->salt->type != V_ASN1_OCTET_STRING) {
318 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, 307 EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN,
319 EVP_R_UNSUPPORTED_SALT_TYPE); 308 EVP_R_UNSUPPORTED_SALT_TYPE);
320 goto err; 309 goto err;
321 } 310 }
322 311
@@ -324,11 +313,12 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
324 salt = kdf->salt->value.octet_string->data; 313 salt = kdf->salt->value.octet_string->data;
325 saltlen = kdf->salt->value.octet_string->length; 314 saltlen = kdf->salt->value.octet_string->length;
326 iter = ASN1_INTEGER_get(kdf->iter); 315 iter = ASN1_INTEGER_get(kdf->iter);
327 if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, 316 if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
328 keylen, key)) 317 keylen, key))
329 goto err; 318 goto err;
330 rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); 319 rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
331 err: 320
321err:
332 OPENSSL_cleanse(key, keylen); 322 OPENSSL_cleanse(key, keylen);
333 PBKDF2PARAM_free(kdf); 323 PBKDF2PARAM_free(kdf);
334 return rv; 324 return rv;
@@ -337,8 +327,9 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
337#ifdef DEBUG_PKCS5V2 327#ifdef DEBUG_PKCS5V2
338static void h__dump (const unsigned char *p, int len) 328static void h__dump (const unsigned char *p, int len)
339{ 329{
340 for (; len --; p++) fprintf(stderr, "%02X ", *p); 330 for (; len --; p++)
341 fprintf(stderr, "\n"); 331 fprintf(stderr, "%02X ", *p);
332 fprintf(stderr, "\n");
342} 333}
343#endif 334#endif
344#endif 335#endif