2 * @file encryption_payload.c
4 * @brief Implementation of encryption_payload_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 #include "encryption_payload.h"
29 #include <encoding/payloads/encodings.h>
30 #include <utils/linked_list.h>
31 #include <utils/logger.h>
32 #include <encoding/generator.h>
33 #include <encoding/parser.h>
34 #include <utils/iterator.h>
35 #include <utils/randomizer.h>
36 #include <crypto/signers/signer.h>
41 typedef struct private_encryption_payload_t private_encryption_payload_t
;
44 * Private data of an encryption_payload_t' Object.
47 struct private_encryption_payload_t
{
50 * Public encryption_payload_t interface.
52 encryption_payload_t
public;
55 * There is no next payload for an encryption payload,
56 * since encryption payload MUST be the last one.
57 * next_payload means here the first payload of the
58 * contained, encrypted payload.
60 u_int8_t next_payload
;
68 * Length of this payload
70 u_int16_t payload_length
;
73 * Chunk containing the iv, data, padding,
74 * and (an eventually not calculated) signature.
79 * Chunk containing the data in decrypted (unpadded) form.
84 * Signer set by set_signer.
89 * Crypter, supplied by encrypt/decrypt
94 * Contained payloads of this encrpytion_payload.
96 linked_list_t
*payloads
;
99 * logger for this payload, uses MESSAGE context
104 * @brief Computes the length of this payload.
106 * @param this calling private_encryption_payload_t object
108 void (*compute_length
) (private_encryption_payload_t
*this);
111 * @brief Generate payloads (unencrypted) in chunk decrypted.
113 * @param this calling private_encryption_payload_t object
115 void (*generate
) (private_encryption_payload_t
*this);
118 * @brief Parse payloads from a (unencrypted) chunk.
120 * @param this calling private_encryption_payload_t object
122 status_t (*parse
) (private_encryption_payload_t
*this);
126 * Encoding rules to parse or generate a IKEv2-Encryption Payload.
128 * The defined offsets are the positions in a object of type
129 * private_encryption_payload_t.
132 encoding_rule_t encryption_payload_encodings
[] = {
133 /* 1 Byte next payload type, stored in the field next_payload */
134 { U_INT_8
, offsetof(private_encryption_payload_t
, next_payload
) },
135 /* the critical bit */
136 { FLAG
, offsetof(private_encryption_payload_t
, critical
) },
137 /* 7 Bit reserved bits, nowhere stored */
145 /* Length of the whole encryption payload*/
146 { PAYLOAD_LENGTH
, offsetof(private_encryption_payload_t
, payload_length
) },
147 /* encrypted data, stored in a chunk. contains iv, data, padding */
148 { ENCRYPTED_DATA
, offsetof(private_encryption_payload_t
, encrypted
) },
153 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
154 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155 ! Next Payload !C! RESERVED ! Payload Length !
156 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157 ! Initialization Vector !
158 ! (length is block size for encryption algorithm) !
159 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160 ! Encrypted IKE Payloads !
161 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
162 ! ! Padding (0-255 octets) !
163 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
165 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 ~ Integrity Checksum Data ~
167 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171 * Implementation of payload_t.verify.
173 static status_t
verify(private_encryption_payload_t
*this)
179 * Implementation of payload_t.get_encoding_rules.
181 static void get_encoding_rules(private_encryption_payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
183 *rules
= encryption_payload_encodings
;
184 *rule_count
= sizeof(encryption_payload_encodings
) / sizeof(encoding_rule_t
);
188 * Implementation of payload_t.get_type.
190 static payload_type_t
get_type(private_encryption_payload_t
*this)
196 * Implementation of payload_t.get_next_type.
198 static payload_type_t
get_next_type(private_encryption_payload_t
*this)
200 /* returns first contained payload here */
201 return (this->next_payload
);
205 * Implementation of payload_t.set_next_type.
207 static void set_next_type(private_encryption_payload_t
*this, payload_type_t type
)
209 /* set next type is not allowed, since this payload MUST be the last one
210 * and so nothing is done in here*/
214 * Implementation of payload_t.get_length.
216 static size_t get_length(private_encryption_payload_t
*this)
218 this->compute_length(this);
219 return this->payload_length
;
223 * Implementation of payload_t.create_payload_iterator.
225 static iterator_t
*create_payload_iterator (private_encryption_payload_t
*this, bool forward
)
227 return (this->payloads
->create_iterator(this->payloads
, forward
));
231 * Implementation of payload_t.add_payload.
233 static void add_payload(private_encryption_payload_t
*this, payload_t
*payload
)
235 payload_t
*last_payload
;
236 if (this->payloads
->get_count(this->payloads
) > 0)
238 this->payloads
->get_last(this->payloads
,(void **) &last_payload
);
239 last_payload
->set_next_type(last_payload
, payload
->get_type(payload
));
243 this->next_payload
= payload
->get_type(payload
);
245 payload
->set_next_type(payload
, NO_PAYLOAD
);
246 this->payloads
->insert_last(this->payloads
, (void*)payload
);
247 this->compute_length(this);
251 * Implementation of encryption_payload_t.remove_first_payload.
253 static status_t
remove_first_payload(private_encryption_payload_t
*this, payload_t
**payload
)
255 return this->payloads
->remove_first(this->payloads
, (void**)payload
);
259 * Implementation of encryption_payload_t.get_payload_count.
261 static size_t get_payload_count(private_encryption_payload_t
*this)
263 return this->payloads
->get_count(this->payloads
);
268 * Implementation of encryption_payload_t.encrypt.
270 static status_t
encrypt(private_encryption_payload_t
*this)
272 chunk_t iv
, padding
, to_crypt
, result
;
273 randomizer_t
*randomizer
;
277 if (this->signer
== NULL
|| this->crypter
== NULL
)
279 this->logger
->log(this->logger
, ERROR
, "could not encrypt, signer/crypter not set");
280 return INVALID_STATE
;
283 /* for random data in iv and padding */
284 randomizer
= randomizer_create();
287 /* build payload chunk */
288 this->generate(this);
290 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "encrypting payloads");
291 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data to encrypt", this->decrypted
);
294 block_size
= this->crypter
->get_block_size(this->crypter
);
295 padding
.len
= block_size
- ((this->decrypted
.len
+ 1) % block_size
);
296 status
= randomizer
->allocate_pseudo_random_bytes(randomizer
, padding
.len
, &padding
);
297 if (status
!= SUCCESS
)
299 randomizer
->destroy(randomizer
);
303 /* concatenate payload data, padding, padding len */
304 to_crypt
.len
= this->decrypted
.len
+ padding
.len
+ 1;
305 to_crypt
.ptr
= malloc(to_crypt
.len
);
307 memcpy(to_crypt
.ptr
, this->decrypted
.ptr
, this->decrypted
.len
);
308 memcpy(to_crypt
.ptr
+ this->decrypted
.len
, padding
.ptr
, padding
.len
);
309 *(to_crypt
.ptr
+ to_crypt
.len
- 1) = padding
.len
;
313 status
= randomizer
->allocate_pseudo_random_bytes(randomizer
, iv
.len
, &iv
);
314 randomizer
->destroy(randomizer
);
315 if (status
!= SUCCESS
)
317 chunk_free(&to_crypt
);
318 chunk_free(&padding
);
322 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data before encryption with padding", to_crypt
);
324 /* encrypt to_crypt chunk */
325 free(this->encrypted
.ptr
);
326 status
= this->crypter
->encrypt(this->crypter
, to_crypt
, iv
, &result
);
329 if (status
!= SUCCESS
)
331 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "encryption failed");
335 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after encryption", result
);
338 /* build encrypted result with iv and signature */
339 this->encrypted
.len
= iv
.len
+ result
.len
+ this->signer
->get_block_size(this->signer
);
340 free(this->encrypted
.ptr
);
341 this->encrypted
.ptr
= malloc(this->encrypted
.len
);
343 /* fill in result, signature is left out */
344 memcpy(this->encrypted
.ptr
, iv
.ptr
, iv
.len
);
345 memcpy(this->encrypted
.ptr
+ iv
.len
, result
.ptr
, result
.len
);
349 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after encryption with IV and (invalid) signature", this->encrypted
);
355 * Implementation of encryption_payload_t.encrypt.
357 static status_t
decrypt(private_encryption_payload_t
*this)
359 chunk_t iv
, concatenated
;
360 u_int8_t padding_length
;
364 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "decrypting encryption payload");
365 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data before decryption with IV and (invalid) signature", this->encrypted
);
368 if (this->signer
== NULL
|| this->crypter
== NULL
)
370 this->logger
->log(this->logger
, ERROR
, "could not decrypt, no crypter/signer set");
371 return INVALID_STATE
;
375 iv
.len
= this->crypter
->get_block_size(this->crypter
);
377 iv
.ptr
= this->encrypted
.ptr
;
379 /* point concatenated to data + padding + padding_length*/
380 concatenated
.ptr
= this->encrypted
.ptr
+ iv
.len
;
381 concatenated
.len
= this->encrypted
.len
- iv
.len
- this->signer
->get_block_size(this->signer
);
383 /* check the size of input:
384 * concatenated must be at least on block_size of crypter
386 if (concatenated
.len
< iv
.len
)
388 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "could not decrypt, invalid input");
392 /* free previus data, if any */
393 free(this->decrypted
.ptr
);
395 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data before decryption", concatenated
);
397 status
= this->crypter
->decrypt(this->crypter
, concatenated
, iv
, &(this->decrypted
));
398 if (status
!= SUCCESS
)
400 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "could not decrypt, decryption failed");
403 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after decryption with padding", this->decrypted
);
406 /* get padding length, sits just bevore signature */
407 padding_length
= *(this->decrypted
.ptr
+ this->decrypted
.len
- 1);
408 /* add one byte to the padding length, since the padding_length field is not included */
410 this->decrypted
.len
-= padding_length
;
412 /* check size again */
413 if (padding_length
> concatenated
.len
|| this->decrypted
.len
< 0)
415 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "decryption failed, invalid padding length found. Invalid key?");
416 /* decryption failed :-/ */
421 this->decrypted
.ptr
= realloc(this->decrypted
.ptr
, this->decrypted
.len
);
422 this->logger
->log_chunk(this->logger
, RAW
|LEVEL2
, "data after decryption without padding", this->decrypted
);
423 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "decryption successful, trying to parse content");
424 return (this->parse(this));
428 * Implementation of encryption_payload_t.set_transforms.
430 static void set_transforms(private_encryption_payload_t
*this, crypter_t
* crypter
, signer_t
* signer
)
432 this->signer
= signer
;
433 this->crypter
= crypter
;
437 * Implementation of encryption_payload_t.build_signature.
439 static status_t
build_signature(private_encryption_payload_t
*this, chunk_t data
)
441 chunk_t data_without_sig
= data
;
444 if (this->signer
== NULL
)
446 this->logger
->log(this->logger
, ERROR
, "unable to build signature, no signer set");
447 return INVALID_STATE
;
450 sig
.len
= this->signer
->get_block_size(this->signer
);
451 data_without_sig
.len
-= sig
.len
;
452 sig
.ptr
= data
.ptr
+ data_without_sig
.len
;
453 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "building signature");
454 this->signer
->get_signature(this->signer
, data_without_sig
, sig
.ptr
);
459 * Implementation of encryption_payload_t.verify_signature.
461 static status_t
verify_signature(private_encryption_payload_t
*this, chunk_t data
)
463 chunk_t sig
, data_without_sig
;
466 if (this->signer
== NULL
)
468 this->logger
->log(this->logger
, ERROR
, "unable to verify signature, no signer set");
469 return INVALID_STATE
;
471 /* find signature in data chunk */
472 sig
.len
= this->signer
->get_block_size(this->signer
);
473 if (data
.len
<= sig
.len
)
475 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "unable to verify signature, invalid input");
478 sig
.ptr
= data
.ptr
+ data
.len
- sig
.len
;
481 data_without_sig
.len
= data
.len
- sig
.len
;
482 data_without_sig
.ptr
= data
.ptr
;
483 valid
= this->signer
->verify_signature(this->signer
, data_without_sig
, sig
);
487 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "signature verification failed");
491 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "signature verification successful");
496 * Implementation of private_encryption_payload_t.generate.
498 static void generate(private_encryption_payload_t
*this)
500 payload_t
*current_payload
, *next_payload
;
501 generator_t
*generator
;
502 iterator_t
*iterator
;
504 /* recalculate length before generating */
505 this->compute_length(this);
507 /* create iterator */
508 iterator
= this->payloads
->create_iterator(this->payloads
, TRUE
);
510 /* get first payload */
511 if (iterator
->has_next(iterator
))
513 iterator
->current(iterator
, (void**)¤t_payload
);
514 this->next_payload
= current_payload
->get_type(current_payload
);
519 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "generating contained payloads, but no available");
520 free(this->decrypted
.ptr
);
521 this->decrypted
= CHUNK_INITIALIZER
;
522 iterator
->destroy(iterator
);
526 generator
= generator_create();
528 /* build all payload, except last */
529 while(iterator
->has_next(iterator
))
531 iterator
->current(iterator
, (void**)&next_payload
);
532 current_payload
->set_next_type(current_payload
, next_payload
->get_type(next_payload
));
533 generator
->generate_payload(generator
, current_payload
);
534 current_payload
= next_payload
;
536 iterator
->destroy(iterator
);
538 /* build last payload */
539 current_payload
->set_next_type(current_payload
, NO_PAYLOAD
);
540 generator
->generate_payload(generator
, current_payload
);
542 /* free already generated data */
543 free(this->decrypted
.ptr
);
545 generator
->write_to_chunk(generator
, &(this->decrypted
));
546 generator
->destroy(generator
);
547 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "successfully generated content in encrpytion payload");
551 * Implementation of private_encryption_payload_t.parse.
553 static status_t
parse(private_encryption_payload_t
*this)
557 payload_type_t current_payload_type
;
559 /* check if there is decrypted data */
560 if (this->decrypted
.ptr
== NULL
)
562 this->logger
->log(this->logger
, ERROR
, "unable to parse, no input!");
563 return INVALID_STATE
;
566 /* build a parser on the decrypted data */
567 parser
= parser_create(this->decrypted
);
569 current_payload_type
= this->next_payload
;
570 /* parse all payloads */
571 while (current_payload_type
!= NO_PAYLOAD
)
573 payload_t
*current_payload
;
575 status
= parser
->parse_payload(parser
, current_payload_type
, (payload_t
**)¤t_payload
);
576 if (status
!= SUCCESS
)
578 parser
->destroy(parser
);
582 status
= current_payload
->verify(current_payload
);
583 if (status
!= SUCCESS
)
585 this->logger
->log(this->logger
, ERROR
|LEVEL1
, "%s verification failed: %s",
586 mapping_find(payload_type_m
,current_payload
->get_type(current_payload
)),
587 mapping_find(status_m
, status
));
588 current_payload
->destroy(current_payload
);
589 parser
->destroy(parser
);
593 /* get next payload type */
594 current_payload_type
= current_payload
->get_next_type(current_payload
);
596 this->payloads
->insert_last(this->payloads
,current_payload
);
598 parser
->destroy(parser
);
599 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "succesfully parsed content of encryption payload");
604 * Implementation of private_encryption_payload_t.compute_length.
606 static void compute_length(private_encryption_payload_t
*this)
608 iterator_t
*iterator
;
609 size_t block_size
, length
= 0;
610 iterator
= this->payloads
->create_iterator(this->payloads
, TRUE
);
612 /* count payload length */
613 while (iterator
->has_next(iterator
))
615 payload_t
*current_payload
;
616 iterator
->current(iterator
, (void **) ¤t_payload
);
617 length
+= current_payload
->get_length(current_payload
);
619 iterator
->destroy(iterator
);
621 if (this->crypter
&& this->signer
)
623 /* append one byte for padding length */
626 block_size
= this->crypter
->get_block_size(this->crypter
);
627 length
+= block_size
- length
% block_size
;
629 length
+= block_size
;
631 length
+= this->signer
->get_block_size(this->signer
);
633 length
+= ENCRYPTION_PAYLOAD_HEADER_LENGTH
;
634 this->payload_length
= length
;
639 * Implementation of payload_t.destroy.
641 static void destroy(private_encryption_payload_t
*this)
643 /* all proposals are getting destroyed */
644 while (this->payloads
->get_count(this->payloads
) > 0)
646 payload_t
*current_payload
;
647 this->payloads
->remove_last(this->payloads
,(void **)¤t_payload
);
648 current_payload
->destroy(current_payload
);
650 this->payloads
->destroy(this->payloads
);
651 free(this->encrypted
.ptr
);
652 free(this->decrypted
.ptr
);
657 * Described in header
659 encryption_payload_t
*encryption_payload_create()
661 private_encryption_payload_t
*this = malloc_thing(private_encryption_payload_t
);
663 /* payload_t interface functions */
664 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
665 this->public.payload_interface
.get_encoding_rules
= (void (*) (payload_t
*, encoding_rule_t
**, size_t *) ) get_encoding_rules
;
666 this->public.payload_interface
.get_length
= (size_t (*) (payload_t
*)) get_length
;
667 this->public.payload_interface
.get_next_type
= (payload_type_t (*) (payload_t
*)) get_next_type
;
668 this->public.payload_interface
.set_next_type
= (void (*) (payload_t
*,payload_type_t
)) set_next_type
;
669 this->public.payload_interface
.get_type
= (payload_type_t (*) (payload_t
*)) get_type
;
670 this->public.payload_interface
.destroy
= (void (*) (payload_t
*))destroy
;
672 /* public functions */
673 this->public.create_payload_iterator
= (iterator_t
* (*) (encryption_payload_t
*,bool)) create_payload_iterator
;
674 this->public.add_payload
= (void (*) (encryption_payload_t
*,payload_t
*)) add_payload
;
675 this->public.remove_first_payload
= (status_t (*)(encryption_payload_t
*, payload_t
**)) remove_first_payload
;
676 this->public.get_payload_count
= (size_t (*)(encryption_payload_t
*)) get_payload_count
;
678 this->public.encrypt
= (status_t (*) (encryption_payload_t
*)) encrypt
;
679 this->public.decrypt
= (status_t (*) (encryption_payload_t
*)) decrypt
;
680 this->public.set_transforms
= (void (*) (encryption_payload_t
*,crypter_t
*,signer_t
*)) set_transforms
;
681 this->public.build_signature
= (status_t (*) (encryption_payload_t
*, chunk_t
)) build_signature
;
682 this->public.verify_signature
= (status_t (*) (encryption_payload_t
*, chunk_t
)) verify_signature
;
683 this->public.destroy
= (void (*) (encryption_payload_t
*)) destroy
;
685 /* private functions */
686 this->compute_length
= compute_length
;
687 this->generate
= generate
;
689 this->logger
= logger_manager
->get_logger(logger_manager
, ENCRYPTION_PAYLOAD
);
691 /* set default values of the fields */
692 this->critical
= FALSE
;
693 this->next_payload
= NO_PAYLOAD
;
694 this->payload_length
= ENCRYPTION_PAYLOAD_HEADER_LENGTH
;
695 this->encrypted
= CHUNK_INITIALIZER
;
696 this->decrypted
= CHUNK_INITIALIZER
;
698 this->crypter
= NULL
;
699 this->payloads
= linked_list_create();
701 return (&(this->public));