2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
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>.
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
18 #include <utils/debug.h>
20 #include <asn1/asn1.h>
21 #include <asn1/asn1_parser.h>
23 typedef struct private_pkcs5_t private_pkcs5_t
;
26 * Private data of a pkcs5_t object
28 struct private_pkcs5_t
{
36 * Salt used during encryption
41 * Iterations for key derivation
46 * Encryption algorithm
48 encryption_algorithm_t encr
;
51 * Encryption key length
62 * The encryption scheme
70 * Data used for individual schemes
77 hash_algorithm_t hash
;
89 pseudo_random_function_t prf_alg
;
106 * Verify padding of decrypted blob.
107 * Length of blob is adjusted accordingly.
109 static bool verify_padding(chunk_t
*blob
)
111 u_int8_t padding
, count
;
113 padding
= count
= blob
->ptr
[blob
->len
- 1];
119 for (; blob
->len
&& count
; --blob
->len
, --count
)
121 if (blob
->ptr
[blob
->len
- 1] != padding
)
130 * Prototype for key derivation functions.
132 typedef bool (*kdf_t
)(private_pkcs5_t
*this, chunk_t password
, chunk_t key
);
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.
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
)
143 if (!kdf(this, password
, keymat
))
147 if (!this->crypter
->set_key(this->crypter
, key
) ||
148 !this->crypter
->decrypt(this->crypter
, data
, iv
, decrypted
))
150 memwipe(keymat
.ptr
, keymat
.len
);
153 memwipe(keymat
.ptr
, keymat
.len
);
154 if (verify_padding(decrypted
))
158 chunk_free(decrypted
);
163 * Function F of PBKDF2
165 static bool pbkdf2_f(chunk_t block
, prf_t
*prf
, chunk_t seed
,
166 u_int64_t iterations
)
171 u
= chunk_alloca(prf
->get_block_size(prf
));
172 if (!prf
->get_bytes(prf
, seed
, u
.ptr
))
176 memcpy(block
.ptr
, u
.ptr
, block
.len
);
178 for (i
= 1; i
< iterations
; i
++)
180 if (!prf
->get_bytes(prf
, u
, u
.ptr
))
184 memxor(block
.ptr
, u
.ptr
, block
.len
);
190 * PBKDF2 key derivation function for PBES2, key must be allocated
192 static bool pbkdf2(private_pkcs5_t
*this, chunk_t password
, chunk_t key
)
195 chunk_t keymat
, block
, seed
;
199 prf
= this->data
.pbes2
.prf
;
201 if (!prf
->set_key(prf
, password
))
206 block
.len
= prf
->get_block_size(prf
);
207 blocks
= (key
.len
- 1) / block
.len
+ 1;
208 keymat
= chunk_alloca(blocks
* block
.len
);
210 seed
= chunk_cata("cc", this->salt
, chunk_from_thing(i
));
212 for (; i
< blocks
; i
++)
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
))
221 memcpy(key
.ptr
, keymat
.ptr
, key
.len
);
226 * PBKDF1 key derivation function for PBES1, key must be allocated
228 static bool pbkdf1(private_pkcs5_t
*this, chunk_t password
, chunk_t key
)
234 hasher
= this->data
.pbes1
.hasher
;
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
))
243 for (i
= 1; i
< this->iterations
; i
++)
245 if (!hasher
->get_hash(hasher
, hash
, hash
.ptr
))
250 memcpy(key
.ptr
, hash
.ptr
, key
.len
);
254 static bool ensure_crypto_primitives(private_pkcs5_t
*this, chunk_t data
)
258 this->crypter
= lib
->crypto
->create_crypter(lib
->crypto
, this->encr
,
262 DBG1(DBG_ASN
, " %N encryption algorithm not available",
263 encryption_algorithm_names
, this->encr
);
267 if (data
.len
% this->crypter
->get_block_size(this->crypter
))
269 DBG1(DBG_ASN
, " data size is not a multiple of block size");
272 switch (this->scheme
)
274 case PKCS5_SCHEME_PBES1
:
276 if (!this->data
.pbes1
.hasher
)
280 hasher
= lib
->crypto
->create_hasher(lib
->crypto
,
281 this->data
.pbes1
.hash
);
284 DBG1(DBG_ASN
, " %N hash algorithm not available",
285 hash_algorithm_names
, this->data
.pbes1
.hash
);
288 if (hasher
->get_hash_size(hasher
) < this->keylen
)
290 hasher
->destroy(hasher
);
293 this->data
.pbes1
.hasher
= hasher
;
296 case PKCS5_SCHEME_PBES2
:
298 if (!this->data
.pbes2
.prf
)
302 prf
= lib
->crypto
->create_prf(lib
->crypto
,
303 this->data
.pbes2
.prf_alg
);
306 DBG1(DBG_ASN
, " %N prf algorithm not available",
307 pseudo_random_function_names
,
308 this->data
.pbes2
.prf_alg
);
311 this->data
.pbes2
.prf
= prf
;
318 METHOD(pkcs5_t
, decrypt
, bool,
319 private_pkcs5_t
*this, chunk_t password
, chunk_t data
, chunk_t
*decrypted
)
321 chunk_t keymat
, key
, iv
;
324 if (!ensure_crypto_primitives(this, data
) || !decrypted
)
328 switch (this->scheme
)
330 case PKCS5_SCHEME_PBES1
:
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
);
336 case PKCS5_SCHEME_PBES2
:
338 keymat
= chunk_alloca(this->keylen
);
340 iv
= this->data
.pbes2
.iv
;
345 return decrypt_generic(this, password
, data
, decrypted
, kdf
,
350 * ASN.1 definition of a PBEParameter structure
352 static const asn1Object_t pbeParameterObjects
[] = {
353 { 0, "PBEParameter", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
354 { 1, "salt", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 1 */
355 { 1, "iterationCount", ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
356 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
358 #define PBEPARAM_SALT 1
359 #define PBEPARAM_ITERATION_COUNT 2
362 * Parse a PBEParameter structure
364 static bool parse_pbes1_params(private_pkcs5_t
*this, chunk_t blob
, int level0
)
366 asn1_parser_t
*parser
;
371 parser
= asn1_parser_create(pbeParameterObjects
, blob
);
372 parser
->set_top_level(parser
, level0
);
374 while (parser
->iterate(parser
, &objectID
, &object
))
380 this->salt
= chunk_clone(object
);
383 case PBEPARAM_ITERATION_COUNT
:
385 this->iterations
= asn1_parse_integer_uint64(object
);
390 success
= parser
->success(parser
);
391 parser
->destroy(parser
);
396 * ASN.1 definition of a PBKDF2-params structure
397 * The salt is actually a CHOICE and could be an AlgorithmIdentifier from
398 * PBKDF2-SaltSources (but as per RFC 2898 that's for future versions).
400 static const asn1Object_t pbkdf2ParamsObjects
[] = {
401 { 0, "PBKDF2-params", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
402 { 1, "salt", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 1 */
403 { 1, "iterationCount",ASN1_INTEGER
, ASN1_BODY
}, /* 2 */
404 { 1, "keyLength", ASN1_INTEGER
, ASN1_OPT
|ASN1_BODY
}, /* 3 */
405 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
406 { 1, "prf", ASN1_EOC
, ASN1_DEF
|ASN1_RAW
}, /* 5 */
407 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
409 #define PBKDF2_SALT 1
410 #define PBKDF2_ITERATION_COUNT 2
411 #define PBKDF2_KEYLENGTH 3
415 * Parse a PBKDF2-params structure
417 static bool parse_pbkdf2_params(private_pkcs5_t
*this, chunk_t blob
, int level0
)
419 asn1_parser_t
*parser
;
424 parser
= asn1_parser_create(pbkdf2ParamsObjects
, blob
);
425 parser
->set_top_level(parser
, level0
);
427 /* keylen is optional */
430 while (parser
->iterate(parser
, &objectID
, &object
))
436 this->salt
= chunk_clone(object
);
439 case PBKDF2_ITERATION_COUNT
:
441 this->iterations
= asn1_parse_integer_uint64(object
);
444 case PBKDF2_KEYLENGTH
:
446 this->keylen
= (size_t)asn1_parse_integer_uint64(object
);
450 { /* defaults to id-hmacWithSHA1, no other is currently defined */
451 this->data
.pbes2
.prf_alg
= PRF_HMAC_SHA1
;
456 success
= parser
->success(parser
);
457 parser
->destroy(parser
);
462 * ASN.1 definition of a PBES2-params structure
464 static const asn1Object_t pbes2ParamsObjects
[] = {
465 { 0, "PBES2-params", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
466 { 1, "keyDerivationFunc", ASN1_EOC
, ASN1_RAW
}, /* 1 */
467 { 1, "encryptionScheme", ASN1_EOC
, ASN1_RAW
}, /* 2 */
468 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
470 #define PBES2PARAMS_KEY_DERIVATION_FUNC 1
471 #define PBES2PARAMS_ENCRYPTION_SCHEME 2
474 * Parse a PBES2-params structure
476 static bool parse_pbes2_params(private_pkcs5_t
*this, chunk_t blob
, int level0
)
478 asn1_parser_t
*parser
;
479 chunk_t object
, params
;
481 bool success
= FALSE
;
483 parser
= asn1_parser_create(pbes2ParamsObjects
, blob
);
484 parser
->set_top_level(parser
, level0
);
486 while (parser
->iterate(parser
, &objectID
, &object
))
490 case PBES2PARAMS_KEY_DERIVATION_FUNC
:
492 int oid
= asn1_parse_algorithmIdentifier(object
,
493 parser
->get_level(parser
) + 1, ¶ms
);
494 if (oid
!= OID_PBKDF2
)
495 { /* unsupported key derivation function */
498 if (!parse_pbkdf2_params(this, params
,
499 parser
->get_level(parser
) + 1))
505 case PBES2PARAMS_ENCRYPTION_SCHEME
:
507 int oid
= asn1_parse_algorithmIdentifier(object
,
508 parser
->get_level(parser
) + 1, ¶ms
);
509 if (oid
!= OID_3DES_EDE_CBC
)
510 { /* unsupported encryption scheme */
513 if (this->keylen
<= 0)
514 { /* default key length for DES-EDE3-CBC-Pad */
517 if (!asn1_parse_simple_object(¶ms
, ASN1_OCTET_STRING
,
518 parser
->get_level(parser
) + 1, "IV"))
522 this->encr
= ENCR_3DES
;
523 this->data
.pbes2
.iv
= chunk_clone(params
);
528 success
= parser
->success(parser
);
530 parser
->destroy(parser
);
534 METHOD(pkcs5_t
, destroy
, void,
535 private_pkcs5_t
*this)
537 DESTROY_IF(this->crypter
);
538 chunk_free(&this->salt
);
539 switch (this->scheme
)
541 case PKCS5_SCHEME_PBES1
:
542 DESTROY_IF(this->data
.pbes1
.hasher
);
544 case PKCS5_SCHEME_PBES2
:
545 DESTROY_IF(this->data
.pbes2
.prf
);
546 chunk_free(&this->data
.pbes2
.iv
);
553 * Described in header
555 pkcs5_t
*pkcs5_from_algorithmIdentifier(chunk_t blob
, int level0
)
557 private_pkcs5_t
*this;
566 .scheme
= PKCS5_SCHEME_PBES1
,
570 oid
= asn1_parse_algorithmIdentifier(blob
, level0
, ¶ms
);
574 case OID_PBE_MD5_DES_CBC
:
575 this->encr
= ENCR_DES
;
576 this->data
.pbes1
.hash
= HASH_MD5
;
578 case OID_PBE_SHA1_DES_CBC
:
579 this->encr
= ENCR_DES
;
580 this->data
.pbes1
.hash
= HASH_SHA1
;
583 this->scheme
= PKCS5_SCHEME_PBES2
;
586 /* encryption scheme not supported */
590 switch (this->scheme
)
592 case PKCS5_SCHEME_PBES1
:
593 if (!parse_pbes1_params(this, params
, level0
))
598 case PKCS5_SCHEME_PBES2
:
599 if (!parse_pbes2_params(this, params
, level0
))
605 return &this->public;