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.c86
1 files changed, 61 insertions, 25 deletions
diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c
index 6bec77baf9..334379f310 100644
--- a/src/lib/libcrypto/evp/p5_crpt2.c
+++ b/src/lib/libcrypto/evp/p5_crpt2.c
@@ -3,7 +3,7 @@
3 * project 1999. 3 * project 1999.
4 */ 4 */
5/* ==================================================================== 5/* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 6 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
@@ -71,28 +71,38 @@
71#endif 71#endif
72 72
73/* This is an implementation of PKCS#5 v2.0 password based encryption key 73/* This is an implementation of PKCS#5 v2.0 password based encryption key
74 * derivation function PBKDF2 using the only currently defined function HMAC 74 * derivation function PBKDF2.
75 * with SHA1. Verified against test vectors posted by Peter Gutmann 75 * SHA1 version verified against test vectors posted by Peter Gutmann
76 * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list. 76 * <pgut001@cs.auckland.ac.nz> to the PKCS-TNG <pkcs-tng@rsa.com> mailing list.
77 */ 77 */
78 78
79int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, 79int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
80 const unsigned char *salt, int saltlen, int iter, 80 const unsigned char *salt, int saltlen, int iter,
81 const EVP_MD *digest,
81 int keylen, unsigned char *out) 82 int keylen, unsigned char *out)
82{ 83 {
83 unsigned char digtmp[SHA_DIGEST_LENGTH], *p, itmp[4]; 84 unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
84 int cplen, j, k, tkeylen; 85 int cplen, j, k, tkeylen, mdlen;
85 unsigned long i = 1; 86 unsigned long i = 1;
86 HMAC_CTX hctx; 87 HMAC_CTX hctx;
87 88
89 mdlen = EVP_MD_size(digest);
90 if (mdlen < 0)
91 return 0;
92
88 HMAC_CTX_init(&hctx); 93 HMAC_CTX_init(&hctx);
89 p = out; 94 p = out;
90 tkeylen = keylen; 95 tkeylen = keylen;
91 if(!pass) passlen = 0; 96 if(!pass)
92 else if(passlen == -1) passlen = strlen(pass); 97 passlen = 0;
93 while(tkeylen) { 98 else if(passlen == -1)
94 if(tkeylen > SHA_DIGEST_LENGTH) cplen = SHA_DIGEST_LENGTH; 99 passlen = strlen(pass);
95 else cplen = tkeylen; 100 while(tkeylen)
101 {
102 if(tkeylen > mdlen)
103 cplen = mdlen;
104 else
105 cplen = tkeylen;
96 /* We are unlikely to ever use more than 256 blocks (5120 bits!) 106 /* We are unlikely to ever use more than 256 blocks (5120 bits!)
97 * but just in case... 107 * but just in case...
98 */ 108 */
@@ -100,20 +110,22 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
100 itmp[1] = (unsigned char)((i >> 16) & 0xff); 110 itmp[1] = (unsigned char)((i >> 16) & 0xff);
101 itmp[2] = (unsigned char)((i >> 8) & 0xff); 111 itmp[2] = (unsigned char)((i >> 8) & 0xff);
102 itmp[3] = (unsigned char)(i & 0xff); 112 itmp[3] = (unsigned char)(i & 0xff);
103 HMAC_Init_ex(&hctx, pass, passlen, EVP_sha1(), NULL); 113 HMAC_Init_ex(&hctx, pass, passlen, digest, NULL);
104 HMAC_Update(&hctx, salt, saltlen); 114 HMAC_Update(&hctx, salt, saltlen);
105 HMAC_Update(&hctx, itmp, 4); 115 HMAC_Update(&hctx, itmp, 4);
106 HMAC_Final(&hctx, digtmp, NULL); 116 HMAC_Final(&hctx, digtmp, NULL);
107 memcpy(p, digtmp, cplen); 117 memcpy(p, digtmp, cplen);
108 for(j = 1; j < iter; j++) { 118 for(j = 1; j < iter; j++)
109 HMAC(EVP_sha1(), pass, passlen, 119 {
110 digtmp, SHA_DIGEST_LENGTH, digtmp, NULL); 120 HMAC(digest, pass, passlen,
111 for(k = 0; k < cplen; k++) p[k] ^= digtmp[k]; 121 digtmp, mdlen, digtmp, NULL);
112 } 122 for(k = 0; k < cplen; k++)
123 p[k] ^= digtmp[k];
124 }
113 tkeylen-= cplen; 125 tkeylen-= cplen;
114 i++; 126 i++;
115 p+= cplen; 127 p+= cplen;
116 } 128 }
117 HMAC_CTX_cleanup(&hctx); 129 HMAC_CTX_cleanup(&hctx);
118#ifdef DEBUG_PKCS5V2 130#ifdef DEBUG_PKCS5V2
119 fprintf(stderr, "Password:\n"); 131 fprintf(stderr, "Password:\n");
@@ -125,7 +137,15 @@ int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
125 h__dump (out, keylen); 137 h__dump (out, keylen);
126#endif 138#endif
127 return 1; 139 return 1;
128} 140 }
141
142int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
143 const unsigned char *salt, int saltlen, int iter,
144 int keylen, unsigned char *out)
145 {
146 return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
147 keylen, out);
148 }
129 149
130#ifdef DO_TEST 150#ifdef DO_TEST
131main() 151main()
@@ -155,6 +175,8 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
155 PBE2PARAM *pbe2 = NULL; 175 PBE2PARAM *pbe2 = NULL;
156 const EVP_CIPHER *cipher; 176 const EVP_CIPHER *cipher;
157 PBKDF2PARAM *kdf = NULL; 177 PBKDF2PARAM *kdf = NULL;
178 const EVP_MD *prfmd;
179 int prf_nid, hmac_md_nid;
158 180
159 if (param == NULL || param->type != V_ASN1_SEQUENCE || 181 if (param == NULL || param->type != V_ASN1_SEQUENCE ||
160 param->value.sequence == NULL) { 182 param->value.sequence == NULL) {
@@ -180,8 +202,7 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
180 /* lets see if we recognise the encryption algorithm. 202 /* lets see if we recognise the encryption algorithm.
181 */ 203 */
182 204
183 cipher = EVP_get_cipherbyname( 205 cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
184 OBJ_nid2sn(OBJ_obj2nid(pbe2->encryption->algorithm)));
185 206
186 if(!cipher) { 207 if(!cipher) {
187 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 208 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
@@ -226,10 +247,23 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
226 goto err; 247 goto err;
227 } 248 }
228 249
229 if(kdf->prf && (OBJ_obj2nid(kdf->prf->algorithm) != NID_hmacWithSHA1)) { 250 if (kdf->prf)
251 prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
252 else
253 prf_nid = NID_hmacWithSHA1;
254
255 if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0))
256 {
230 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); 257 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
231 goto err; 258 goto err;
232 } 259 }
260
261 prfmd = EVP_get_digestbynid(hmac_md_nid);
262 if (prfmd == NULL)
263 {
264 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
265 goto err;
266 }
233 267
234 if(kdf->salt->type != V_ASN1_OCTET_STRING) { 268 if(kdf->salt->type != V_ASN1_OCTET_STRING) {
235 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, 269 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
@@ -241,7 +275,9 @@ int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
241 salt = kdf->salt->value.octet_string->data; 275 salt = kdf->salt->value.octet_string->data;
242 saltlen = kdf->salt->value.octet_string->length; 276 saltlen = kdf->salt->value.octet_string->length;
243 iter = ASN1_INTEGER_get(kdf->iter); 277 iter = ASN1_INTEGER_get(kdf->iter);
244 PKCS5_PBKDF2_HMAC_SHA1(pass, passlen, salt, saltlen, iter, keylen, key); 278 if(!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
279 keylen, key))
280 goto err;
245 EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); 281 EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
246 OPENSSL_cleanse(key, keylen); 282 OPENSSL_cleanse(key, keylen);
247 PBKDF2PARAM_free(kdf); 283 PBKDF2PARAM_free(kdf);