generator rewritten (no memory allocation test anymore)
[strongswan.git] / Source / charon / encoding / payloads / encryption_payload.c
1 /**
2 * @file encryption_payload.c
3 *
4 * @brief Implementation of encryption_payload_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
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>.
16 *
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
20 * for more details.
21 */
22
23 /* offsetof macro */
24 #include <stddef.h>
25
26 #include "encryption_payload.h"
27
28 #include <encoding/payloads/encodings.h>
29 #include <utils/allocator.h>
30 #include <utils/linked_list.h>
31 #include <encoding/generator.h>
32 #include <encoding/parser.h>
33 #include <utils/iterator.h>
34 #include <utils/randomizer.h>
35 #include <transforms/signers/signer.h>
36
37
38
39
40 typedef struct private_encryption_payload_t private_encryption_payload_t;
41
42 /**
43 * Private data of an encryption_payload_t' Object
44 *
45 */
46 struct private_encryption_payload_t {
47 /**
48 * public encryption_payload_t interface
49 */
50 encryption_payload_t public;
51
52 /**
53 * There is no next payload for an encryption payload,
54 * since encryption payload MUST be the last one.
55 * next_payload means here the first payload of the
56 * contained, encrypted payload.
57 */
58 u_int8_t next_payload;
59
60 /**
61 * Critical flag
62 */
63 bool critical;
64
65 /**
66 * Length of this payload
67 */
68 u_int16_t payload_length;
69
70 /**
71 * initialization vector
72 */
73 chunk_t iv;
74
75 /**
76 * integrity checksum
77 */
78 chunk_t checksum;
79
80 /**
81 * chunk containing the iv, data, padding,
82 * and (an eventually not calculated) signature
83 */
84 chunk_t encrypted;
85
86 /**
87 * chunk containing the data in decrypted (unpadded) form
88 */
89 chunk_t decrypted;
90
91 /**
92 * signer set by set_signer
93 */
94 signer_t *signer;
95
96 /**
97 * Contained payloads of this encrpytion_payload
98 */
99 linked_list_t *payloads;
100
101 /**
102 * @brief Computes the length of this payload.
103 *
104 * @param this calling private_encryption_payload_t object
105 * @return
106 * SUCCESS in any case
107 */
108 status_t (*compute_length) (private_encryption_payload_t *this);
109
110 /**
111 * @brief Generate payloads (unencrypted) in chunk decrypted.
112 *
113 * @param this calling private_encryption_payload_t object
114 * @return
115 * SUCCESS in any case
116 */
117 status_t (*generate) (private_encryption_payload_t *this);
118 status_t (*parse) (private_encryption_payload_t *this);
119 };
120
121 /**
122 * Encoding rules to parse or generate a IKEv2-Encryption Payload
123 *
124 * The defined offsets are the positions in a object of type
125 * private_encryption_payload_t.
126 *
127 */
128 encoding_rule_t encryption_payload_encodings[] = {
129 /* 1 Byte next payload type, stored in the field next_payload */
130 { U_INT_8, offsetof(private_encryption_payload_t, next_payload) },
131 /* the critical bit */
132 { FLAG, offsetof(private_encryption_payload_t, critical) },
133 /* 7 Bit reserved bits, nowhere stored */
134 { RESERVED_BIT, 0 },
135 { RESERVED_BIT, 0 },
136 { RESERVED_BIT, 0 },
137 { RESERVED_BIT, 0 },
138 { RESERVED_BIT, 0 },
139 { RESERVED_BIT, 0 },
140 { RESERVED_BIT, 0 },
141 /* Length of the whole encryption payload*/
142 { PAYLOAD_LENGTH, offsetof(private_encryption_payload_t, payload_length) },
143 /* encrypted data, stored in a chunk. contains iv, data, padding */
144 { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) },
145 };
146
147 /*
148 1 2 3
149 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
150 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151 ! Next Payload !C! RESERVED ! Payload Length !
152 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
153 ! Initialization Vector !
154 ! (length is block size for encryption algorithm) !
155 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156 ! Encrypted IKE Payloads !
157 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158 ! ! Padding (0-255 octets) !
159 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
160 ! ! Pad Length !
161 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
162 ~ Integrity Checksum Data ~
163 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
164 */
165
166 /**
167 * Implements payload_t's verify function.
168 * See #payload_s.verify for description.
169 */
170 static status_t verify(private_encryption_payload_t *this)
171 {
172 // int proposal_number = 1;
173 status_t status;
174 // iterator_t *iterator;
175 // bool first = TRUE;
176 //
177 // if (this->critical)
178 // {
179 // /* critical bit set! */
180 // return FAILED;
181 // }
182 //
183 // /* check proposal numbering */
184 // status = this->proposals->create_iterator(this->proposals,&iterator,TRUE);
185 // if (status != SUCCESS)
186 // {
187 // return status;
188 // }
189 //
190 // while(iterator->has_next(iterator))
191 // {
192 // proposal_substructure_t *current_proposal;
193 // status = iterator->current(iterator,(void **)&current_proposal);
194 // {
195 // break;
196 // }
197 // if (current_proposal->get_proposal_number(current_proposal) > proposal_number)
198 // {
199 // if (first)
200 // {
201 // /* first number must be 1 */
202 // status = FAILED;
203 // break;
204 // }
205 //
206 // if (current_proposal->get_proposal_number(current_proposal) != (proposal_number + 1))
207 // {
208 // /* must be only one more then previous proposal */
209 // status = FAILED;
210 // break;
211 // }
212 // }
213 // else if (current_proposal->get_proposal_number(current_proposal) < proposal_number)
214 // {
215 // iterator->destroy(iterator);
216 // /* must not be smaller then proceeding one */
217 // status = FAILED;
218 // break;
219 // }
220 // first = FALSE;
221 // }
222 //
223 // iterator->destroy(iterator);
224 return status;
225 }
226
227 /**
228 * implements payload_t.destroy
229 */
230 static status_t destroy(private_encryption_payload_t *this)
231 {
232 /* all proposals are getting destroyed */
233 while (this->payloads->get_count(this->payloads) > 0)
234 {
235 payload_t *current_payload;
236 if (this->payloads->remove_last(this->payloads,(void **)&current_payload) != SUCCESS)
237 {
238 break;
239 }
240 current_payload->destroy(current_payload);
241 }
242 this->payloads->destroy(this->payloads);
243
244 allocator_free(this->iv.ptr);
245 allocator_free(this->encrypted.ptr);
246 allocator_free(this->decrypted.ptr);
247 allocator_free(this->checksum.ptr);
248 allocator_free(this);
249
250 return SUCCESS;
251 }
252
253 /**
254 * implements payload_t.get_encoding_rules
255 */
256 static status_t get_encoding_rules(private_encryption_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
257 {
258 *rules = encryption_payload_encodings;
259 *rule_count = sizeof(encryption_payload_encodings) / sizeof(encoding_rule_t);
260
261 return SUCCESS;
262 }
263
264 /**
265 * implements payload_t.get_type
266 */
267 static payload_type_t get_type(private_encryption_payload_t *this)
268 {
269 return ENCRYPTED;
270 }
271
272 /**
273 * implements payload_t.get_next_type
274 */
275 static payload_type_t get_next_type(private_encryption_payload_t *this)
276 {
277 /* returns first contained payload here */
278 return (this->next_payload);
279 }
280
281 /**
282 * implements payload_t.set_next_type
283 */
284 static status_t set_next_type(private_encryption_payload_t *this, payload_type_t type)
285 {
286 /* set next type is not allowed, since this payload MUST be the last one */
287 return FAILED;
288 }
289
290 /**
291 * implements payload_t.get_length
292 */
293 static size_t get_length(private_encryption_payload_t *this)
294 {
295 this->compute_length(this);
296 return this->payload_length;
297 }
298
299 /**
300 * implements encryption_payload_t.create_payload_iterator
301 */
302 static status_t create_payload_iterator (private_encryption_payload_t *this, iterator_t **iterator, bool forward)
303 {
304 return (this->payloads->create_iterator(this->payloads, iterator, forward));
305 }
306
307 /**
308 * implements encryption_payload_t.add_payload
309 */
310 static status_t add_payload(private_encryption_payload_t *this, payload_t *payload)
311 {
312 payload_t *last_payload;
313 if ((this->payloads->get_count(this->payloads) > 0) &&
314 (this->payloads->get_last(this->payloads,(void **) &last_payload) != SUCCESS))
315 {
316 return OUT_OF_RES;
317 }
318
319 if (this->payloads->insert_last(this->payloads, payload) != SUCCESS)
320 {
321 return OUT_OF_RES;
322 }
323 if (this->payloads->get_count(this->payloads) == 1)
324 {
325 this->next_payload = payload->get_type(payload);
326 }
327 else
328 {
329 last_payload->set_next_type(last_payload, payload->get_type(payload));
330 }
331 payload->set_next_type(payload, NO_PAYLOAD);
332 this->compute_length(this);
333 return SUCCESS;
334 }
335
336 /**
337 * implements encryption_payload_t.encrypt
338 */
339 static status_t encrypt(private_encryption_payload_t *this, crypter_t *crypter)
340 {
341 chunk_t iv, padding, concatenated;
342 randomizer_t *randomizer;
343 status_t status;
344
345 if (this->signer == NULL)
346 {
347 return INVALID_STATE;
348 }
349
350 /* for random data in iv and padding */
351 randomizer = randomizer_create();
352 if (randomizer == NULL)
353 {
354 return OUT_OF_RES;
355 }
356
357 /* build payload chunk */
358 status = this->generate(this);
359 if (status != SUCCESS)
360 {
361 randomizer->destroy(randomizer);
362 return status;
363 }
364
365 /* build padding */
366 padding.len = (this->decrypted.len + 1) % crypter->get_block_size(crypter);
367 status = randomizer->allocate_pseudo_random_bytes(randomizer, padding.len, &padding);
368 if (status != SUCCESS)
369 {
370 randomizer->destroy(randomizer);
371 return status;
372 }
373
374 /* concatenate payload data, padding, padding len */
375 concatenated.len = this->decrypted.len + padding.len + 1;
376 concatenated.ptr = allocator_alloc(concatenated.len);
377 if (concatenated.ptr == NULL)
378 {
379 randomizer->destroy(randomizer);
380 allocator_free(padding.ptr);
381 return OUT_OF_RES;
382 }
383 memcpy(concatenated.ptr, this->decrypted.ptr, this->decrypted.len);
384 memcpy(concatenated.ptr + this->decrypted.len, padding.ptr, padding.len);
385 *(concatenated.ptr + concatenated.len - 1) = padding.len;
386
387
388 /* build iv */
389 iv.len = crypter->get_block_size(crypter);
390 status = randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
391 randomizer->destroy(randomizer);
392 if (status != SUCCESS)
393 {
394 allocator_free(padding.ptr);
395 allocator_free(concatenated.ptr);
396 return status;
397 }
398
399
400 /* encrypt concatenated chunk */
401 allocator_free(this->encrypted.ptr);
402 status = crypter->encrypt(crypter, iv, concatenated, &(this->encrypted));
403 allocator_free(padding.ptr);
404 allocator_free(concatenated.ptr);
405 allocator_free(iv.ptr);
406 if (status != SUCCESS)
407 {
408 return status;
409 }
410
411 /* append an empty signature */
412 this->encrypted.len += this->signer->get_block_size(this->signer);
413 allocator_realloc(this->encrypted.ptr, this->encrypted.len);
414 if (this->encrypted.ptr == NULL)
415 {
416 return OUT_OF_RES;
417 }
418
419 return SUCCESS;
420 }
421
422 /**
423 * implements encryption_payload_t.decrypt
424 */
425 static status_t decrypt(private_encryption_payload_t *this, crypter_t *crypter)
426 {
427 chunk_t iv, concatenated;
428 u_int8_t padding_length;
429 status_t status;
430
431 if (this->signer == NULL)
432 {
433 return INVALID_STATE;
434 }
435
436 /* get IV */
437 iv.len = crypter->get_block_size(crypter);
438 iv.ptr = this->encrypted.ptr;
439
440 /* point concatenated to data + padding + padding_length*/
441 concatenated.ptr = this->encrypted.ptr + iv.len;
442 concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
443
444 /* check the size of input:
445 * concatenated must be at least on block_size of crypter
446 */
447 if (concatenated.len < iv.len)
448 {
449 return FAILED;
450 }
451
452 /* free previus data, if any */
453 allocator_free(this->decrypted.ptr);
454
455 status = crypter->decrypt(crypter, iv, concatenated, &(this->decrypted));
456 if (status != SUCCESS)
457 {
458 return FAILED;
459 }
460
461 /* get padding length, sits just bevore signature */
462 padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
463 this->decrypted.len -= padding_length;
464
465 /* check size again */
466 if (padding_length > concatenated.len || this->decrypted.len < 0)
467 {
468 /* decryption failed :-/ */
469 return FAILED;
470 }
471
472 /* free padding */
473 this->decrypted.ptr = allocator_realloc(this->decrypted.ptr, this->decrypted.len);
474 if (this->decrypted.ptr == NULL)
475 {
476 return OUT_OF_RES;
477 }
478
479 return SUCCESS;
480 }
481
482 /**
483 * implements encryption_payload_t.set_signer
484 */
485 static status_t set_signer(private_encryption_payload_t *this, signer_t* signer)
486 {
487 this->signer = signer;
488 return SUCCESS;
489 }
490
491 /**
492 * implements encryption_payload_t.build_signature
493 */
494 static status_t build_signature(private_encryption_payload_t *this, chunk_t data)
495 {
496 chunk_t data_without_sig = data;
497 chunk_t sig;
498
499 if (this->signer == NULL)
500 {
501 return INVALID_STATE;
502 }
503
504 sig.len = this->signer->get_block_size(this->signer);
505 data_without_sig.len -= sig.len;
506 sig.ptr = data.ptr + data_without_sig.len;
507 this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
508 return SUCCESS;
509 }
510
511 /**
512 * implements encryption_payload_t.verify_signature
513 */
514 static status_t verify_signature(private_encryption_payload_t *this, chunk_t data)
515 {
516 chunk_t sig, data_without_sig;
517 bool valid;
518
519 if (this->signer == NULL)
520 {
521 return INVALID_STATE;
522 }
523 /* find signature in data chunk */
524 sig.len = this->signer->get_block_size(this->signer);
525 if (data.len <= sig.len)
526 {
527 return FAILED;
528 }
529 sig.ptr = data.ptr + data.len - sig.len;
530
531 /* verify it */
532 data_without_sig.len = data.len - sig.len;
533 data_without_sig.ptr = data.ptr;
534 this->signer->verify_signature(this->signer, data_without_sig, sig, &valid);
535
536 if (!valid)
537 {
538 return FAILED;
539 }
540
541 return SUCCESS;
542 }
543
544 /**
545 * implements private_encryption_payload_t.generate
546 */
547 static status_t generate(private_encryption_payload_t *this)
548 {
549 status_t status;
550 payload_t *current_payload, *next_payload;
551 generator_t *generator;
552 iterator_t *iterator;
553
554 /* create iterator */
555 status = this->payloads->create_iterator(this->payloads, &iterator, TRUE);
556 if (status != SUCCESS)
557 {
558 return status;
559 }
560
561 /* get first payload */
562 if (iterator->has_next(iterator))
563 {
564 iterator->current(iterator, (void**)&current_payload);
565 this->next_payload = current_payload->get_type(current_payload);
566 }
567 else
568 {
569 /* no paylads? */
570 allocator_free(this->decrypted.ptr);
571 this->decrypted = CHUNK_INITIALIZER;
572 iterator->destroy(iterator);
573 return SUCCESS;
574 }
575
576 generator = generator_create();
577 if (generator == NULL)
578 {
579 iterator->destroy(iterator);
580 return OUT_OF_RES;
581 }
582
583 /* build all payload, except last */
584 while(iterator->has_next(iterator))
585 {
586 iterator->current(iterator, (void**)&next_payload);
587 current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
588
589 generator->generate_payload(generator, current_payload);
590 current_payload = next_payload;
591 }
592 iterator->destroy(iterator);
593
594 /* build last payload */
595 current_payload->set_next_type(current_payload, NO_PAYLOAD);
596 generator->generate_payload(generator, current_payload);
597
598 /* free already generated data */
599 allocator_free(this->decrypted.ptr);
600
601 generator->write_to_chunk(generator, &(this->decrypted));
602 generator->destroy(generator);
603 return SUCCESS;
604 }
605
606 static status_t parse(private_encryption_payload_t *this)
607 {
608 parser_t *parser;
609 status_t status;
610 payload_type_t current_payload_type;
611
612 /* check if there is decrypted data */
613 if (this->decrypted.ptr == NULL)
614 {
615 return INVALID_STATE;
616 }
617
618 /* build a parser on the decrypted data */
619 parser = parser_create(this->decrypted);
620 if (parser == NULL)
621 {
622 return OUT_OF_RES;
623 }
624
625
626 current_payload_type = this->next_payload;
627 /* parse all payloads */
628 while (current_payload_type != NO_PAYLOAD)
629 {
630 payload_t *current_payload;
631
632 status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
633 if (status != SUCCESS)
634 {
635 return PARSE_ERROR;
636 }
637
638 status = current_payload->verify(current_payload);
639 if (status != SUCCESS)
640 {
641 return VERIFY_ERROR;
642 }
643
644 /* get next payload type */
645 current_payload_type = current_payload->get_next_type(current_payload);
646
647 status = this->payloads->insert_last(this->payloads,current_payload);
648 if (status != SUCCESS)
649 {
650 return OUT_OF_RES;
651 }
652 }
653 return SUCCESS;
654 }
655
656 /**
657 * implements private_encryption_payload_t.compute_length
658 */
659 static status_t compute_length(private_encryption_payload_t *this)
660 {
661 iterator_t *iterator;
662 status_t status;
663 size_t length = ENCRYPTION_PAYLOAD_HEADER_LENGTH;
664 status = this->payloads->create_iterator(this->payloads, &iterator, TRUE);
665 if (status != SUCCESS)
666 {
667 return status;
668 }
669 while (iterator->has_next(iterator))
670 {
671 payload_t *current_payload;
672 iterator->current(iterator, (void **) &current_payload);
673 length += current_payload->get_length(current_payload);
674 }
675 iterator->destroy(iterator);
676
677 this->payload_length = length;
678
679 return SUCCESS;
680 }
681
682 /*
683 * Described in header
684 */
685 encryption_payload_t *encryption_payload_create()
686 {
687 private_encryption_payload_t *this = allocator_alloc_thing(private_encryption_payload_t);
688 if (this == NULL)
689 {
690 return NULL;
691 }
692
693 /* payload_t interface functions */
694 this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
695 this->public.payload_interface.get_encoding_rules = (status_t (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
696 this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
697 this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
698 this->public.payload_interface.set_next_type = (status_t (*) (payload_t *,payload_type_t)) set_next_type;
699 this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
700 this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy;
701
702 /* public functions */
703 this->public.create_payload_iterator = (status_t (*) (encryption_payload_t *,iterator_t **,bool)) create_payload_iterator;
704 this->public.add_payload = (status_t (*) (encryption_payload_t *,payload_t *)) add_payload;
705 this->public.encrypt = (status_t (*) (encryption_payload_t *, crypter_t*)) encrypt;
706 this->public.decrypt = (status_t (*) (encryption_payload_t *, crypter_t*)) decrypt;
707 this->public.set_signer = (status_t (*) (encryption_payload_t *,signer_t*)) set_signer;
708 this->public.build_signature = (status_t (*) (encryption_payload_t*, chunk_t)) build_signature;
709 this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature;
710 this->public.destroy = (status_t (*) (encryption_payload_t *)) destroy;
711
712 /* private functions */
713 this->compute_length = compute_length;
714 this->generate = generate;
715 this->parse = parse;
716
717 /* set default values of the fields */
718 this->critical = TRUE;
719 this->next_payload = NO_PAYLOAD;
720 this->payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH;
721 this->iv = CHUNK_INITIALIZER;
722 this->encrypted = CHUNK_INITIALIZER;
723 this->decrypted = CHUNK_INITIALIZER;
724 this->checksum = CHUNK_INITIALIZER;
725 this->signer = NULL;
726
727 this->payloads = linked_list_create();
728
729 if (this->payloads == NULL)
730 {
731 allocator_free(this);
732 return NULL;
733 }
734 return (&(this->public));
735 }
736
737