ike: Only parse payloads valid for the current IKE version
[strongswan.git] / src / libcharon / encoding / payloads / encrypted_payload.c
1 /*
2 * Copyright (C) 2011-2014 Tobias Brunner
3 * Copyright (C) 2005-2010 Martin Willi
4 * Copyright (C) 2010 revosec AG
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include <stddef.h>
20 #include <string.h>
21
22 #include "encrypted_payload.h"
23 #include "encrypted_fragment_payload.h"
24
25 #include <daemon.h>
26 #include <encoding/payloads/encodings.h>
27 #include <collections/linked_list.h>
28 #include <encoding/parser.h>
29
30 typedef struct private_encrypted_payload_t private_encrypted_payload_t;
31 typedef struct private_encrypted_fragment_payload_t private_encrypted_fragment_payload_t;
32
33 struct private_encrypted_payload_t {
34
35 /**
36 * Public encrypted_payload_t interface.
37 */
38 encrypted_payload_t public;
39
40 /**
41 * There is no next payload for an encrypted payload,
42 * since encrypted payload MUST be the last one.
43 * next_payload means here the first payload of the
44 * contained, encrypted payload.
45 */
46 u_int8_t next_payload;
47
48 /**
49 * Flags, including reserved bits
50 */
51 u_int8_t flags;
52
53 /**
54 * Length of this payload
55 */
56 u_int16_t payload_length;
57
58 /**
59 * Chunk containing the IV, plain, padding and ICV.
60 */
61 chunk_t encrypted;
62
63 /**
64 * AEAD transform to use
65 */
66 aead_t *aead;
67
68 /**
69 * Contained payloads
70 */
71 linked_list_t *payloads;
72
73 /**
74 * Type of payload, PLV2_ENCRYPTED or PLV1_ENCRYPTED
75 */
76 payload_type_t type;
77 };
78
79 struct private_encrypted_fragment_payload_t {
80
81 /**
82 * Public interface.
83 */
84 encrypted_fragment_payload_t public;
85
86 /**
87 * The first fragment contains the type of the first payload contained in
88 * the original encrypted payload, for all other fragments it MUST be set
89 * to zero.
90 */
91 u_int8_t next_payload;
92
93 /**
94 * Flags, including reserved bits
95 */
96 u_int8_t flags;
97
98 /**
99 * Length of this payload
100 */
101 u_int16_t payload_length;
102
103 /**
104 * Chunk containing the IV, plain, padding and ICV.
105 */
106 chunk_t encrypted;
107
108 /**
109 * Fragment number
110 */
111 u_int16_t fragment_number;
112
113 /**
114 * Total fragments
115 */
116 u_int16_t total_fragments;
117
118 /**
119 * AEAD transform to use
120 */
121 aead_t *aead;
122
123 /**
124 * Chunk containing the plain packet data.
125 */
126 chunk_t plain;
127 };
128
129 /**
130 * Encoding rules to parse or generate a IKEv2-Encrypted Payload.
131 *
132 * The defined offsets are the positions in a object of type
133 * private_encrypted_payload_t.
134 */
135 static encoding_rule_t encodings_v2[] = {
136 /* 1 Byte next payload type, stored in the field next_payload */
137 { U_INT_8, offsetof(private_encrypted_payload_t, next_payload) },
138 /* Critical and 7 reserved bits, all stored for reconstruction */
139 { U_INT_8, offsetof(private_encrypted_payload_t, flags) },
140 /* Length of the whole encrypted payload*/
141 { PAYLOAD_LENGTH, offsetof(private_encrypted_payload_t, payload_length) },
142 /* encrypted data, stored in a chunk. contains iv, data, padding */
143 { CHUNK_DATA, offsetof(private_encrypted_payload_t, encrypted) },
144 };
145
146 /*
147 1 2 3
148 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
149 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150 ! Next Payload !C! RESERVED ! Payload Length !
151 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152 ! Initialization Vector !
153 ! (length is block size for encryption algorithm) !
154 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155 ! Encrypted IKE Payloads !
156 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157 ! ! Padding (0-255 octets) !
158 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
159 ! ! Pad Length !
160 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 ~ Integrity Checksum Data ~
162 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 */
164
165 /**
166 * Encoding rules to parse or generate a complete encrypted IKEv1 message.
167 *
168 * The defined offsets are the positions in a object of type
169 * private_encrypted_payload_t.
170 */
171 static encoding_rule_t encodings_v1[] = {
172 /* encrypted data, stored in a chunk */
173 { ENCRYPTED_DATA, offsetof(private_encrypted_payload_t, encrypted) },
174 };
175
176 /*
177 1 2 3
178 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
179 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
180 ! Encrypted IKE Payloads !
181 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
182 ! ! Padding (0-255 octets) !
183 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184 */
185
186 /**
187 * Encoding rules to parse or generate an IKEv2-Encrypted Fragment Payload.
188 *
189 * The defined offsets are the positions in a object of type
190 * private_encrypted_payload_t.
191 */
192 static encoding_rule_t encodings_fragment[] = {
193 /* 1 Byte next payload type, stored in the field next_payload */
194 { U_INT_8, offsetof(private_encrypted_fragment_payload_t, next_payload) },
195 /* Critical and 7 reserved bits, all stored for reconstruction */
196 { U_INT_8, offsetof(private_encrypted_fragment_payload_t, flags) },
197 /* Length of the whole encryption payload*/
198 { PAYLOAD_LENGTH, offsetof(private_encrypted_fragment_payload_t, payload_length) },
199 /* Fragment number */
200 { U_INT_16, offsetof(private_encrypted_fragment_payload_t, fragment_number) },
201 /* Total number of fragments */
202 { U_INT_16, offsetof(private_encrypted_fragment_payload_t, total_fragments) },
203 /* encrypted data, stored in a chunk. contains iv, data, padding */
204 { CHUNK_DATA, offsetof(private_encrypted_fragment_payload_t, encrypted) },
205 };
206
207 /*
208 1 2 3
209 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
210 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
211 ! Next Payload !C! RESERVED ! Payload Length !
212 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
213 ! Fragment Number | Total Fragments !
214 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
215 ! Initialization Vector !
216 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
217 ! Encrypted IKE Payloads !
218 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
219 ! ! Padding (0-255 octets) !
220 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
221 ! ! Pad Length !
222 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
223 ~ Integrity Checksum Data ~
224 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
225 */
226
227 METHOD(payload_t, verify, status_t,
228 private_encrypted_payload_t *this)
229 {
230 return SUCCESS;
231 }
232
233 METHOD(payload_t, get_encoding_rules, int,
234 private_encrypted_payload_t *this, encoding_rule_t **rules)
235 {
236 if (this->type == PLV2_ENCRYPTED)
237 {
238 *rules = encodings_v2;
239 return countof(encodings_v2);
240 }
241 *rules = encodings_v1;
242 return countof(encodings_v1);
243 }
244
245 METHOD(payload_t, get_header_length, int,
246 private_encrypted_payload_t *this)
247 {
248 if (this->type == PLV2_ENCRYPTED)
249 {
250 return 4;
251 }
252 return 0;
253 }
254
255 METHOD(payload_t, get_type, payload_type_t,
256 private_encrypted_payload_t *this)
257 {
258 return this->type;
259 }
260
261 METHOD(payload_t, get_next_type, payload_type_t,
262 private_encrypted_payload_t *this)
263 {
264 return this->next_payload;
265 }
266
267 METHOD(payload_t, set_next_type, void,
268 private_encrypted_payload_t *this, payload_type_t type)
269 {
270 /* the next payload is set during add, still allow this for IKEv1 */
271 this->next_payload = type;
272 }
273
274 /**
275 * Get length of encryption/integrity overhead for the given plaintext length
276 */
277 static size_t compute_overhead(aead_t *aead, size_t len)
278 {
279 size_t bs, overhead;
280
281 /* padding */
282 bs = aead->get_block_size(aead);
283 overhead = bs - (len % bs);
284 /* add iv */
285 overhead += aead->get_iv_size(aead);
286 /* add icv */
287 overhead += aead->get_icv_size(aead);
288 return overhead;
289 }
290
291 /**
292 * Compute the length of the whole payload
293 */
294 static void compute_length(private_encrypted_payload_t *this)
295 {
296 enumerator_t *enumerator;
297 payload_t *payload;
298 size_t length = 0;
299
300 if (this->encrypted.len)
301 {
302 length = this->encrypted.len;
303 }
304 else
305 {
306 enumerator = this->payloads->create_enumerator(this->payloads);
307 while (enumerator->enumerate(enumerator, &payload))
308 {
309 length += payload->get_length(payload);
310 }
311 enumerator->destroy(enumerator);
312
313 if (this->aead)
314 {
315 length += compute_overhead(this->aead, length);
316 }
317 }
318 length += get_header_length(this);
319 this->payload_length = length;
320 }
321
322 METHOD2(payload_t, encrypted_payload_t, get_length, size_t,
323 private_encrypted_payload_t *this)
324 {
325 compute_length(this);
326 return this->payload_length;
327 }
328
329 METHOD(encrypted_payload_t, add_payload, void,
330 private_encrypted_payload_t *this, payload_t *payload)
331 {
332 payload_t *last_payload;
333
334 if (this->payloads->get_count(this->payloads) > 0)
335 {
336 this->payloads->get_last(this->payloads, (void **)&last_payload);
337 last_payload->set_next_type(last_payload, payload->get_type(payload));
338 }
339 else
340 {
341 this->next_payload = payload->get_type(payload);
342 }
343 payload->set_next_type(payload, PL_NONE);
344 this->payloads->insert_last(this->payloads, payload);
345 compute_length(this);
346 }
347
348 METHOD(encrypted_payload_t, remove_payload, payload_t *,
349 private_encrypted_payload_t *this)
350 {
351 payload_t *payload;
352
353 if (this->payloads->remove_first(this->payloads,
354 (void**)&payload) == SUCCESS)
355 {
356 return payload;
357 }
358 return NULL;
359 }
360
361 /**
362 * Generate payload before encryption
363 */
364 static chunk_t generate(private_encrypted_payload_t *this,
365 generator_t *generator)
366 {
367 payload_t *current, *next;
368 enumerator_t *enumerator;
369 u_int32_t *lenpos;
370 chunk_t chunk = chunk_empty;
371
372 enumerator = this->payloads->create_enumerator(this->payloads);
373 if (enumerator->enumerate(enumerator, &current))
374 {
375 this->next_payload = current->get_type(current);
376
377 while (enumerator->enumerate(enumerator, &next))
378 {
379 current->set_next_type(current, next->get_type(next));
380 generator->generate_payload(generator, current);
381 current = next;
382 }
383 current->set_next_type(current, PL_NONE);
384 generator->generate_payload(generator, current);
385
386 chunk = generator->get_chunk(generator, &lenpos);
387 DBG2(DBG_ENC, "generated content in encrypted payload");
388 }
389 enumerator->destroy(enumerator);
390 return chunk;
391 }
392
393 METHOD(encrypted_payload_t, generate_payloads, void,
394 private_encrypted_payload_t *this, generator_t *generator)
395 {
396 generate(this, generator);
397 }
398
399 /**
400 * Append the encrypted payload header to the associated data
401 */
402 static chunk_t append_header(private_encrypted_payload_t *this, chunk_t assoc)
403 {
404 struct {
405 u_int8_t next_payload;
406 u_int8_t flags;
407 u_int16_t length;
408 } __attribute__((packed)) header = {
409 .next_payload = this->next_payload,
410 .flags = this->flags,
411 .length = htons(get_length(this)),
412 };
413 return chunk_cat("cc", assoc, chunk_from_thing(header));
414 }
415
416 /**
417 * Encrypts the data in plain and returns it in an allocated chunk.
418 */
419 static status_t encrypt_content(char *label, aead_t *aead, u_int64_t mid,
420 chunk_t plain, chunk_t assoc, chunk_t *encrypted)
421 {
422 chunk_t iv, padding, icv, crypt;
423 iv_gen_t *iv_gen;
424 rng_t *rng;
425 size_t bs;
426
427 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
428 if (!rng)
429 {
430 DBG1(DBG_ENC, "encrypting %s failed, no RNG found", label);
431 return NOT_SUPPORTED;
432 }
433
434 iv_gen = aead->get_iv_gen(aead);
435 if (!iv_gen)
436 {
437 DBG1(DBG_ENC, "encrypting %s failed, no IV generator", label);
438 return NOT_SUPPORTED;
439 }
440
441 bs = aead->get_block_size(aead);
442 /* we need at least one byte padding to store the padding length */
443 padding.len = bs - (plain.len % bs);
444 iv.len = aead->get_iv_size(aead);
445 icv.len = aead->get_icv_size(aead);
446
447 /* prepare data to authenticate-encrypt:
448 * | IV | plain | padding | ICV |
449 * \____crypt______/ ^
450 * | /
451 * v /
452 * assoc -> + ------->/
453 */
454 *encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len);
455 iv.ptr = encrypted->ptr;
456 memcpy(iv.ptr + iv.len, plain.ptr, plain.len);
457 plain.ptr = iv.ptr + iv.len;
458 padding.ptr = plain.ptr + plain.len;
459 icv.ptr = padding.ptr + padding.len;
460 crypt = chunk_create(plain.ptr, plain.len + padding.len);
461
462 if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) ||
463 !rng->get_bytes(rng, padding.len - 1, padding.ptr))
464 {
465 DBG1(DBG_ENC, "encrypting %s failed, no IV or padding", label);
466 rng->destroy(rng);
467
468 return FAILED;
469 }
470 padding.ptr[padding.len - 1] = padding.len - 1;
471 rng->destroy(rng);
472
473 DBG3(DBG_ENC, "%s encryption:", label);
474 DBG3(DBG_ENC, "IV %B", &iv);
475 DBG3(DBG_ENC, "plain %B", &plain);
476 DBG3(DBG_ENC, "padding %B", &padding);
477 DBG3(DBG_ENC, "assoc %B", &assoc);
478
479 if (!aead->encrypt(aead, crypt, assoc, iv, NULL))
480 {
481 return FAILED;
482 }
483 DBG3(DBG_ENC, "encrypted %B", &crypt);
484 DBG3(DBG_ENC, "ICV %B", &icv);
485 return SUCCESS;
486 }
487
488 METHOD(encrypted_payload_t, encrypt, status_t,
489 private_encrypted_payload_t *this, u_int64_t mid, chunk_t assoc)
490 {
491 generator_t *generator;
492 chunk_t plain;
493 status_t status;
494
495 if (this->aead == NULL)
496 {
497 DBG1(DBG_ENC, "encrypting encrypted payload failed, transform missing");
498 return INVALID_STATE;
499 }
500
501 free(this->encrypted.ptr);
502 generator = generator_create();
503 plain = generate(this, generator);
504 assoc = append_header(this, assoc);
505 status = encrypt_content("encrypted payload", this->aead, mid, plain, assoc,
506 &this->encrypted);
507 generator->destroy(generator);
508 free(assoc.ptr);
509 return status;
510 }
511
512 METHOD(encrypted_payload_t, encrypt_v1, status_t,
513 private_encrypted_payload_t *this, u_int64_t mid, chunk_t iv)
514 {
515 generator_t *generator;
516 chunk_t plain, padding;
517 size_t bs;
518
519 if (this->aead == NULL)
520 {
521 DBG1(DBG_ENC, "encryption failed, transform missing");
522 return INVALID_STATE;
523 }
524
525 generator = generator_create();
526 plain = generate(this, generator);
527 bs = this->aead->get_block_size(this->aead);
528 padding.len = bs - (plain.len % bs);
529
530 /* prepare data to encrypt:
531 * | plain | padding | */
532 free(this->encrypted.ptr);
533 this->encrypted = chunk_alloc(plain.len + padding.len);
534 memcpy(this->encrypted.ptr, plain.ptr, plain.len);
535 plain.ptr = this->encrypted.ptr;
536 padding.ptr = plain.ptr + plain.len;
537 memset(padding.ptr, 0, padding.len);
538 generator->destroy(generator);
539
540 DBG3(DBG_ENC, "encrypting payloads:");
541 DBG3(DBG_ENC, "IV %B", &iv);
542 DBG3(DBG_ENC, "plain %B", &plain);
543 DBG3(DBG_ENC, "padding %B", &padding);
544
545 if (!this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
546 {
547 return FAILED;
548 }
549
550 DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
551
552 return SUCCESS;
553 }
554
555 /**
556 * Parse the payloads after decryption.
557 */
558 static status_t parse(private_encrypted_payload_t *this, chunk_t plain)
559 {
560 parser_t *parser;
561 payload_type_t type;
562
563 parser = parser_create(plain);
564 parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2);
565 type = this->next_payload;
566 while (type != PL_NONE)
567 {
568 payload_t *payload;
569
570 if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len)
571 {
572 DBG1(DBG_ENC, "invalid %N payload length, decryption failed?",
573 payload_type_names, type);
574 parser->destroy(parser);
575 return PARSE_ERROR;
576 }
577 if (parser->parse_payload(parser, type, &payload) != SUCCESS)
578 {
579 parser->destroy(parser);
580 return PARSE_ERROR;
581 }
582 if (payload->verify(payload) != SUCCESS)
583 {
584 DBG1(DBG_ENC, "%N verification failed",
585 payload_type_names, payload->get_type(payload));
586 payload->destroy(payload);
587 parser->destroy(parser);
588 return VERIFY_ERROR;
589 }
590 type = payload->get_next_type(payload);
591 this->payloads->insert_last(this->payloads, payload);
592 }
593 parser->destroy(parser);
594 DBG2(DBG_ENC, "parsed content of encrypted payload");
595 return SUCCESS;
596 }
597
598 /**
599 * Decrypts the given data in-place and returns a chunk pointing to the
600 * resulting plaintext.
601 */
602 static status_t decrypt_content(char *label, aead_t *aead, chunk_t encrypted,
603 chunk_t assoc, chunk_t *plain)
604 {
605 chunk_t iv, padding, icv, crypt;
606 size_t bs;
607
608 /* prepare data to authenticate-decrypt:
609 * | IV | plain | padding | ICV |
610 * \____crypt______/ ^
611 * | /
612 * v /
613 * assoc -> + ------->/
614 */
615 bs = aead->get_block_size(aead);
616 iv.len = aead->get_iv_size(aead);
617 iv.ptr = encrypted.ptr;
618 icv.len = aead->get_icv_size(aead);
619 icv.ptr = encrypted.ptr + encrypted.len - icv.len;
620 crypt.ptr = iv.ptr + iv.len;
621 crypt.len = encrypted.len - iv.len;
622
623 if (iv.len + icv.len > encrypted.len ||
624 (crypt.len - icv.len) % bs)
625 {
626 DBG1(DBG_ENC, "decrypting %s payload failed, invalid length", label);
627 return FAILED;
628 }
629
630 DBG3(DBG_ENC, "%s decryption:", label);
631 DBG3(DBG_ENC, "IV %B", &iv);
632 DBG3(DBG_ENC, "encrypted %B", &crypt);
633 DBG3(DBG_ENC, "ICV %B", &icv);
634 DBG3(DBG_ENC, "assoc %B", &assoc);
635
636 if (!aead->decrypt(aead, crypt, assoc, iv, NULL))
637 {
638 DBG1(DBG_ENC, "verifying %s integrity failed", label);
639 return FAILED;
640 }
641
642 *plain = chunk_create(crypt.ptr, crypt.len - icv.len);
643 padding.len = plain->ptr[plain->len - 1] + 1;
644 if (padding.len > plain->len)
645 {
646 DBG1(DBG_ENC, "decrypting %s failed, padding invalid %B", label,
647 &crypt);
648 return PARSE_ERROR;
649 }
650 plain->len -= padding.len;
651 padding.ptr = plain->ptr + plain->len;
652
653 DBG3(DBG_ENC, "plain %B", plain);
654 DBG3(DBG_ENC, "padding %B", &padding);
655 return SUCCESS;
656 }
657
658 METHOD(encrypted_payload_t, decrypt, status_t,
659 private_encrypted_payload_t *this, chunk_t assoc)
660 {
661 chunk_t plain;
662 status_t status;
663
664 if (this->aead == NULL)
665 {
666 DBG1(DBG_ENC, "decrypting encrypted payload failed, transform missing");
667 return INVALID_STATE;
668 }
669
670 assoc = append_header(this, assoc);
671 status = decrypt_content("encrypted payload", this->aead, this->encrypted,
672 assoc, &plain);
673 free(assoc.ptr);
674
675 if (status != SUCCESS)
676 {
677 return status;
678 }
679 return parse(this, plain);
680 }
681
682 METHOD(encrypted_payload_t, decrypt_plain, status_t,
683 private_encrypted_payload_t *this, chunk_t assoc)
684 {
685 if (!this->encrypted.ptr)
686 {
687 return FAILED;
688 }
689 return parse(this, this->encrypted);
690 }
691
692 METHOD(encrypted_payload_t, decrypt_v1, status_t,
693 private_encrypted_payload_t *this, chunk_t iv)
694 {
695 if (this->aead == NULL)
696 {
697 DBG1(DBG_ENC, "decryption failed, transform missing");
698 return INVALID_STATE;
699 }
700
701 /* data must be a multiple of block size */
702 if (iv.len != this->aead->get_block_size(this->aead) ||
703 this->encrypted.len < iv.len || this->encrypted.len % iv.len)
704 {
705 DBG1(DBG_ENC, "decryption failed, invalid length");
706 return FAILED;
707 }
708
709 DBG3(DBG_ENC, "decrypting payloads:");
710 DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
711
712 if (!this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
713 {
714 return FAILED;
715 }
716
717 DBG3(DBG_ENC, "plain %B", &this->encrypted);
718
719 return parse(this, this->encrypted);
720 }
721
722 METHOD(encrypted_payload_t, set_transform, void,
723 private_encrypted_payload_t *this, aead_t* aead)
724 {
725 this->aead = aead;
726 }
727
728 METHOD2(payload_t, encrypted_payload_t, destroy, void,
729 private_encrypted_payload_t *this)
730 {
731 this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
732 free(this->encrypted.ptr);
733 free(this);
734 }
735
736 /*
737 * Described in header
738 */
739 encrypted_payload_t *encrypted_payload_create(payload_type_t type)
740 {
741 private_encrypted_payload_t *this;
742
743 INIT(this,
744 .public = {
745 .payload_interface = {
746 .verify = _verify,
747 .get_encoding_rules = _get_encoding_rules,
748 .get_header_length = _get_header_length,
749 .get_length = _get_length,
750 .get_next_type = _get_next_type,
751 .set_next_type = _set_next_type,
752 .get_type = _get_type,
753 .destroy = _destroy,
754 },
755 .get_length = _get_length,
756 .add_payload = _add_payload,
757 .remove_payload = _remove_payload,
758 .generate_payloads = _generate_payloads,
759 .set_transform = _set_transform,
760 .encrypt = _encrypt,
761 .decrypt = _decrypt,
762 .destroy = _destroy,
763 },
764 .next_payload = PL_NONE,
765 .payloads = linked_list_create(),
766 .type = type,
767 );
768 this->payload_length = get_header_length(this);
769
770 if (type == PLV1_ENCRYPTED)
771 {
772 this->public.encrypt = _encrypt_v1;
773 this->public.decrypt = _decrypt_v1;
774 }
775
776 return &this->public;
777 }
778
779 /*
780 * Described in header
781 */
782 encrypted_payload_t *encrypted_payload_create_from_plain(payload_type_t next,
783 chunk_t plain)
784 {
785 private_encrypted_payload_t *this;
786
787 this = (private_encrypted_payload_t*)encrypted_payload_create(PLV2_ENCRYPTED);
788 this->public.decrypt = _decrypt_plain;
789 this->next_payload = next;
790 this->encrypted = plain;
791 compute_length(this);
792
793 return &this->public;
794 }
795
796 METHOD(payload_t, frag_verify, status_t,
797 private_encrypted_fragment_payload_t *this)
798 {
799 if (!this->fragment_number || !this->total_fragments ||
800 this->fragment_number > this->total_fragments)
801 {
802 DBG1(DBG_ENC, "invalid fragment number (%u) or total fragments (%u)",
803 this->fragment_number, this->total_fragments);
804 return FAILED;
805 }
806 if (this->fragment_number > 1 && this->next_payload != 0)
807 {
808 DBG1(DBG_ENC, "invalid next payload (%u) for fragment %u, ignored",
809 this->next_payload, this->fragment_number);
810 this->next_payload = 0;
811 }
812 return SUCCESS;
813 }
814
815 METHOD(payload_t, frag_get_encoding_rules, int,
816 private_encrypted_fragment_payload_t *this, encoding_rule_t **rules)
817 {
818 *rules = encodings_fragment;
819 return countof(encodings_fragment);
820 }
821
822 METHOD(payload_t, frag_get_header_length, int,
823 private_encrypted_fragment_payload_t *this)
824 {
825 return 8;
826 }
827
828 METHOD(payload_t, frag_get_type, payload_type_t,
829 private_encrypted_fragment_payload_t *this)
830 {
831 return PLV2_FRAGMENT;
832 }
833
834 METHOD(payload_t, frag_get_next_type, payload_type_t,
835 private_encrypted_fragment_payload_t *this)
836 {
837 return this->next_payload;
838 }
839
840 METHOD(payload_t, frag_set_next_type, void,
841 private_encrypted_fragment_payload_t *this, payload_type_t type)
842 {
843 if (this->fragment_number == 1 && this->next_payload == PL_NONE)
844 {
845 this->next_payload = type;
846 }
847 }
848
849 METHOD2(payload_t, encrypted_payload_t, frag_get_length, size_t,
850 private_encrypted_fragment_payload_t *this)
851 {
852 if (this->encrypted.len)
853 {
854 this->payload_length = this->encrypted.len;
855 }
856 else
857 {
858 this->payload_length = this->plain.len;
859
860 if (this->aead)
861 {
862 this->payload_length += compute_overhead(this->aead,
863 this->payload_length);
864 }
865 }
866 this->payload_length += frag_get_header_length(this);
867 return this->payload_length;
868 }
869
870 METHOD(encrypted_fragment_payload_t, get_fragment_number, u_int16_t,
871 private_encrypted_fragment_payload_t *this)
872 {
873 return this->fragment_number;
874 }
875
876 METHOD(encrypted_fragment_payload_t, get_total_fragments, u_int16_t,
877 private_encrypted_fragment_payload_t *this)
878 {
879 return this->total_fragments;
880 }
881
882 METHOD(encrypted_fragment_payload_t, frag_get_content, chunk_t,
883 private_encrypted_fragment_payload_t *this)
884 {
885 return this->plain;
886 }
887
888 METHOD(encrypted_payload_t, frag_add_payload, void,
889 private_encrypted_fragment_payload_t *this, payload_t* payload)
890 {
891 payload->destroy(payload);
892 }
893
894 METHOD(encrypted_payload_t, frag_set_transform, void,
895 private_encrypted_fragment_payload_t *this, aead_t* aead)
896 {
897 this->aead = aead;
898 }
899
900 /**
901 * Append the encrypted fragment payload header to the associated data
902 */
903 static chunk_t append_header_frag(private_encrypted_fragment_payload_t *this,
904 chunk_t assoc)
905 {
906 struct {
907 u_int8_t next_payload;
908 u_int8_t flags;
909 u_int16_t length;
910 u_int16_t fragment_number;
911 u_int16_t total_fragments;
912 } __attribute__((packed)) header = {
913 .next_payload = this->next_payload,
914 .flags = this->flags,
915 .length = htons(frag_get_length(this)),
916 .fragment_number = htons(this->fragment_number),
917 .total_fragments = htons(this->total_fragments),
918 };
919 return chunk_cat("cc", assoc, chunk_from_thing(header));
920 }
921
922 METHOD(encrypted_payload_t, frag_encrypt, status_t,
923 private_encrypted_fragment_payload_t *this, u_int64_t mid, chunk_t assoc)
924 {
925 status_t status;
926
927 if (!this->aead)
928 {
929 DBG1(DBG_ENC, "encrypting encrypted fragment payload failed, "
930 "transform missing");
931 return INVALID_STATE;
932 }
933 free(this->encrypted.ptr);
934 assoc = append_header_frag(this, assoc);
935 status = encrypt_content("encrypted fragment payload", this->aead, mid,
936 this->plain, assoc, &this->encrypted);
937 free(assoc.ptr);
938 return status;
939 }
940
941 METHOD(encrypted_payload_t, frag_decrypt, status_t,
942 private_encrypted_fragment_payload_t *this, chunk_t assoc)
943 {
944 status_t status;
945
946 if (!this->aead)
947 {
948 DBG1(DBG_ENC, "decrypting encrypted fragment payload failed, "
949 "transform missing");
950 return INVALID_STATE;
951 }
952 free(this->plain.ptr);
953 assoc = append_header_frag(this, assoc);
954 status = decrypt_content("encrypted fragment payload", this->aead,
955 this->encrypted, assoc, &this->plain);
956 this->plain = chunk_clone(this->plain);
957 free(assoc.ptr);
958 return status;
959 }
960
961 METHOD2(payload_t, encrypted_payload_t, frag_destroy, void,
962 private_encrypted_fragment_payload_t *this)
963 {
964 free(this->encrypted.ptr);
965 free(this->plain.ptr);
966 free(this);
967 }
968
969 /*
970 * Described in header
971 */
972 encrypted_fragment_payload_t *encrypted_fragment_payload_create()
973 {
974 private_encrypted_fragment_payload_t *this;
975
976 INIT(this,
977 .public = {
978 .encrypted = {
979 .payload_interface = {
980 .verify = _frag_verify,
981 .get_encoding_rules = _frag_get_encoding_rules,
982 .get_header_length = _frag_get_header_length,
983 .get_length = _frag_get_length,
984 .get_next_type = _frag_get_next_type,
985 .set_next_type = _frag_set_next_type,
986 .get_type = _frag_get_type,
987 .destroy = _frag_destroy,
988 },
989 .get_length = _frag_get_length,
990 .add_payload = _frag_add_payload,
991 .remove_payload = (void*)return_null,
992 .generate_payloads = nop,
993 .set_transform = _frag_set_transform,
994 .encrypt = _frag_encrypt,
995 .decrypt = _frag_decrypt,
996 .destroy = _frag_destroy,
997 },
998 .get_fragment_number = _get_fragment_number,
999 .get_total_fragments = _get_total_fragments,
1000 .get_content = _frag_get_content,
1001 },
1002 .next_payload = PL_NONE,
1003 );
1004 this->payload_length = frag_get_header_length(this);
1005
1006 return &this->public;
1007 }
1008
1009 /*
1010 * Described in header
1011 */
1012 encrypted_fragment_payload_t *encrypted_fragment_payload_create_from_data(
1013 u_int16_t num, u_int16_t total, chunk_t plain)
1014 {
1015 private_encrypted_fragment_payload_t *this;
1016
1017 this = (private_encrypted_fragment_payload_t*)encrypted_fragment_payload_create();
1018 this->fragment_number = num;
1019 this->total_fragments = total;
1020 this->plain = chunk_clone(plain);
1021
1022 return &this->public;
1023 }