ikev2: Add encrypted fragment payload
[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 type = this->next_payload;
565 while (type != PL_NONE)
566 {
567 payload_t *payload;
568
569 if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len)
570 {
571 DBG1(DBG_ENC, "invalid %N payload length, decryption failed?",
572 payload_type_names, type);
573 parser->destroy(parser);
574 return PARSE_ERROR;
575 }
576 if (parser->parse_payload(parser, type, &payload) != SUCCESS)
577 {
578 parser->destroy(parser);
579 return PARSE_ERROR;
580 }
581 if (payload->verify(payload) != SUCCESS)
582 {
583 DBG1(DBG_ENC, "%N verification failed",
584 payload_type_names, payload->get_type(payload));
585 payload->destroy(payload);
586 parser->destroy(parser);
587 return VERIFY_ERROR;
588 }
589 type = payload->get_next_type(payload);
590 this->payloads->insert_last(this->payloads, payload);
591 }
592 parser->destroy(parser);
593 DBG2(DBG_ENC, "parsed content of encrypted payload");
594 return SUCCESS;
595 }
596
597 /**
598 * Decrypts the given data in-place and returns a chunk pointing to the
599 * resulting plaintext.
600 */
601 static status_t decrypt_content(char *label, aead_t *aead, chunk_t encrypted,
602 chunk_t assoc, chunk_t *plain)
603 {
604 chunk_t iv, padding, icv, crypt;
605 size_t bs;
606
607 /* prepare data to authenticate-decrypt:
608 * | IV | plain | padding | ICV |
609 * \____crypt______/ ^
610 * | /
611 * v /
612 * assoc -> + ------->/
613 */
614 bs = aead->get_block_size(aead);
615 iv.len = aead->get_iv_size(aead);
616 iv.ptr = encrypted.ptr;
617 icv.len = aead->get_icv_size(aead);
618 icv.ptr = encrypted.ptr + encrypted.len - icv.len;
619 crypt.ptr = iv.ptr + iv.len;
620 crypt.len = encrypted.len - iv.len;
621
622 if (iv.len + icv.len > encrypted.len ||
623 (crypt.len - icv.len) % bs)
624 {
625 DBG1(DBG_ENC, "decrypting %s payload failed, invalid length", label);
626 return FAILED;
627 }
628
629 DBG3(DBG_ENC, "%s decryption:", label);
630 DBG3(DBG_ENC, "IV %B", &iv);
631 DBG3(DBG_ENC, "encrypted %B", &crypt);
632 DBG3(DBG_ENC, "ICV %B", &icv);
633 DBG3(DBG_ENC, "assoc %B", &assoc);
634
635 if (!aead->decrypt(aead, crypt, assoc, iv, NULL))
636 {
637 DBG1(DBG_ENC, "verifying %s integrity failed", label);
638 return FAILED;
639 }
640
641 *plain = chunk_create(crypt.ptr, crypt.len - icv.len);
642 padding.len = plain->ptr[plain->len - 1] + 1;
643 if (padding.len > plain->len)
644 {
645 DBG1(DBG_ENC, "decrypting %s failed, padding invalid %B", label,
646 &crypt);
647 return PARSE_ERROR;
648 }
649 plain->len -= padding.len;
650 padding.ptr = plain->ptr + plain->len;
651
652 DBG3(DBG_ENC, "plain %B", plain);
653 DBG3(DBG_ENC, "padding %B", &padding);
654 return SUCCESS;
655 }
656
657 METHOD(encrypted_payload_t, decrypt, status_t,
658 private_encrypted_payload_t *this, chunk_t assoc)
659 {
660 chunk_t plain;
661 status_t status;
662
663 if (this->aead == NULL)
664 {
665 DBG1(DBG_ENC, "decrypting encrypted payload failed, transform missing");
666 return INVALID_STATE;
667 }
668
669 assoc = append_header(this, assoc);
670 status = decrypt_content("encrypted payload", this->aead, this->encrypted,
671 assoc, &plain);
672 free(assoc.ptr);
673
674 if (status != SUCCESS)
675 {
676 return status;
677 }
678 return parse(this, plain);
679 }
680
681 METHOD(encrypted_payload_t, decrypt_plain, status_t,
682 private_encrypted_payload_t *this, chunk_t assoc)
683 {
684 if (!this->encrypted.ptr)
685 {
686 return FAILED;
687 }
688 return parse(this, this->encrypted);
689 }
690
691 METHOD(encrypted_payload_t, decrypt_v1, status_t,
692 private_encrypted_payload_t *this, chunk_t iv)
693 {
694 if (this->aead == NULL)
695 {
696 DBG1(DBG_ENC, "decryption failed, transform missing");
697 return INVALID_STATE;
698 }
699
700 /* data must be a multiple of block size */
701 if (iv.len != this->aead->get_block_size(this->aead) ||
702 this->encrypted.len < iv.len || this->encrypted.len % iv.len)
703 {
704 DBG1(DBG_ENC, "decryption failed, invalid length");
705 return FAILED;
706 }
707
708 DBG3(DBG_ENC, "decrypting payloads:");
709 DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
710
711 if (!this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
712 {
713 return FAILED;
714 }
715
716 DBG3(DBG_ENC, "plain %B", &this->encrypted);
717
718 return parse(this, this->encrypted);
719 }
720
721 METHOD(encrypted_payload_t, set_transform, void,
722 private_encrypted_payload_t *this, aead_t* aead)
723 {
724 this->aead = aead;
725 }
726
727 METHOD2(payload_t, encrypted_payload_t, destroy, void,
728 private_encrypted_payload_t *this)
729 {
730 this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
731 free(this->encrypted.ptr);
732 free(this);
733 }
734
735 /*
736 * Described in header
737 */
738 encrypted_payload_t *encrypted_payload_create(payload_type_t type)
739 {
740 private_encrypted_payload_t *this;
741
742 INIT(this,
743 .public = {
744 .payload_interface = {
745 .verify = _verify,
746 .get_encoding_rules = _get_encoding_rules,
747 .get_header_length = _get_header_length,
748 .get_length = _get_length,
749 .get_next_type = _get_next_type,
750 .set_next_type = _set_next_type,
751 .get_type = _get_type,
752 .destroy = _destroy,
753 },
754 .get_length = _get_length,
755 .add_payload = _add_payload,
756 .remove_payload = _remove_payload,
757 .generate_payloads = _generate_payloads,
758 .set_transform = _set_transform,
759 .encrypt = _encrypt,
760 .decrypt = _decrypt,
761 .destroy = _destroy,
762 },
763 .next_payload = PL_NONE,
764 .payloads = linked_list_create(),
765 .type = type,
766 );
767 this->payload_length = get_header_length(this);
768
769 if (type == PLV1_ENCRYPTED)
770 {
771 this->public.encrypt = _encrypt_v1;
772 this->public.decrypt = _decrypt_v1;
773 }
774
775 return &this->public;
776 }
777
778 /*
779 * Described in header
780 */
781 encrypted_payload_t *encrypted_payload_create_from_plain(payload_type_t next,
782 chunk_t plain)
783 {
784 private_encrypted_payload_t *this;
785
786 this = (private_encrypted_payload_t*)encrypted_payload_create(PLV2_ENCRYPTED);
787 this->public.decrypt = _decrypt_plain;
788 this->next_payload = next;
789 this->encrypted = plain;
790 compute_length(this);
791
792 return &this->public;
793 }
794
795 METHOD(payload_t, frag_verify, status_t,
796 private_encrypted_fragment_payload_t *this)
797 {
798 if (!this->fragment_number || !this->total_fragments ||
799 this->fragment_number > this->total_fragments)
800 {
801 DBG1(DBG_ENC, "invalid fragment number (%u) or total fragments (%u)",
802 this->fragment_number, this->total_fragments);
803 return FAILED;
804 }
805 if (this->fragment_number > 1 && this->next_payload != 0)
806 {
807 DBG1(DBG_ENC, "invalid next payload (%u) for fragment %u, ignored",
808 this->next_payload, this->fragment_number);
809 this->next_payload = 0;
810 }
811 return SUCCESS;
812 }
813
814 METHOD(payload_t, frag_get_encoding_rules, int,
815 private_encrypted_fragment_payload_t *this, encoding_rule_t **rules)
816 {
817 *rules = encodings_fragment;
818 return countof(encodings_fragment);
819 }
820
821 METHOD(payload_t, frag_get_header_length, int,
822 private_encrypted_fragment_payload_t *this)
823 {
824 return 8;
825 }
826
827 METHOD(payload_t, frag_get_type, payload_type_t,
828 private_encrypted_fragment_payload_t *this)
829 {
830 return PLV2_FRAGMENT;
831 }
832
833 METHOD(payload_t, frag_get_next_type, payload_type_t,
834 private_encrypted_fragment_payload_t *this)
835 {
836 return this->next_payload;
837 }
838
839 METHOD(payload_t, frag_set_next_type, void,
840 private_encrypted_fragment_payload_t *this, payload_type_t type)
841 {
842 if (this->fragment_number == 1 && this->next_payload == PL_NONE)
843 {
844 this->next_payload = type;
845 }
846 }
847
848 METHOD2(payload_t, encrypted_payload_t, frag_get_length, size_t,
849 private_encrypted_fragment_payload_t *this)
850 {
851 if (this->encrypted.len)
852 {
853 this->payload_length = this->encrypted.len;
854 }
855 else
856 {
857 this->payload_length = this->plain.len;
858
859 if (this->aead)
860 {
861 this->payload_length += compute_overhead(this->aead,
862 this->payload_length);
863 }
864 }
865 this->payload_length += frag_get_header_length(this);
866 return this->payload_length;
867 }
868
869 METHOD(encrypted_fragment_payload_t, get_fragment_number, u_int16_t,
870 private_encrypted_fragment_payload_t *this)
871 {
872 return this->fragment_number;
873 }
874
875 METHOD(encrypted_fragment_payload_t, get_total_fragments, u_int16_t,
876 private_encrypted_fragment_payload_t *this)
877 {
878 return this->total_fragments;
879 }
880
881 METHOD(encrypted_fragment_payload_t, frag_get_content, chunk_t,
882 private_encrypted_fragment_payload_t *this)
883 {
884 return this->plain;
885 }
886
887 METHOD(encrypted_payload_t, frag_add_payload, void,
888 private_encrypted_fragment_payload_t *this, payload_t* payload)
889 {
890 payload->destroy(payload);
891 }
892
893 METHOD(encrypted_payload_t, frag_set_transform, void,
894 private_encrypted_fragment_payload_t *this, aead_t* aead)
895 {
896 this->aead = aead;
897 }
898
899 /**
900 * Append the encrypted fragment payload header to the associated data
901 */
902 static chunk_t append_header_frag(private_encrypted_fragment_payload_t *this,
903 chunk_t assoc)
904 {
905 struct {
906 u_int8_t next_payload;
907 u_int8_t flags;
908 u_int16_t length;
909 u_int16_t fragment_number;
910 u_int16_t total_fragments;
911 } __attribute__((packed)) header = {
912 .next_payload = this->next_payload,
913 .flags = this->flags,
914 .length = htons(frag_get_length(this)),
915 .fragment_number = htons(this->fragment_number),
916 .total_fragments = htons(this->total_fragments),
917 };
918 return chunk_cat("cc", assoc, chunk_from_thing(header));
919 }
920
921 METHOD(encrypted_payload_t, frag_encrypt, status_t,
922 private_encrypted_fragment_payload_t *this, u_int64_t mid, chunk_t assoc)
923 {
924 status_t status;
925
926 if (!this->aead)
927 {
928 DBG1(DBG_ENC, "encrypting encrypted fragment payload failed, "
929 "transform missing");
930 return INVALID_STATE;
931 }
932 free(this->encrypted.ptr);
933 assoc = append_header_frag(this, assoc);
934 status = encrypt_content("encrypted fragment payload", this->aead, mid,
935 this->plain, assoc, &this->encrypted);
936 free(assoc.ptr);
937 return status;
938 }
939
940 METHOD(encrypted_payload_t, frag_decrypt, status_t,
941 private_encrypted_fragment_payload_t *this, chunk_t assoc)
942 {
943 status_t status;
944
945 if (!this->aead)
946 {
947 DBG1(DBG_ENC, "decrypting encrypted fragment payload failed, "
948 "transform missing");
949 return INVALID_STATE;
950 }
951 free(this->plain.ptr);
952 assoc = append_header_frag(this, assoc);
953 status = decrypt_content("encrypted fragment payload", this->aead,
954 this->encrypted, assoc, &this->plain);
955 this->plain = chunk_clone(this->plain);
956 free(assoc.ptr);
957 return status;
958 }
959
960 METHOD2(payload_t, encrypted_payload_t, frag_destroy, void,
961 private_encrypted_fragment_payload_t *this)
962 {
963 free(this->encrypted.ptr);
964 free(this->plain.ptr);
965 free(this);
966 }
967
968 /*
969 * Described in header
970 */
971 encrypted_fragment_payload_t *encrypted_fragment_payload_create()
972 {
973 private_encrypted_fragment_payload_t *this;
974
975 INIT(this,
976 .public = {
977 .encrypted = {
978 .payload_interface = {
979 .verify = _frag_verify,
980 .get_encoding_rules = _frag_get_encoding_rules,
981 .get_header_length = _frag_get_header_length,
982 .get_length = _frag_get_length,
983 .get_next_type = _frag_get_next_type,
984 .set_next_type = _frag_set_next_type,
985 .get_type = _frag_get_type,
986 .destroy = _frag_destroy,
987 },
988 .get_length = _frag_get_length,
989 .add_payload = _frag_add_payload,
990 .remove_payload = (void*)return_null,
991 .generate_payloads = nop,
992 .set_transform = _frag_set_transform,
993 .encrypt = _frag_encrypt,
994 .decrypt = _frag_decrypt,
995 .destroy = _frag_destroy,
996 },
997 .get_fragment_number = _get_fragment_number,
998 .get_total_fragments = _get_total_fragments,
999 .get_content = _frag_get_content,
1000 },
1001 .next_payload = PL_NONE,
1002 );
1003 this->payload_length = frag_get_header_length(this);
1004
1005 return &this->public;
1006 }
1007
1008 /*
1009 * Described in header
1010 */
1011 encrypted_fragment_payload_t *encrypted_fragment_payload_create_from_data(
1012 u_int16_t num, u_int16_t total, chunk_t plain)
1013 {
1014 private_encrypted_fragment_payload_t *this;
1015
1016 this = (private_encrypted_fragment_payload_t*)encrypted_fragment_payload_create();
1017 this->fragment_number = num;
1018 this->total_fragments = total;
1019 this->plain = chunk_clone(plain);
1020
1021 return &this->public;
1022 }