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