OLD | NEW |
1 /* p5_crpt2.c */ | 1 /* p5_crpt2.c */ |
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
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 |
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 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 #include <openssl/hmac.h> | 64 #include <openssl/hmac.h> |
65 | 65 |
66 /* set this to print out info about the keygen algorithm */ | 66 /* set this to print out info about the keygen algorithm */ |
67 /* #define DEBUG_PKCS5V2 */ | 67 /* #define DEBUG_PKCS5V2 */ |
68 | 68 |
69 #ifdef DEBUG_PKCS5V2 | 69 #ifdef DEBUG_PKCS5V2 |
70 static void h__dump (const unsigned char *p, int len); | 70 static void h__dump (const unsigned char *p, int len); |
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 |
79 int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, | 79 int 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 */ |
99 itmp[0] = (unsigned char)((i >> 24) & 0xff); | 109 itmp[0] = (unsigned char)((i >> 24) & 0xff); |
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"); |
120 h__dump (pass, passlen); | 132 h__dump (pass, passlen); |
121 fprintf(stderr, "Salt:\n"); | 133 fprintf(stderr, "Salt:\n"); |
122 h__dump (salt, saltlen); | 134 h__dump (salt, saltlen); |
123 fprintf(stderr, "Iteration count %d\n", iter); | 135 fprintf(stderr, "Iteration count %d\n", iter); |
124 fprintf(stderr, "Key:\n"); | 136 fprintf(stderr, "Key:\n"); |
125 h__dump (out, keylen); | 137 h__dump (out, keylen); |
126 #endif | 138 #endif |
127 return 1; | 139 return 1; |
128 } | 140 » } |
| 141 |
| 142 int 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 |
131 main() | 151 main() |
132 { | 152 { |
133 unsigned char out[4]; | 153 unsigned char out[4]; |
134 unsigned char salt[] = {0x12, 0x34, 0x56, 0x78}; | 154 unsigned char salt[] = {0x12, 0x34, 0x56, 0x78}; |
135 PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); | 155 PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); |
136 fprintf(stderr, "Out %02X %02X %02X %02X\n", | 156 fprintf(stderr, "Out %02X %02X %02X %02X\n", |
137 out[0], out[1], out[2], out[3]); | 157 out[0], out[1], out[2], out[3]); |
138 } | 158 } |
139 | 159 |
140 #endif | 160 #endif |
141 | 161 |
142 /* Now the key derivation function itself. This is a bit evil because | 162 /* Now the key derivation function itself. This is a bit evil because |
143 * it has to check the ASN1 parameters are valid: and there are quite a | 163 * it has to check the ASN1 parameters are valid: and there are quite a |
144 * few of them... | 164 * few of them... |
145 */ | 165 */ |
146 | 166 |
147 int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, | 167 int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, |
148 ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md
, | 168 ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md
, |
149 int en_de) | 169 int en_de) |
150 { | 170 { |
151 unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; | 171 unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; |
152 const unsigned char *pbuf; | 172 const unsigned char *pbuf; |
153 int saltlen, iter, plen; | 173 int saltlen, iter, plen; |
154 unsigned int keylen; | 174 unsigned int keylen; |
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) { |
161 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); | 183 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); |
162 return 0; | 184 return 0; |
163 } | 185 } |
164 | 186 |
165 pbuf = param->value.sequence->data; | 187 pbuf = param->value.sequence->data; |
166 plen = param->value.sequence->length; | 188 plen = param->value.sequence->length; |
167 if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { | 189 if(!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { |
168 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); | 190 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,EVP_R_DECODE_ERROR); |
169 return 0; | 191 return 0; |
170 } | 192 } |
171 | 193 |
172 /* See if we recognise the key derivation function */ | 194 /* See if we recognise the key derivation function */ |
173 | 195 |
174 if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { | 196 if(OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { |
175 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | 197 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, |
176 EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); | 198 EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); |
177 goto err; | 199 goto err; |
178 } | 200 } |
179 | 201 |
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, |
188 EVP_R_UNSUPPORTED_CIPHER); | 209 EVP_R_UNSUPPORTED_CIPHER); |
189 goto err; | 210 goto err; |
190 } | 211 } |
191 | 212 |
192 /* Fixup cipher based on AlgorithmIdentifier */ | 213 /* Fixup cipher based on AlgorithmIdentifier */ |
193 EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de); | 214 EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de); |
194 if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { | 215 if(EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { |
(...skipping 24 matching lines...) Expand all Loading... |
219 pbe2 = NULL; | 240 pbe2 = NULL; |
220 | 241 |
221 /* Now check the parameters of the kdf */ | 242 /* Now check the parameters of the kdf */ |
222 | 243 |
223 if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){ | 244 if(kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)){ |
224 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, | 245 EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, |
225 EVP_R_UNSUPPORTED_KEYLENGTH); | 246 EVP_R_UNSUPPORTED_KEYLENGTH); |
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, |
236 EVP_R_UNSUPPORTED_SALT_TYPE); | 270 EVP_R_UNSUPPORTED_SALT_TYPE); |
237 goto err; | 271 goto err; |
238 } | 272 } |
239 | 273 |
240 /* it seems that its all OK */ | 274 /* it seems that its all OK */ |
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); |
248 return 1; | 284 return 1; |
249 | 285 |
250 err: | 286 err: |
251 PBE2PARAM_free(pbe2); | 287 PBE2PARAM_free(pbe2); |
252 PBKDF2PARAM_free(kdf); | 288 PBKDF2PARAM_free(kdf); |
253 return 0; | 289 return 0; |
254 } | 290 } |
255 | 291 |
256 #ifdef DEBUG_PKCS5V2 | 292 #ifdef DEBUG_PKCS5V2 |
257 static void h__dump (const unsigned char *p, int len) | 293 static void h__dump (const unsigned char *p, int len) |
258 { | 294 { |
259 for (; len --; p++) fprintf(stderr, "%02X ", *p); | 295 for (; len --; p++) fprintf(stderr, "%02X ", *p); |
260 fprintf(stderr, "\n"); | 296 fprintf(stderr, "\n"); |
261 } | 297 } |
262 #endif | 298 #endif |
263 #endif | 299 #endif |
OLD | NEW |