Extract PKCS#5 handling from pkcs8 plugin to separate helper class
[strongswan.git] / src / libstrongswan / crypto / pkcs5.c
1 /*
2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "pkcs5.h"
17
18 #include <utils/debug.h>
19 #include <asn1/oid.h>
20 #include <asn1/asn1.h>
21 #include <asn1/asn1_parser.h>
22
23 typedef struct private_pkcs5_t private_pkcs5_t;
24
25 /**
26 * Private data of a pkcs5_t object
27 */
28 struct private_pkcs5_t {
29
30 /**
31 * Implements pkcs5_t.
32 */
33 pkcs5_t public;
34
35 /**
36 * Salt used during encryption
37 */
38 chunk_t salt;
39
40 /**
41 * Iterations for key derivation
42 */
43 u_int64_t iterations;
44
45 /**
46 * Encryption algorithm
47 */
48 encryption_algorithm_t encr;
49
50 /**
51 * Encryption key length
52 */
53 size_t keylen;
54
55 /**
56 * Crypter
57 */
58 crypter_t *crypter;
59
60
61 /**
62 * The encryption scheme
63 */
64 enum {
65 PKCS5_SCHEME_PBES1,
66 PKCS5_SCHEME_PBES2,
67 } scheme;
68
69 /**
70 * Data used for individual schemes
71 */
72 union {
73 struct {
74 /**
75 * Hash algorithm
76 */
77 hash_algorithm_t hash;
78
79 /**
80 * Hasher
81 */
82 hasher_t *hasher;
83
84 } pbes1;
85 struct {
86 /**
87 * PRF algorithm
88 */
89 pseudo_random_function_t prf_alg;
90
91 /**
92 * PRF
93 */
94 prf_t * prf;
95
96 /**
97 * IV
98 */
99 chunk_t iv;
100
101 } pbes2;
102 } data;
103 };
104
105 /**
106 * Verify padding of decrypted blob.
107 * Length of blob is adjusted accordingly.
108 */
109 static bool verify_padding(chunk_t *blob)
110 {
111 u_int8_t padding, count;
112
113 padding = count = blob->ptr[blob->len - 1];
114
115 if (padding > 8)
116 {
117 return FALSE;
118 }
119 for (; blob->len && count; --blob->len, --count)
120 {
121 if (blob->ptr[blob->len - 1] != padding)
122 {
123 return FALSE;
124 }
125 }
126 return TRUE;
127 }
128
129 /**
130 * Prototype for key derivation functions.
131 */
132 typedef bool (*kdf_t)(private_pkcs5_t *this, chunk_t password, chunk_t key);
133
134 /**
135 * Try to decrypt the given data with the given password using the given
136 * key derivation function. keymat is where the kdf function writes the key
137 * to, key and iv point to the actual keys and initialization vectors resp.
138 */
139 static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
140 chunk_t data, chunk_t *decrypted, kdf_t kdf,
141 chunk_t keymat, chunk_t key, chunk_t iv)
142 {
143 if (!kdf(this, password, keymat))
144 {
145 return FALSE;
146 }
147 if (!this->crypter->set_key(this->crypter, key) ||
148 !this->crypter->decrypt(this->crypter, data, iv, decrypted))
149 {
150 memwipe(keymat.ptr, keymat.len);
151 return FALSE;
152 }
153 memwipe(keymat.ptr, keymat.len);
154 if (verify_padding(decrypted))
155 {
156 return TRUE;
157 }
158 chunk_free(decrypted);
159 return FALSE;
160 }
161
162 /**
163 * Function F of PBKDF2
164 */
165 static bool pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed,
166 u_int64_t iterations)
167 {
168 chunk_t u;
169 u_int64_t i;
170
171 u = chunk_alloca(prf->get_block_size(prf));
172 if (!prf->get_bytes(prf, seed, u.ptr))
173 {
174 return FALSE;
175 }
176 memcpy(block.ptr, u.ptr, block.len);
177
178 for (i = 1; i < iterations; i++)
179 {
180 if (!prf->get_bytes(prf, u, u.ptr))
181 {
182 return FALSE;
183 }
184 memxor(block.ptr, u.ptr, block.len);
185 }
186 return TRUE;
187 }
188
189 /**
190 * PBKDF2 key derivation function for PBES2, key must be allocated
191 */
192 static bool pbkdf2(private_pkcs5_t *this, chunk_t password, chunk_t key)
193 {
194 prf_t *prf;
195 chunk_t keymat, block, seed;
196 size_t blocks;
197 u_int32_t i = 0;
198
199 prf = this->data.pbes2.prf;
200
201 if (!prf->set_key(prf, password))
202 {
203 return FALSE;
204 }
205
206 block.len = prf->get_block_size(prf);
207 blocks = (key.len - 1) / block.len + 1;
208 keymat = chunk_alloca(blocks * block.len);
209
210 seed = chunk_cata("cc", this->salt, chunk_from_thing(i));
211
212 for (; i < blocks; i++)
213 {
214 htoun32(seed.ptr + this->salt.len, i + 1);
215 block.ptr = keymat.ptr + (i * block.len);
216 if (!pbkdf2_f(block, prf, seed, this->iterations))
217 {
218 return FALSE;
219 }
220 }
221 memcpy(key.ptr, keymat.ptr, key.len);
222 return TRUE;
223 }
224
225 /**
226 * PBKDF1 key derivation function for PBES1, key must be allocated
227 */
228 static bool pbkdf1(private_pkcs5_t *this, chunk_t password, chunk_t key)
229 {
230 hasher_t *hasher;
231 chunk_t hash;
232 u_int64_t i;
233
234 hasher = this->data.pbes1.hasher;
235
236 hash = chunk_alloca(hasher->get_hash_size(hasher));
237 if (!hasher->get_hash(hasher, password, NULL) ||
238 !hasher->get_hash(hasher, this->salt, hash.ptr))
239 {
240 return FALSE;
241 }
242
243 for (i = 1; i < this->iterations; i++)
244 {
245 if (!hasher->get_hash(hasher, hash, hash.ptr))
246 {
247 return FALSE;
248 }
249 }
250 memcpy(key.ptr, hash.ptr, key.len);
251 return TRUE;
252 }
253
254 static bool ensure_crypto_primitives(private_pkcs5_t *this, chunk_t data)
255 {
256 if (!this->crypter)
257 {
258 this->crypter = lib->crypto->create_crypter(lib->crypto, this->encr,
259 this->keylen);
260 if (!this->crypter)
261 {
262 DBG1(DBG_ASN, " %N encryption algorithm not available",
263 encryption_algorithm_names, this->encr);
264 return FALSE;
265 }
266 }
267 if (data.len % this->crypter->get_block_size(this->crypter))
268 {
269 DBG1(DBG_ASN, " data size is not a multiple of block size");
270 return FALSE;
271 }
272 switch (this->scheme)
273 {
274 case PKCS5_SCHEME_PBES1:
275 {
276 if (!this->data.pbes1.hasher)
277 {
278 hasher_t *hasher;
279
280 hasher = lib->crypto->create_hasher(lib->crypto,
281 this->data.pbes1.hash);
282 if (!hasher)
283 {
284 DBG1(DBG_ASN, " %N hash algorithm not available",
285 hash_algorithm_names, this->data.pbes1.hash);
286 return FALSE;
287 }
288 if (hasher->get_hash_size(hasher) < this->keylen)
289 {
290 hasher->destroy(hasher);
291 return FALSE;
292 }
293 this->data.pbes1.hasher = hasher;
294 }
295 }
296 case PKCS5_SCHEME_PBES2:
297 {
298 if (!this->data.pbes2.prf)
299 {
300 prf_t *prf;
301
302 prf = lib->crypto->create_prf(lib->crypto,
303 this->data.pbes2.prf_alg);
304 if (!prf)
305 {
306 DBG1(DBG_ASN, " %N prf algorithm not available",
307 pseudo_random_function_names,
308 this->data.pbes2.prf_alg);
309 return FALSE;
310 }
311 this->data.pbes2.prf = prf;
312 }
313 }
314 }
315 return TRUE;
316 }
317
318 METHOD(pkcs5_t, decrypt, bool,
319 private_pkcs5_t *this, chunk_t password, chunk_t data, chunk_t *decrypted)
320 {
321 chunk_t keymat, key, iv;
322 kdf_t kdf;
323
324 if (!ensure_crypto_primitives(this, data) || !decrypted)
325 {
326 return FALSE;
327 }
328 switch (this->scheme)
329 {
330 case PKCS5_SCHEME_PBES1:
331 kdf = pbkdf1;
332 keymat = chunk_alloca(this->keylen * 2);
333 key = chunk_create(keymat.ptr, this->keylen);
334 iv = chunk_create(keymat.ptr + this->keylen, this->keylen);
335 break;
336 case PKCS5_SCHEME_PBES2:
337 kdf = pbkdf2;
338 keymat = chunk_alloca(this->keylen);
339 key = keymat;
340 iv = this->data.pbes2.iv;
341 break;
342 default:
343 return FALSE;
344 }
345 return decrypt_generic(this, password, data, decrypted, kdf,
346 keymat, key, iv);
347 }
348
349 /**
350 * Converts an ASN.1 INTEGER object to an u_int64_t. If the INTEGER is longer
351 * than 8 bytes only the 8 LSBs are returned.
352 *
353 * @param blob body of an ASN.1 coded integer object
354 * @return converted integer
355 */
356 static u_int64_t parse_asn1_integer_uint64(chunk_t blob)
357 {
358 u_int64_t val = 0;
359 int i;
360
361 for (i = 0; i < blob.len; i++)
362 { /* if it is longer than 8 bytes, we just use the 8 LSBs */
363 val <<= 8;
364 val |= (u_int64_t)blob.ptr[i];
365 }
366 return val;
367 }
368
369 /**
370 * ASN.1 definition of a PBEParameter structure
371 */
372 static const asn1Object_t pbeParameterObjects[] = {
373 { 0, "PBEParameter", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
374 { 1, "salt", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */
375 { 1, "iterationCount", ASN1_INTEGER, ASN1_BODY }, /* 2 */
376 { 0, "exit", ASN1_EOC, ASN1_EXIT }
377 };
378 #define PBEPARAM_SALT 1
379 #define PBEPARAM_ITERATION_COUNT 2
380
381 /**
382 * Parse a PBEParameter structure
383 */
384 static bool parse_pbes1_params(private_pkcs5_t *this, chunk_t blob, int level0)
385 {
386 asn1_parser_t *parser;
387 chunk_t object;
388 int objectID;
389 bool success;
390
391 parser = asn1_parser_create(pbeParameterObjects, blob);
392 parser->set_top_level(parser, level0);
393
394 while (parser->iterate(parser, &objectID, &object))
395 {
396 switch (objectID)
397 {
398 case PBEPARAM_SALT:
399 {
400 this->salt = chunk_clone(object);
401 break;
402 }
403 case PBEPARAM_ITERATION_COUNT:
404 {
405 this->iterations = parse_asn1_integer_uint64(object);
406 break;
407 }
408 }
409 }
410 success = parser->success(parser);
411 parser->destroy(parser);
412 return success;
413 }
414
415 /**
416 * ASN.1 definition of a PBKDF2-params structure
417 * The salt is actually a CHOICE and could be an AlgorithmIdentifier from
418 * PBKDF2-SaltSources (but as per RFC 2898 that's for future versions).
419 */
420 static const asn1Object_t pbkdf2ParamsObjects[] = {
421 { 0, "PBKDF2-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
422 { 1, "salt", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */
423 { 1, "iterationCount",ASN1_INTEGER, ASN1_BODY }, /* 2 */
424 { 1, "keyLength", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 3 */
425 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
426 { 1, "prf", ASN1_EOC, ASN1_DEF|ASN1_RAW }, /* 5 */
427 { 0, "exit", ASN1_EOC, ASN1_EXIT }
428 };
429 #define PBKDF2_SALT 1
430 #define PBKDF2_ITERATION_COUNT 2
431 #define PBKDF2_KEYLENGTH 3
432 #define PBKDF2_PRF 5
433
434 /**
435 * Parse a PBKDF2-params structure
436 */
437 static bool parse_pbkdf2_params(private_pkcs5_t *this, chunk_t blob, int level0)
438 {
439 asn1_parser_t *parser;
440 chunk_t object;
441 int objectID;
442 bool success;
443
444 parser = asn1_parser_create(pbkdf2ParamsObjects, blob);
445 parser->set_top_level(parser, level0);
446
447 /* keylen is optional */
448 this->keylen = 0;
449
450 while (parser->iterate(parser, &objectID, &object))
451 {
452 switch (objectID)
453 {
454 case PBKDF2_SALT:
455 {
456 this->salt = chunk_clone(object);
457 break;
458 }
459 case PBKDF2_ITERATION_COUNT:
460 {
461 this->iterations = parse_asn1_integer_uint64(object);
462 break;
463 }
464 case PBKDF2_KEYLENGTH:
465 {
466 this->keylen = (size_t)parse_asn1_integer_uint64(object);
467 break;
468 }
469 case PBKDF2_PRF:
470 { /* defaults to id-hmacWithSHA1, no other is currently defined */
471 this->data.pbes2.prf_alg = PRF_HMAC_SHA1;
472 break;
473 }
474 }
475 }
476 success = parser->success(parser);
477 parser->destroy(parser);
478 return success;
479 }
480
481 /**
482 * ASN.1 definition of a PBES2-params structure
483 */
484 static const asn1Object_t pbes2ParamsObjects[] = {
485 { 0, "PBES2-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
486 { 1, "keyDerivationFunc", ASN1_EOC, ASN1_RAW }, /* 1 */
487 { 1, "encryptionScheme", ASN1_EOC, ASN1_RAW }, /* 2 */
488 { 0, "exit", ASN1_EOC, ASN1_EXIT }
489 };
490 #define PBES2PARAMS_KEY_DERIVATION_FUNC 1
491 #define PBES2PARAMS_ENCRYPTION_SCHEME 2
492
493 /**
494 * Parse a PBES2-params structure
495 */
496 static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
497 {
498 asn1_parser_t *parser;
499 chunk_t object, params;
500 int objectID;
501 bool success = FALSE;
502
503 parser = asn1_parser_create(pbes2ParamsObjects, blob);
504 parser->set_top_level(parser, level0);
505
506 while (parser->iterate(parser, &objectID, &object))
507 {
508 switch (objectID)
509 {
510 case PBES2PARAMS_KEY_DERIVATION_FUNC:
511 {
512 int oid = asn1_parse_algorithmIdentifier(object,
513 parser->get_level(parser) + 1, &params);
514 if (oid != OID_PBKDF2)
515 { /* unsupported key derivation function */
516 goto end;
517 }
518 if (!parse_pbkdf2_params(this, params,
519 parser->get_level(parser) + 1))
520 {
521 goto end;
522 }
523 break;
524 }
525 case PBES2PARAMS_ENCRYPTION_SCHEME:
526 {
527 int oid = asn1_parse_algorithmIdentifier(object,
528 parser->get_level(parser) + 1, &params);
529 if (oid != OID_3DES_EDE_CBC)
530 { /* unsupported encryption scheme */
531 goto end;
532 }
533 if (this->keylen <= 0)
534 { /* default key length for DES-EDE3-CBC-Pad */
535 this->keylen = 24;
536 }
537 if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
538 parser->get_level(parser) + 1, "IV"))
539 {
540 goto end;
541 }
542 this->encr = ENCR_3DES;
543 this->data.pbes2.iv = chunk_clone(params);
544 break;
545 }
546 }
547 }
548 success = parser->success(parser);
549 end:
550 parser->destroy(parser);
551 return success;
552 }
553
554 METHOD(pkcs5_t, destroy, void,
555 private_pkcs5_t *this)
556 {
557 DESTROY_IF(this->crypter);
558 chunk_free(&this->salt);
559 switch (this->scheme)
560 {
561 case PKCS5_SCHEME_PBES1:
562 DESTROY_IF(this->data.pbes1.hasher);
563 break;
564 case PKCS5_SCHEME_PBES2:
565 DESTROY_IF(this->data.pbes2.prf);
566 chunk_free(&this->data.pbes2.iv);
567 break;
568 }
569 free(this);
570 }
571
572 /*
573 * Described in header
574 */
575 pkcs5_t *pkcs5_from_algorithmIdentifier(chunk_t blob, int level0)
576 {
577 private_pkcs5_t *this;
578 chunk_t params;
579 int oid;
580
581 INIT(this,
582 .public = {
583 .decrypt = _decrypt,
584 .destroy = _destroy,
585 },
586 .scheme = PKCS5_SCHEME_PBES1,
587 .keylen = 8,
588 );
589
590 oid = asn1_parse_algorithmIdentifier(blob, level0, &params);
591
592 switch (oid)
593 {
594 case OID_PBE_MD5_DES_CBC:
595 this->encr = ENCR_DES;
596 this->data.pbes1.hash = HASH_MD5;
597 break;
598 case OID_PBE_SHA1_DES_CBC:
599 this->encr = ENCR_DES;
600 this->data.pbes1.hash = HASH_SHA1;
601 break;
602 case OID_PBES2:
603 this->scheme = PKCS5_SCHEME_PBES2;
604 break;
605 default:
606 /* encryption scheme not supported */
607 goto failure;
608 }
609
610 switch (this->scheme)
611 {
612 case PKCS5_SCHEME_PBES1:
613 if (!parse_pbes1_params(this, params, level0))
614 {
615 goto failure;
616 }
617 break;
618 case PKCS5_SCHEME_PBES2:
619 if (!parse_pbes2_params(this, params, level0))
620 {
621 goto failure;
622 }
623 break;
624 }
625 return &this->public;
626
627 failure:
628 destroy(this);
629 return NULL;
630 }