2 * @file encryption_payload.c
4 * @brief Implementation of encryption_payload_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 #include "encryption_payload.h"
30 #include <encoding/payloads/encodings.h>
31 #include <utils/linked_list.h>
32 #include <utils/logger.h>
33 #include <encoding/generator.h>
34 #include <encoding/parser.h>
35 #include <utils/iterator.h>
36 #include <utils/randomizer.h>
37 #include <crypto/signers/signer.h>
42 typedef struct private_encryption_payload_t private_encryption_payload_t
;
45 * Private data of an encryption_payload_t' Object.
48 struct private_encryption_payload_t
{
51 * Public encryption_payload_t interface.
53 encryption_payload_t
public;
56 * There is no next payload for an encryption payload,
57 * since encryption payload MUST be the last one.
58 * next_payload means here the first payload of the
59 * contained, encrypted payload.
61 u_int8_t next_payload
;
69 * Length of this payload
71 u_int16_t payload_length
;
74 * Chunk containing the iv, data, padding,
75 * and (an eventually not calculated) signature.
80 * Chunk containing the data in decrypted (unpadded) form.
85 * Signer set by set_signer.
90 * Crypter, supplied by encrypt/decrypt
95 * Contained payloads of this encrpytion_payload.
97 linked_list_t
*payloads
;
100 * logger for this payload, uses MESSAGE context
105 * @brief Computes the length of this payload.
107 * @param this calling private_encryption_payload_t object
109 void (*compute_length
) (private_encryption_payload_t
*this);
112 * @brief Generate payloads (unencrypted) in chunk decrypted.
114 * @param this calling private_encryption_payload_t object
116 void (*generate
) (private_encryption_payload_t
*this);
119 * @brief Parse payloads from a (unencrypted) chunk.
121 * @param this calling private_encryption_payload_t object
123 status_t (*parse
) (private_encryption_payload_t
*this);
127 * Encoding rules to parse or generate a IKEv2-Encryption Payload.
129 * The defined offsets are the positions in a object of type
130 * private_encryption_payload_t.
133 encoding_rule_t encryption_payload_encodings
[] = {
134 /* 1 Byte next payload type, stored in the field next_payload */
135 { U_INT_8
, offsetof(private_encryption_payload_t
, next_payload
) },
136 /* the critical bit */
137 { FLAG
, offsetof(private_encryption_payload_t
, critical
) },
138 /* 7 Bit reserved bits, nowhere stored */
146 /* Length of the whole encryption payload*/
147 { PAYLOAD_LENGTH
, offsetof(private_encryption_payload_t
, payload_length
) },
148 /* encrypted data, stored in a chunk. contains iv, data, padding */
149 { ENCRYPTED_DATA
, offsetof(private_encryption_payload_t
, encrypted
) },
154 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
155 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156 ! Next Payload !C! RESERVED ! Payload Length !
157 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158 ! Initialization Vector !
159 ! (length is block size for encryption algorithm) !
160 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 ! Encrypted IKE Payloads !
162 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 ! ! Padding (0-255 octets) !
164 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
166 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167 ~ Integrity Checksum Data ~
168 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
172 * Implementation of payload_t.verify.
174 static status_t
verify(private_encryption_payload_t
*this)
180 * Implementation of payload_t.get_encoding_rules.
182 static void get_encoding_rules(private_encryption_payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
184 *rules
= encryption_payload_encodings
;
185 *rule_count
= sizeof(encryption_payload_encodings
) / sizeof(encoding_rule_t
);
189 * Implementation of payload_t.get_type.
191 static payload_type_t
get_type(private_encryption_payload_t
*this)
197 * Implementation of payload_t.get_next_type.
199 static payload_type_t
get_next_type(private_encryption_payload_t
*this)
201 /* returns first contained payload here */
202 return (this->next_payload
);
206 * Implementation of payload_t.set_next_type.
208 static void set_next_type(private_encryption_payload_t
*this, payload_type_t type
)
210 /* set next type is not allowed, since this payload MUST be the last one
211 * and so nothing is done in here*/
215 * Implementation of payload_t.get_length.
217 static size_t get_length(private_encryption_payload_t
*this)
219 this->compute_length(this);
220 return this->payload_length
;
224 * Implementation of payload_t.create_payload_iterator.
226 static iterator_t
*create_payload_iterator (private_encryption_payload_t
*this, bool forward
)
228 return (this->payloads
->create_iterator(this->payloads
, forward
));
232 * Implementation of payload_t.add_payload.
234 static void add_payload(private_encryption_payload_t
*this, payload_t
*payload
)
236 payload_t
*last_payload
;
237 if (this->payloads
->get_count(this->payloads
) > 0)
239 this->payloads
->get_last(this->payloads
,(void **) &last_payload
);
240 last_payload
->set_next_type(last_payload
, payload
->get_type(payload
));
244 this->next_payload
= payload
->get_type(payload
);
246 payload
->set_next_type(payload
, NO_PAYLOAD
);
247 this->payloads
->insert_last(this->payloads
, (void*)payload
);
248 this->compute_length(this);
252 * Implementation of encryption_payload_t.remove_first_payload.
254 static status_t
remove_first_payload(private_encryption_payload_t
*this, payload_t
**payload
)
256 return this->payloads
->remove_first(this->payloads
, (void**)payload
);
260 * Implementation of encryption_payload_t.get_payload_count.
262 static size_t get_payload_count(private_encryption_payload_t
*this)
264 return this->payloads
->get_count(this->payloads
);
269 * Implementation of encryption_payload_t.encrypt.
271 static status_t
encrypt(private_encryption_payload_t
*this)
273 chunk_t iv
, padding
, to_crypt
, result
;
274 randomizer_t
*randomizer
;
278 if (this->signer
== NULL
|| this->crypter
== NULL
)
280 this->logger
->log(this->logger
, ERROR
, "could not encrypt, signer/crypter not set");
281 return INVALID_STATE
;
284 /* for random data in iv and padding */
285 randomizer
= randomizer_create();
288 /* build payload chunk */
289 this->generate(this);
291 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "encrypting payloads");
292 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data to encrypt", this->decrypted
);
295 block_size
= this->crypter
->get_block_size(this->crypter
);
296 padding
.len
= block_size
- ((this->decrypted
.len
+ 1) % block_size
);
297 status
= randomizer
->allocate_pseudo_random_bytes(randomizer
, padding
.len
, &padding
);
298 if (status
!= SUCCESS
)
300 randomizer
->destroy(randomizer
);
304 /* concatenate payload data, padding, padding len */
305 to_crypt
.len
= this->decrypted
.len
+ padding
.len
+ 1;
306 to_crypt
.ptr
= malloc(to_crypt
.len
);
308 memcpy(to_crypt
.ptr
, this->decrypted
.ptr
, this->decrypted
.len
);
309 memcpy(to_crypt
.ptr
+ this->decrypted
.len
, padding
.ptr
, padding
.len
);
310 *(to_crypt
.ptr
+ to_crypt
.len
- 1) = padding
.len
;
314 status
= randomizer
->allocate_pseudo_random_bytes(randomizer
, iv
.len
, &iv
);
315 randomizer
->destroy(randomizer
);
316 if (status
!= SUCCESS
)
318 chunk_free(&to_crypt
);
319 chunk_free(&padding
);
323 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data before encryption with padding", to_crypt
);
325 /* encrypt to_crypt chunk */
326 free(this->encrypted
.ptr
);
327 status
= this->crypter
->encrypt(this->crypter
, to_crypt
, iv
, &result
);
330 if (status
!= SUCCESS
)
332 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "encryption failed");
336 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after encryption", result
);
339 /* build encrypted result with iv and signature */
340 this->encrypted
.len
= iv
.len
+ result
.len
+ this->signer
->get_block_size(this->signer
);
341 free(this->encrypted
.ptr
);
342 this->encrypted
.ptr
= malloc(this->encrypted
.len
);
344 /* fill in result, signature is left out */
345 memcpy(this->encrypted
.ptr
, iv
.ptr
, iv
.len
);
346 memcpy(this->encrypted
.ptr
+ iv
.len
, result
.ptr
, result
.len
);
350 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after encryption with IV and (invalid) signature", this->encrypted
);
356 * Implementation of encryption_payload_t.encrypt.
358 static status_t
decrypt(private_encryption_payload_t
*this)
360 chunk_t iv
, concatenated
;
361 u_int8_t padding_length
;
365 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "decrypting encryption payload");
366 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data before decryption with IV and (invalid) signature", this->encrypted
);
369 if (this->signer
== NULL
|| this->crypter
== NULL
)
371 this->logger
->log(this->logger
, ERROR
, "could not decrypt, no crypter/signer set");
372 return INVALID_STATE
;
376 iv
.len
= this->crypter
->get_block_size(this->crypter
);
378 iv
.ptr
= this->encrypted
.ptr
;
380 /* point concatenated to data + padding + padding_length*/
381 concatenated
.ptr
= this->encrypted
.ptr
+ iv
.len
;
382 concatenated
.len
= this->encrypted
.len
- iv
.len
- this->signer
->get_block_size(this->signer
);
384 /* check the size of input:
385 * concatenated must be at least on block_size of crypter
387 if (concatenated
.len
< iv
.len
)
389 this->logger
->log(this->logger
, ERROR
, "could not decrypt, invalid input");
393 /* free previus data, if any */
394 free(this->decrypted
.ptr
);
396 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data before decryption", concatenated
);
398 status
= this->crypter
->decrypt(this->crypter
, concatenated
, iv
, &(this->decrypted
));
399 if (status
!= SUCCESS
)
401 this->logger
->log(this->logger
, ERROR
, "could not decrypt, decryption failed");
404 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after decryption with padding", this->decrypted
);
407 /* get padding length, sits just bevore signature */
408 padding_length
= *(this->decrypted
.ptr
+ this->decrypted
.len
- 1);
409 /* add one byte to the padding length, since the padding_length field is not included */
411 this->decrypted
.len
-= padding_length
;
413 /* check size again */
414 if (padding_length
> concatenated
.len
|| this->decrypted
.len
< 0)
416 this->logger
->log(this->logger
, ERROR
, "decryption failed, invalid padding length found. Invalid key?");
417 /* decryption failed :-/ */
422 this->decrypted
.ptr
= realloc(this->decrypted
.ptr
, this->decrypted
.len
);
423 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after decryption without padding", this->decrypted
);
424 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "decryption successful, trying to parse content");
425 return (this->parse(this));
429 * Implementation of encryption_payload_t.set_transforms.
431 static void set_transforms(private_encryption_payload_t
*this, crypter_t
* crypter
, signer_t
* signer
)
433 this->signer
= signer
;
434 this->crypter
= crypter
;
438 * Implementation of encryption_payload_t.build_signature.
440 static status_t
build_signature(private_encryption_payload_t
*this, chunk_t data
)
442 chunk_t data_without_sig
= data
;
445 if (this->signer
== NULL
)
447 this->logger
->log(this->logger
, ERROR
, "unable to build signature, no signer set");
448 return INVALID_STATE
;
451 sig
.len
= this->signer
->get_block_size(this->signer
);
452 data_without_sig
.len
-= sig
.len
;
453 sig
.ptr
= data
.ptr
+ data_without_sig
.len
;
454 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "building signature");
455 this->signer
->get_signature(this->signer
, data_without_sig
, sig
.ptr
);
460 * Implementation of encryption_payload_t.verify_signature.
462 static status_t
verify_signature(private_encryption_payload_t
*this, chunk_t data
)
464 chunk_t sig
, data_without_sig
;
467 if (this->signer
== NULL
)
469 this->logger
->log(this->logger
, ERROR
, "unable to verify signature, no signer set");
470 return INVALID_STATE
;
472 /* find signature in data chunk */
473 sig
.len
= this->signer
->get_block_size(this->signer
);
474 if (data
.len
<= sig
.len
)
476 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "unable to verify signature, invalid input");
479 sig
.ptr
= data
.ptr
+ data
.len
- sig
.len
;
482 data_without_sig
.len
= data
.len
- sig
.len
;
483 data_without_sig
.ptr
= data
.ptr
;
484 valid
= this->signer
->verify_signature(this->signer
, data_without_sig
, sig
);
488 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "signature verification failed");
492 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "signature verification successful");
497 * Implementation of private_encryption_payload_t.generate.
499 static void generate(private_encryption_payload_t
*this)
501 payload_t
*current_payload
, *next_payload
;
502 generator_t
*generator
;
503 iterator_t
*iterator
;
505 /* recalculate length before generating */
506 this->compute_length(this);
508 /* create iterator */
509 iterator
= this->payloads
->create_iterator(this->payloads
, TRUE
);
511 /* get first payload */
512 if (iterator
->has_next(iterator
))
514 iterator
->current(iterator
, (void**)¤t_payload
);
515 this->next_payload
= current_payload
->get_type(current_payload
);
520 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "generating contained payloads, but no available");
521 free(this->decrypted
.ptr
);
522 this->decrypted
= CHUNK_INITIALIZER
;
523 iterator
->destroy(iterator
);
527 generator
= generator_create();
529 /* build all payload, except last */
530 while(iterator
->has_next(iterator
))
532 iterator
->current(iterator
, (void**)&next_payload
);
533 current_payload
->set_next_type(current_payload
, next_payload
->get_type(next_payload
));
534 generator
->generate_payload(generator
, current_payload
);
535 current_payload
= next_payload
;
537 iterator
->destroy(iterator
);
539 /* build last payload */
540 current_payload
->set_next_type(current_payload
, NO_PAYLOAD
);
541 generator
->generate_payload(generator
, current_payload
);
543 /* free already generated data */
544 free(this->decrypted
.ptr
);
546 generator
->write_to_chunk(generator
, &(this->decrypted
));
547 generator
->destroy(generator
);
548 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "successfully generated content in encrpytion payload");
552 * Implementation of private_encryption_payload_t.parse.
554 static status_t
parse(private_encryption_payload_t
*this)
558 payload_type_t current_payload_type
;
560 /* build a parser on the decrypted data */
561 parser
= parser_create(this->decrypted
);
563 current_payload_type
= this->next_payload
;
564 /* parse all payloads */
565 while (current_payload_type
!= NO_PAYLOAD
)
567 payload_t
*current_payload
;
569 status
= parser
->parse_payload(parser
, current_payload_type
, (payload_t
**)¤t_payload
);
570 if (status
!= SUCCESS
)
572 parser
->destroy(parser
);
576 status
= current_payload
->verify(current_payload
);
577 if (status
!= SUCCESS
)
579 this->logger
->log(this->logger
, ERROR
, "%s verification failed",
580 mapping_find(payload_type_m
,current_payload
->get_type(current_payload
)));
581 current_payload
->destroy(current_payload
);
582 parser
->destroy(parser
);
586 /* get next payload type */
587 current_payload_type
= current_payload
->get_next_type(current_payload
);
589 this->payloads
->insert_last(this->payloads
,current_payload
);
591 parser
->destroy(parser
);
592 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "succesfully parsed content of encryption payload");
597 * Implementation of private_encryption_payload_t.compute_length.
599 static void compute_length(private_encryption_payload_t
*this)
601 iterator_t
*iterator
;
602 size_t block_size
, length
= 0;
603 iterator
= this->payloads
->create_iterator(this->payloads
, TRUE
);
605 /* count payload length */
606 while (iterator
->has_next(iterator
))
608 payload_t
*current_payload
;
609 iterator
->current(iterator
, (void **) ¤t_payload
);
610 length
+= current_payload
->get_length(current_payload
);
612 iterator
->destroy(iterator
);
614 if (this->crypter
&& this->signer
)
616 /* append one byte for padding length */
619 block_size
= this->crypter
->get_block_size(this->crypter
);
620 length
+= block_size
- length
% block_size
;
622 length
+= block_size
;
624 length
+= this->signer
->get_block_size(this->signer
);
626 length
+= ENCRYPTION_PAYLOAD_HEADER_LENGTH
;
627 this->payload_length
= length
;
632 * Implementation of payload_t.destroy.
634 static void destroy(private_encryption_payload_t
*this)
636 /* all proposals are getting destroyed */
637 while (this->payloads
->get_count(this->payloads
) > 0)
639 payload_t
*current_payload
;
640 this->payloads
->remove_last(this->payloads
,(void **)¤t_payload
);
641 current_payload
->destroy(current_payload
);
643 this->payloads
->destroy(this->payloads
);
644 free(this->encrypted
.ptr
);
645 free(this->decrypted
.ptr
);
650 * Described in header
652 encryption_payload_t
*encryption_payload_create()
654 private_encryption_payload_t
*this = malloc_thing(private_encryption_payload_t
);
656 /* payload_t interface functions */
657 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
658 this->public.payload_interface
.get_encoding_rules
= (void (*) (payload_t
*, encoding_rule_t
**, size_t *) ) get_encoding_rules
;
659 this->public.payload_interface
.get_length
= (size_t (*) (payload_t
*)) get_length
;
660 this->public.payload_interface
.get_next_type
= (payload_type_t (*) (payload_t
*)) get_next_type
;
661 this->public.payload_interface
.set_next_type
= (void (*) (payload_t
*,payload_type_t
)) set_next_type
;
662 this->public.payload_interface
.get_type
= (payload_type_t (*) (payload_t
*)) get_type
;
663 this->public.payload_interface
.destroy
= (void (*) (payload_t
*))destroy
;
665 /* public functions */
666 this->public.create_payload_iterator
= (iterator_t
* (*) (encryption_payload_t
*,bool)) create_payload_iterator
;
667 this->public.add_payload
= (void (*) (encryption_payload_t
*,payload_t
*)) add_payload
;
668 this->public.remove_first_payload
= (status_t (*)(encryption_payload_t
*, payload_t
**)) remove_first_payload
;
669 this->public.get_payload_count
= (size_t (*)(encryption_payload_t
*)) get_payload_count
;
671 this->public.encrypt
= (status_t (*) (encryption_payload_t
*)) encrypt
;
672 this->public.decrypt
= (status_t (*) (encryption_payload_t
*)) decrypt
;
673 this->public.set_transforms
= (void (*) (encryption_payload_t
*,crypter_t
*,signer_t
*)) set_transforms
;
674 this->public.build_signature
= (status_t (*) (encryption_payload_t
*, chunk_t
)) build_signature
;
675 this->public.verify_signature
= (status_t (*) (encryption_payload_t
*, chunk_t
)) verify_signature
;
676 this->public.destroy
= (void (*) (encryption_payload_t
*)) destroy
;
678 /* private functions */
679 this->compute_length
= compute_length
;
680 this->generate
= generate
;
682 this->logger
= logger_manager
->get_logger(logger_manager
, ENCRYPTION_PAYLOAD
);
684 /* set default values of the fields */
685 this->critical
= FALSE
;
686 this->next_payload
= NO_PAYLOAD
;
687 this->payload_length
= ENCRYPTION_PAYLOAD_HEADER_LENGTH
;
688 this->encrypted
= CHUNK_INITIALIZER
;
689 this->decrypted
= CHUNK_INITIALIZER
;
691 this->crypter
= NULL
;
692 this->payloads
= linked_list_create();
694 return (&(this->public));