Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/encrypted_payload.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2011-2018 Tobias Brunner
3: * Copyright (C) 2005-2010 Martin Willi
4: * Copyright (C) 2010 revosec AG
5: * Copyright (C) 2005 Jan Hutter
6: * HSR 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: uint8_t next_payload;
47:
48: /**
49: * Flags, including reserved bits
50: */
51: uint8_t flags;
52:
53: /**
54: * Length of this payload
55: */
56: uint16_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: uint8_t next_payload;
92:
93: /**
94: * Flags, including reserved bits
95: */
96: uint8_t flags;
97:
98: /**
99: * Length of this payload
100: */
101: uint16_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: uint16_t fragment_number;
112:
113: /**
114: * Total fragments
115: */
116: uint16_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: METHOD2(payload_t, encrypted_payload_t, get_length_plain, size_t,
330: private_encrypted_payload_t *this)
331: {
332: /* contains only the decrypted payload data, no IV, padding or ICV */
333: this->payload_length = this->encrypted.len;
334:
335: if (this->aead)
336: {
337: this->payload_length += compute_overhead(this->aead,
338: this->payload_length);
339: }
340: this->payload_length += get_header_length(this);
341: return this->payload_length;
342: }
343:
344: METHOD(encrypted_payload_t, add_payload, void,
345: private_encrypted_payload_t *this, payload_t *payload)
346: {
347: payload_t *last_payload;
348:
349: if (this->payloads->get_count(this->payloads) > 0)
350: {
351: this->payloads->get_last(this->payloads, (void **)&last_payload);
352: last_payload->set_next_type(last_payload, payload->get_type(payload));
353: }
354: else
355: {
356: this->next_payload = payload->get_type(payload);
357: }
358: payload->set_next_type(payload, PL_NONE);
359: this->payloads->insert_last(this->payloads, payload);
360: compute_length(this);
361: }
362:
363: METHOD(encrypted_payload_t, remove_payload, payload_t *,
364: private_encrypted_payload_t *this)
365: {
366: payload_t *payload;
367:
368: if (this->payloads->remove_first(this->payloads,
369: (void**)&payload) == SUCCESS)
370: {
371: return payload;
372: }
373: return NULL;
374: }
375:
376: /**
377: * Generate payload before encryption
378: */
379: static chunk_t generate(private_encrypted_payload_t *this,
380: generator_t *generator)
381: {
382: payload_t *current, *next;
383: enumerator_t *enumerator;
384: uint32_t *lenpos;
385: chunk_t chunk = chunk_empty;
386:
387: enumerator = this->payloads->create_enumerator(this->payloads);
388: if (enumerator->enumerate(enumerator, ¤t))
389: {
390: this->next_payload = current->get_type(current);
391:
392: while (enumerator->enumerate(enumerator, &next))
393: {
394: current->set_next_type(current, next->get_type(next));
395: generator->generate_payload(generator, current);
396: current = next;
397: }
398: current->set_next_type(current, PL_NONE);
399: generator->generate_payload(generator, current);
400:
401: chunk = generator->get_chunk(generator, &lenpos);
402: DBG2(DBG_ENC, "generated content in encrypted payload");
403: }
404: enumerator->destroy(enumerator);
405: return chunk;
406: }
407:
408: METHOD(encrypted_payload_t, generate_payloads, void,
409: private_encrypted_payload_t *this, generator_t *generator)
410: {
411: generate(this, generator);
412: }
413:
414: /**
415: * Append the encrypted payload header to the associated data
416: */
417: static chunk_t append_header(private_encrypted_payload_t *this, chunk_t assoc)
418: {
419: struct {
420: uint8_t next_payload;
421: uint8_t flags;
422: uint16_t length;
423: } __attribute__((packed)) header = {
424: .next_payload = this->next_payload,
425: .flags = this->flags,
426: .length = htons(get_length(this)),
427: };
428: return chunk_cat("cc", assoc, chunk_from_thing(header));
429: }
430:
431: /**
432: * Encrypts the data in plain and returns it in an allocated chunk.
433: */
434: static status_t encrypt_content(char *label, aead_t *aead, uint64_t mid,
435: chunk_t plain, chunk_t assoc, chunk_t *encrypted)
436: {
437: chunk_t iv, padding, icv, crypt;
438: iv_gen_t *iv_gen;
439: rng_t *rng;
440: size_t bs;
441:
442: rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
443: if (!rng)
444: {
445: DBG1(DBG_ENC, "encrypting %s failed, no RNG found", label);
446: return NOT_SUPPORTED;
447: }
448:
449: iv_gen = aead->get_iv_gen(aead);
450: if (!iv_gen)
451: {
452: DBG1(DBG_ENC, "encrypting %s failed, no IV generator", label);
453: return NOT_SUPPORTED;
454: }
455:
456: bs = aead->get_block_size(aead);
457: /* we need at least one byte padding to store the padding length */
458: padding.len = bs - (plain.len % bs);
459: iv.len = aead->get_iv_size(aead);
460: icv.len = aead->get_icv_size(aead);
461:
462: /* prepare data to authenticate-encrypt:
463: * | IV | plain | padding | ICV |
464: * \____crypt______/ ^
465: * | /
466: * v /
467: * assoc -> + ------->/
468: */
469: *encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len);
470: iv.ptr = encrypted->ptr;
471: memcpy(iv.ptr + iv.len, plain.ptr, plain.len);
472: plain.ptr = iv.ptr + iv.len;
473: padding.ptr = plain.ptr + plain.len;
474: icv.ptr = padding.ptr + padding.len;
475: crypt = chunk_create(plain.ptr, plain.len + padding.len);
476:
477: if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) ||
478: !rng->get_bytes(rng, padding.len - 1, padding.ptr))
479: {
480: DBG1(DBG_ENC, "encrypting %s failed, no IV or padding", label);
481: rng->destroy(rng);
482:
483: return FAILED;
484: }
485: padding.ptr[padding.len - 1] = padding.len - 1;
486: rng->destroy(rng);
487:
488: DBG3(DBG_ENC, "%s encryption:", label);
489: DBG3(DBG_ENC, "IV %B", &iv);
490: DBG3(DBG_ENC, "plain %B", &plain);
491: DBG3(DBG_ENC, "padding %B", &padding);
492: DBG3(DBG_ENC, "assoc %B", &assoc);
493:
494: if (!aead->encrypt(aead, crypt, assoc, iv, NULL))
495: {
496: return FAILED;
497: }
498: DBG3(DBG_ENC, "encrypted %B", &crypt);
499: DBG3(DBG_ENC, "ICV %B", &icv);
500: return SUCCESS;
501: }
502:
503: METHOD(encrypted_payload_t, encrypt, status_t,
504: private_encrypted_payload_t *this, uint64_t mid, chunk_t assoc)
505: {
506: generator_t *generator;
507: chunk_t plain;
508: status_t status;
509:
510: if (this->aead == NULL)
511: {
512: DBG1(DBG_ENC, "encrypting encrypted payload failed, transform missing");
513: return INVALID_STATE;
514: }
515:
516: free(this->encrypted.ptr);
517: generator = generator_create();
518: plain = generate(this, generator);
519: assoc = append_header(this, assoc);
520: /* lower 32-bits are for fragment number, if used */
521: mid <<= 32;
522: status = encrypt_content("encrypted payload", this->aead, mid, plain, assoc,
523: &this->encrypted);
524: generator->destroy(generator);
525: free(assoc.ptr);
526: return status;
527: }
528:
529: METHOD(encrypted_payload_t, encrypt_v1, status_t,
530: private_encrypted_payload_t *this, uint64_t mid, chunk_t iv)
531: {
532: generator_t *generator;
533: chunk_t plain, padding;
534: size_t bs;
535:
536: if (this->aead == NULL)
537: {
538: DBG1(DBG_ENC, "encryption failed, transform missing");
539: return INVALID_STATE;
540: }
541:
542: generator = generator_create();
543: plain = generate(this, generator);
544: bs = this->aead->get_block_size(this->aead);
545: padding.len = bs - (plain.len % bs);
546:
547: /* prepare data to encrypt:
548: * | plain | padding | */
549: free(this->encrypted.ptr);
550: this->encrypted = chunk_alloc(plain.len + padding.len);
551: memcpy(this->encrypted.ptr, plain.ptr, plain.len);
552: plain.ptr = this->encrypted.ptr;
553: padding.ptr = plain.ptr + plain.len;
554: memset(padding.ptr, 0, padding.len);
555: generator->destroy(generator);
556:
557: DBG3(DBG_ENC, "encrypting payloads:");
558: DBG3(DBG_ENC, "IV %B", &iv);
559: DBG3(DBG_ENC, "plain %B", &plain);
560: DBG3(DBG_ENC, "padding %B", &padding);
561:
562: if (!this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
563: {
564: return FAILED;
565: }
566:
567: DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
568:
569: return SUCCESS;
570: }
571:
572: /**
573: * Parse the payloads after decryption.
574: */
575: static status_t parse(private_encrypted_payload_t *this, chunk_t plain)
576: {
577: parser_t *parser;
578: payload_type_t type;
579:
580: parser = parser_create(plain);
581: parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2);
582: type = this->next_payload;
583: while (type != PL_NONE)
584: {
585: payload_t *payload;
586:
587: if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len)
588: {
589: DBG1(DBG_ENC, "invalid %N payload length, decryption failed?",
590: payload_type_names, type);
591: parser->destroy(parser);
592: return PARSE_ERROR;
593: }
594: if (parser->parse_payload(parser, type, &payload) != SUCCESS)
595: {
596: parser->destroy(parser);
597: return PARSE_ERROR;
598: }
599: if (payload->verify(payload) != SUCCESS)
600: {
601: DBG1(DBG_ENC, "%N verification failed",
602: payload_type_names, payload->get_type(payload));
603: payload->destroy(payload);
604: parser->destroy(parser);
605: return VERIFY_ERROR;
606: }
607: type = payload->get_next_type(payload);
608: this->payloads->insert_last(this->payloads, payload);
609: }
610: parser->destroy(parser);
611: DBG2(DBG_ENC, "parsed content of encrypted payload");
612: return SUCCESS;
613: }
614:
615: /**
616: * Decrypts the given data in-place and returns a chunk pointing to the
617: * resulting plaintext.
618: */
619: static status_t decrypt_content(char *label, aead_t *aead, chunk_t encrypted,
620: chunk_t assoc, chunk_t *plain)
621: {
622: chunk_t iv, padding, icv, crypt;
623: size_t bs;
624:
625: /* prepare data to authenticate-decrypt:
626: * | IV | plain | padding | ICV |
627: * \____crypt______/ ^
628: * | /
629: * v /
630: * assoc -> + ------->/
631: */
632: bs = aead->get_block_size(aead);
633: iv.len = aead->get_iv_size(aead);
634: iv.ptr = encrypted.ptr;
635: icv.len = aead->get_icv_size(aead);
636: icv.ptr = encrypted.ptr + encrypted.len - icv.len;
637: crypt.ptr = iv.ptr + iv.len;
638: crypt.len = encrypted.len - iv.len;
639:
640: if (iv.len + icv.len > encrypted.len ||
641: (crypt.len - icv.len) % bs)
642: {
643: DBG1(DBG_ENC, "decrypting %s payload failed, invalid length", label);
644: return FAILED;
645: }
646:
647: DBG3(DBG_ENC, "%s decryption:", label);
648: DBG3(DBG_ENC, "IV %B", &iv);
649: DBG3(DBG_ENC, "encrypted %B", &crypt);
650: DBG3(DBG_ENC, "ICV %B", &icv);
651: DBG3(DBG_ENC, "assoc %B", &assoc);
652:
653: if (!aead->decrypt(aead, crypt, assoc, iv, NULL))
654: {
655: DBG1(DBG_ENC, "verifying %s integrity failed", label);
656: return FAILED;
657: }
658:
659: *plain = chunk_create(crypt.ptr, crypt.len - icv.len);
660: padding.len = plain->ptr[plain->len - 1] + 1;
661: if (padding.len > plain->len)
662: {
663: DBG1(DBG_ENC, "decrypting %s failed, padding invalid %B", label,
664: &crypt);
665: return PARSE_ERROR;
666: }
667: plain->len -= padding.len;
668: padding.ptr = plain->ptr + plain->len;
669:
670: DBG3(DBG_ENC, "plain %B", plain);
671: DBG3(DBG_ENC, "padding %B", &padding);
672: return SUCCESS;
673: }
674:
675: METHOD(encrypted_payload_t, decrypt, status_t,
676: private_encrypted_payload_t *this, chunk_t assoc)
677: {
678: chunk_t plain;
679: status_t status;
680:
681: if (this->aead == NULL)
682: {
683: DBG1(DBG_ENC, "decrypting encrypted payload failed, transform missing");
684: return INVALID_STATE;
685: }
686:
687: assoc = append_header(this, assoc);
688: status = decrypt_content("encrypted payload", this->aead, this->encrypted,
689: assoc, &plain);
690: free(assoc.ptr);
691:
692: if (status != SUCCESS)
693: {
694: return status;
695: }
696: return parse(this, plain);
697: }
698:
699: METHOD(encrypted_payload_t, decrypt_plain, status_t,
700: private_encrypted_payload_t *this, chunk_t assoc)
701: {
702: if (!this->encrypted.ptr)
703: {
704: return FAILED;
705: }
706: return parse(this, this->encrypted);
707: }
708:
709: METHOD(encrypted_payload_t, decrypt_v1, status_t,
710: private_encrypted_payload_t *this, chunk_t iv)
711: {
712: if (this->aead == NULL)
713: {
714: DBG1(DBG_ENC, "decryption failed, transform missing");
715: return INVALID_STATE;
716: }
717:
718: /* data must be a multiple of block size */
719: if (iv.len != this->aead->get_block_size(this->aead) ||
720: this->encrypted.len < iv.len || this->encrypted.len % iv.len)
721: {
722: DBG1(DBG_ENC, "decryption failed, invalid length");
723: return FAILED;
724: }
725:
726: DBG3(DBG_ENC, "decrypting payloads:");
727: DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
728:
729: if (!this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL))
730: {
731: return FAILED;
732: }
733:
734: DBG3(DBG_ENC, "plain %B", &this->encrypted);
735:
736: return parse(this, this->encrypted);
737: }
738:
739: METHOD(encrypted_payload_t, set_transform, void,
740: private_encrypted_payload_t *this, aead_t* aead)
741: {
742: this->aead = aead;
743: }
744:
745: METHOD(encrypted_payload_t, get_transform, aead_t*,
746: private_encrypted_payload_t *this)
747: {
748: return this->aead;
749: }
750:
751: METHOD2(payload_t, encrypted_payload_t, destroy, void,
752: private_encrypted_payload_t *this)
753: {
754: this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
755: free(this->encrypted.ptr);
756: free(this);
757: }
758:
759: /*
760: * Described in header
761: */
762: encrypted_payload_t *encrypted_payload_create(payload_type_t type)
763: {
764: private_encrypted_payload_t *this;
765:
766: INIT(this,
767: .public = {
768: .payload_interface = {
769: .verify = _verify,
770: .get_encoding_rules = _get_encoding_rules,
771: .get_header_length = _get_header_length,
772: .get_length = _get_length,
773: .get_next_type = _get_next_type,
774: .set_next_type = _set_next_type,
775: .get_type = _get_type,
776: .destroy = _destroy,
777: },
778: .get_length = _get_length,
779: .add_payload = _add_payload,
780: .remove_payload = _remove_payload,
781: .generate_payloads = _generate_payloads,
782: .set_transform = _set_transform,
783: .get_transform = _get_transform,
784: .encrypt = _encrypt,
785: .decrypt = _decrypt,
786: .destroy = _destroy,
787: },
788: .next_payload = PL_NONE,
789: .payloads = linked_list_create(),
790: .type = type,
791: );
792: this->payload_length = get_header_length(this);
793:
794: if (type == PLV1_ENCRYPTED)
795: {
796: this->public.encrypt = _encrypt_v1;
797: this->public.decrypt = _decrypt_v1;
798: }
799:
800: return &this->public;
801: }
802:
803: /*
804: * Described in header
805: */
806: encrypted_payload_t *encrypted_payload_create_from_plain(payload_type_t next,
807: chunk_t plain)
808: {
809: private_encrypted_payload_t *this;
810:
811: this = (private_encrypted_payload_t*)encrypted_payload_create(PLV2_ENCRYPTED);
812: this->public.payload_interface.get_length = _get_length_plain;
813: this->public.get_length = _get_length_plain;
814: this->public.decrypt = _decrypt_plain;
815: this->next_payload = next;
816: this->encrypted = plain;
817:
818: return &this->public;
819: }
820:
821: METHOD(payload_t, frag_verify, status_t,
822: private_encrypted_fragment_payload_t *this)
823: {
824: if (!this->fragment_number || !this->total_fragments ||
825: this->fragment_number > this->total_fragments)
826: {
827: DBG1(DBG_ENC, "invalid fragment number (%u) or total fragments (%u)",
828: this->fragment_number, this->total_fragments);
829: return FAILED;
830: }
831: if (this->fragment_number > 1 && this->next_payload != 0)
832: {
833: DBG1(DBG_ENC, "invalid next payload (%u) for fragment %u, ignored",
834: this->next_payload, this->fragment_number);
835: this->next_payload = 0;
836: }
837: return SUCCESS;
838: }
839:
840: METHOD(payload_t, frag_get_encoding_rules, int,
841: private_encrypted_fragment_payload_t *this, encoding_rule_t **rules)
842: {
843: *rules = encodings_fragment;
844: return countof(encodings_fragment);
845: }
846:
847: METHOD(payload_t, frag_get_header_length, int,
848: private_encrypted_fragment_payload_t *this)
849: {
850: return 8;
851: }
852:
853: METHOD(payload_t, frag_get_type, payload_type_t,
854: private_encrypted_fragment_payload_t *this)
855: {
856: return PLV2_FRAGMENT;
857: }
858:
859: METHOD(payload_t, frag_get_next_type, payload_type_t,
860: private_encrypted_fragment_payload_t *this)
861: {
862: return this->next_payload;
863: }
864:
865: METHOD(payload_t, frag_set_next_type, void,
866: private_encrypted_fragment_payload_t *this, payload_type_t type)
867: {
868: if (this->fragment_number == 1 && this->next_payload == PL_NONE)
869: {
870: this->next_payload = type;
871: }
872: }
873:
874: METHOD2(payload_t, encrypted_payload_t, frag_get_length, size_t,
875: private_encrypted_fragment_payload_t *this)
876: {
877: if (this->encrypted.len)
878: {
879: this->payload_length = this->encrypted.len;
880: }
881: else
882: {
883: this->payload_length = this->plain.len;
884:
885: if (this->aead)
886: {
887: this->payload_length += compute_overhead(this->aead,
888: this->payload_length);
889: }
890: }
891: this->payload_length += frag_get_header_length(this);
892: return this->payload_length;
893: }
894:
895: METHOD(encrypted_fragment_payload_t, get_fragment_number, uint16_t,
896: private_encrypted_fragment_payload_t *this)
897: {
898: return this->fragment_number;
899: }
900:
901: METHOD(encrypted_fragment_payload_t, get_total_fragments, uint16_t,
902: private_encrypted_fragment_payload_t *this)
903: {
904: return this->total_fragments;
905: }
906:
907: METHOD(encrypted_fragment_payload_t, frag_get_content, chunk_t,
908: private_encrypted_fragment_payload_t *this)
909: {
910: return this->plain;
911: }
912:
913: METHOD(encrypted_payload_t, frag_add_payload, void,
914: private_encrypted_fragment_payload_t *this, payload_t* payload)
915: {
916: payload->destroy(payload);
917: }
918:
919: METHOD(encrypted_payload_t, frag_set_transform, void,
920: private_encrypted_fragment_payload_t *this, aead_t* aead)
921: {
922: this->aead = aead;
923: }
924:
925: METHOD(encrypted_payload_t, frag_get_transform, aead_t*,
926: private_encrypted_fragment_payload_t *this)
927: {
928: return this->aead;
929: }
930:
931: /**
932: * Append the encrypted fragment payload header to the associated data
933: */
934: static chunk_t append_header_frag(private_encrypted_fragment_payload_t *this,
935: chunk_t assoc)
936: {
937: struct {
938: uint8_t next_payload;
939: uint8_t flags;
940: uint16_t length;
941: uint16_t fragment_number;
942: uint16_t total_fragments;
943: } __attribute__((packed)) header = {
944: .next_payload = this->next_payload,
945: .flags = this->flags,
946: .length = htons(frag_get_length(this)),
947: .fragment_number = htons(this->fragment_number),
948: .total_fragments = htons(this->total_fragments),
949: };
950: return chunk_cat("cc", assoc, chunk_from_thing(header));
951: }
952:
953: METHOD(encrypted_payload_t, frag_encrypt, status_t,
954: private_encrypted_fragment_payload_t *this, uint64_t mid, chunk_t assoc)
955: {
956: status_t status;
957:
958: if (!this->aead)
959: {
960: DBG1(DBG_ENC, "encrypting encrypted fragment payload failed, "
961: "transform missing");
962: return INVALID_STATE;
963: }
964: free(this->encrypted.ptr);
965: assoc = append_header_frag(this, assoc);
966: /* IKEv2 message IDs are not unique if fragmentation is used, hence include
967: * the fragment number to make it unique */
968: mid = mid << 32 | this->fragment_number;
969: status = encrypt_content("encrypted fragment payload", this->aead, mid,
970: this->plain, assoc, &this->encrypted);
971: free(assoc.ptr);
972: return status;
973: }
974:
975: METHOD(encrypted_payload_t, frag_decrypt, status_t,
976: private_encrypted_fragment_payload_t *this, chunk_t assoc)
977: {
978: status_t status;
979:
980: if (!this->aead)
981: {
982: DBG1(DBG_ENC, "decrypting encrypted fragment payload failed, "
983: "transform missing");
984: return INVALID_STATE;
985: }
986: free(this->plain.ptr);
987: assoc = append_header_frag(this, assoc);
988: status = decrypt_content("encrypted fragment payload", this->aead,
989: this->encrypted, assoc, &this->plain);
990: this->plain = chunk_clone(this->plain);
991: free(assoc.ptr);
992: return status;
993: }
994:
995: METHOD2(payload_t, encrypted_payload_t, frag_destroy, void,
996: private_encrypted_fragment_payload_t *this)
997: {
998: free(this->encrypted.ptr);
999: free(this->plain.ptr);
1000: free(this);
1001: }
1002:
1003: /*
1004: * Described in header
1005: */
1006: encrypted_fragment_payload_t *encrypted_fragment_payload_create()
1007: {
1008: private_encrypted_fragment_payload_t *this;
1009:
1010: INIT(this,
1011: .public = {
1012: .encrypted = {
1013: .payload_interface = {
1014: .verify = _frag_verify,
1015: .get_encoding_rules = _frag_get_encoding_rules,
1016: .get_header_length = _frag_get_header_length,
1017: .get_length = _frag_get_length,
1018: .get_next_type = _frag_get_next_type,
1019: .set_next_type = _frag_set_next_type,
1020: .get_type = _frag_get_type,
1021: .destroy = _frag_destroy,
1022: },
1023: .get_length = _frag_get_length,
1024: .add_payload = _frag_add_payload,
1025: .remove_payload = (void*)return_null,
1026: .generate_payloads = nop,
1027: .set_transform = _frag_set_transform,
1028: .get_transform = _frag_get_transform,
1029: .encrypt = _frag_encrypt,
1030: .decrypt = _frag_decrypt,
1031: .destroy = _frag_destroy,
1032: },
1033: .get_fragment_number = _get_fragment_number,
1034: .get_total_fragments = _get_total_fragments,
1035: .get_content = _frag_get_content,
1036: },
1037: .next_payload = PL_NONE,
1038: );
1039: this->payload_length = frag_get_header_length(this);
1040:
1041: return &this->public;
1042: }
1043:
1044: /*
1045: * Described in header
1046: */
1047: encrypted_fragment_payload_t *encrypted_fragment_payload_create_from_data(
1048: uint16_t num, uint16_t total, chunk_t plain)
1049: {
1050: private_encrypted_fragment_payload_t *this;
1051:
1052: this = (private_encrypted_fragment_payload_t*)encrypted_fragment_payload_create();
1053: this->fragment_number = num;
1054: this->total_fragments = total;
1055: this->plain = chunk_clone(plain);
1056:
1057: return &this->public;
1058: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>