Use modified encryption payload to encrypt/decrypt complete IKEv1 messages.
[strongswan.git] / src / libcharon / encoding / payloads / encryption_payload.c
1 /*
2 * Copyright (C) 2005-2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 * Copyright (C) 2011 Tobias Brunner
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 "encryption_payload.h"
23
24 #include <daemon.h>
25 #include <encoding/payloads/encodings.h>
26 #include <utils/linked_list.h>
27 #include <encoding/generator.h>
28 #include <encoding/parser.h>
29
30 typedef struct private_encryption_payload_t private_encryption_payload_t;
31
32 /**
33 * Private data of an encryption_payload_t' Object.
34 *
35 */
36 struct private_encryption_payload_t {
37
38 /**
39 * Public encryption_payload_t interface.
40 */
41 encryption_payload_t public;
42
43 /**
44 * There is no next payload for an encryption payload,
45 * since encryption payload MUST be the last one.
46 * next_payload means here the first payload of the
47 * contained, encrypted payload.
48 */
49 u_int8_t next_payload;
50
51 /**
52 * Flags, including reserved bits
53 */
54 u_int8_t flags;
55
56 /**
57 * Length of this payload
58 */
59 u_int16_t payload_length;
60
61 /**
62 * Chunk containing the IV, plain, padding and ICV.
63 */
64 chunk_t encrypted;
65
66 /**
67 * AEAD transform to use
68 */
69 aead_t *aead;
70
71 /**
72 * Contained payloads
73 */
74 linked_list_t *payloads;
75
76 /**
77 * Type of payload, ENCRYPTED or ENCRYPTED_V1
78 */
79 payload_type_t type;
80 };
81
82 /**
83 * Encoding rules to parse or generate a IKEv2-Encryption Payload.
84 *
85 * The defined offsets are the positions in a object of type
86 * private_encryption_payload_t.
87 */
88 static encoding_rule_t encodings_v2[] = {
89 /* 1 Byte next payload type, stored in the field next_payload */
90 { U_INT_8, offsetof(private_encryption_payload_t, next_payload) },
91 /* Critical and 7 reserved bits, all stored for reconstruction */
92 { U_INT_8, offsetof(private_encryption_payload_t, flags) },
93 /* Length of the whole encryption payload*/
94 { PAYLOAD_LENGTH, offsetof(private_encryption_payload_t, payload_length) },
95 /* encrypted data, stored in a chunk. contains iv, data, padding */
96 { CHUNK_DATA, offsetof(private_encryption_payload_t, encrypted) },
97 };
98
99 /*
100 1 2 3
101 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
102 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103 ! Next Payload !C! RESERVED ! Payload Length !
104 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105 ! Initialization Vector !
106 ! (length is block size for encryption algorithm) !
107 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108 ! Encrypted IKE Payloads !
109 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110 ! ! Padding (0-255 octets) !
111 +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
112 ! ! Pad Length !
113 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
114 ~ Integrity Checksum Data ~
115 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116 */
117
118 /**
119 * Encoding rules to parse or generate a complete encrypted IKEv1 message.
120 *
121 * The defined offsets are the positions in a object of type
122 * private_encryption_payload_t.
123 */
124 static encoding_rule_t encodings_v1[] = {
125 /* encrypted data, stored in a chunk */
126 { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) },
127 };
128
129 /*
130 1 2 3
131 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
132 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
133 ! Message Length !
134 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
135 ! Encrypted IKE Payloads !
136 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
137 ! ! Padding (0-255 octets) !
138 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139 */
140
141 METHOD(payload_t, verify, status_t,
142 private_encryption_payload_t *this)
143 {
144 return SUCCESS;
145 }
146
147 METHOD(payload_t, get_encoding_rules, int,
148 private_encryption_payload_t *this, encoding_rule_t **rules)
149 {
150 if (this->type == ENCRYPTED)
151 {
152 *rules = encodings_v2;
153 return countof(encodings_v2);
154 }
155 *rules = encodings_v1;
156 return countof(encodings_v1);
157 }
158
159 METHOD(payload_t, get_header_length, int,
160 private_encryption_payload_t *this)
161 {
162 if (this->type == ENCRYPTED)
163 {
164 return 4;
165 }
166 return 0;
167 }
168
169 METHOD(payload_t, get_type, payload_type_t,
170 private_encryption_payload_t *this)
171 {
172 return this->type;
173 }
174
175 METHOD(payload_t, get_next_type, payload_type_t,
176 private_encryption_payload_t *this)
177 {
178 return this->next_payload;
179 }
180
181 METHOD(payload_t, set_next_type, void,
182 private_encryption_payload_t *this, payload_type_t type)
183 {
184 /* the next payload is set during add, still allow this for IKEv1 */
185 this->next_payload = type;
186 }
187
188 /**
189 * Compute the length of the whole payload
190 */
191 static void compute_length(private_encryption_payload_t *this)
192 {
193 enumerator_t *enumerator;
194 payload_t *payload;
195 size_t bs, length = 0;
196
197 if (this->encrypted.len)
198 {
199 length = this->encrypted.len;
200 }
201 else
202 {
203 enumerator = this->payloads->create_enumerator(this->payloads);
204 while (enumerator->enumerate(enumerator, &payload))
205 {
206 length += payload->get_length(payload);
207 }
208 enumerator->destroy(enumerator);
209
210 if (this->aead)
211 {
212 /* append padding */
213 bs = this->aead->get_block_size(this->aead);
214 length += bs - (length % bs);
215 /* add iv */
216 length += this->aead->get_iv_size(this->aead);
217 /* add icv */
218 length += this->aead->get_icv_size(this->aead);
219 }
220 }
221 length += get_header_length(this);
222 this->payload_length = length;
223 }
224
225 METHOD2(payload_t, encryption_payload_t, get_length, size_t,
226 private_encryption_payload_t *this)
227 {
228 compute_length(this);
229 return this->payload_length;
230 }
231
232 METHOD(encryption_payload_t, add_payload, void,
233 private_encryption_payload_t *this, payload_t *payload)
234 {
235 payload_t *last_payload;
236
237 if (this->payloads->get_count(this->payloads) > 0)
238 {
239 this->payloads->get_last(this->payloads, (void **)&last_payload);
240 last_payload->set_next_type(last_payload, payload->get_type(payload));
241 }
242 else
243 {
244 this->next_payload = payload->get_type(payload);
245 }
246 payload->set_next_type(payload, NO_PAYLOAD);
247 this->payloads->insert_last(this->payloads, payload);
248 compute_length(this);
249 }
250
251 METHOD(encryption_payload_t, remove_payload, payload_t *,
252 private_encryption_payload_t *this)
253 {
254 payload_t *payload;
255
256 if (this->payloads->remove_first(this->payloads,
257 (void**)&payload) == SUCCESS)
258 {
259 return payload;
260 }
261 return NULL;
262 }
263
264 /**
265 * Generate payload before encryption
266 */
267 static chunk_t generate(private_encryption_payload_t *this,
268 generator_t *generator)
269 {
270 payload_t *current, *next;
271 enumerator_t *enumerator;
272 u_int32_t *lenpos;
273 chunk_t chunk = chunk_empty;
274
275 enumerator = this->payloads->create_enumerator(this->payloads);
276 if (enumerator->enumerate(enumerator, &current))
277 {
278 this->next_payload = current->get_type(current);
279
280 while (enumerator->enumerate(enumerator, &next))
281 {
282 current->set_next_type(current, next->get_type(next));
283 generator->generate_payload(generator, current);
284 current = next;
285 }
286 current->set_next_type(current, NO_PAYLOAD);
287 generator->generate_payload(generator, current);
288
289 chunk = generator->get_chunk(generator, &lenpos);
290 DBG2(DBG_ENC, "generated content in encryption payload");
291 }
292 enumerator->destroy(enumerator);
293 return chunk;
294 }
295
296 /**
297 * Append the encryption payload header to the associated data
298 */
299 static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc)
300 {
301 struct {
302 u_int8_t next_payload;
303 u_int8_t flags;
304 u_int16_t length;
305 } __attribute__((packed)) header = {
306 .next_payload = this->next_payload,
307 .flags = this->flags,
308 .length = htons(get_length(this)),
309 };
310 return chunk_cat("cc", assoc, chunk_from_thing(header));
311 }
312
313 METHOD(encryption_payload_t, encrypt, bool,
314 private_encryption_payload_t *this, chunk_t assoc)
315 {
316 chunk_t iv, plain, padding, icv, crypt;
317 generator_t *generator;
318 rng_t *rng;
319 size_t bs;
320
321 if (this->aead == NULL)
322 {
323 DBG1(DBG_ENC, "encrypting encryption payload failed, transform missing");
324 return FALSE;
325 }
326
327 rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
328 if (!rng)
329 {
330 DBG1(DBG_ENC, "encrypting encryption payload failed, no RNG found");
331 return FALSE;
332 }
333
334 assoc = append_header(this, assoc);
335
336 generator = generator_create();
337 plain = generate(this, generator);
338 bs = this->aead->get_block_size(this->aead);
339 /* we need at least one byte padding to store the padding length */
340 padding.len = bs - (plain.len % bs);
341 iv.len = this->aead->get_iv_size(this->aead);
342 icv.len = this->aead->get_icv_size(this->aead);
343
344 /* prepare data to authenticate-encrypt:
345 * | IV | plain | padding | ICV |
346 * \____crypt______/ ^
347 * | /
348 * v /
349 * assoc -> + ------->/
350 */
351 free(this->encrypted.ptr);
352 this->encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len);
353 iv.ptr = this->encrypted.ptr;
354 memcpy(iv.ptr + iv.len, plain.ptr, plain.len);
355 plain.ptr = iv.ptr + iv.len;
356 padding.ptr = plain.ptr + plain.len;
357 icv.ptr = padding.ptr + padding.len;
358 crypt = chunk_create(plain.ptr, plain.len + padding.len);
359 generator->destroy(generator);
360
361 rng->get_bytes(rng, iv.len, iv.ptr);
362 rng->get_bytes(rng, padding.len - 1, padding.ptr);
363 padding.ptr[padding.len - 1] = padding.len - 1;
364 rng->destroy(rng);
365
366 DBG3(DBG_ENC, "encryption payload encryption:");
367 DBG3(DBG_ENC, "IV %B", &iv);
368 DBG3(DBG_ENC, "plain %B", &plain);
369 DBG3(DBG_ENC, "padding %B", &padding);
370 DBG3(DBG_ENC, "assoc %B", &assoc);
371
372 this->aead->encrypt(this->aead, crypt, assoc, iv, NULL);
373
374 DBG3(DBG_ENC, "encrypted %B", &crypt);
375 DBG3(DBG_ENC, "ICV %B", &icv);
376
377 free(assoc.ptr);
378
379 return TRUE;
380 }
381
382 METHOD(encryption_payload_t, encrypt_v1, bool,
383 private_encryption_payload_t *this, chunk_t iv)
384 {
385 generator_t *generator;
386 chunk_t plain, padding;
387 size_t bs;
388
389 if (this->aead == NULL)
390 {
391 DBG1(DBG_ENC, "encryption failed, transform missing");
392 chunk_free(&iv);
393 return FALSE;
394 }
395
396 generator = generator_create();
397 plain = generate(this, generator);
398 bs = this->aead->get_block_size(this->aead);
399 padding.len = bs - (plain.len % bs);
400
401 /* prepare data to encrypt:
402 * | plain | padding | */
403 free(this->encrypted.ptr);
404 this->encrypted = chunk_alloc(plain.len + padding.len);
405 memcpy(this->encrypted.ptr, plain.ptr, plain.len);
406 plain.ptr = this->encrypted.ptr;
407 padding.ptr = plain.ptr + plain.len;
408 memset(padding.ptr, 0, padding.len);
409 generator->destroy(generator);
410
411 DBG3(DBG_ENC, "encrypting payloads:");
412 DBG3(DBG_ENC, "plain %B", &plain);
413 DBG3(DBG_ENC, "padding %B", &padding);
414
415 this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL);
416 chunk_free(&iv);
417
418 DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
419
420 return TRUE;
421 }
422
423 /**
424 * Parse the payloads after decryption.
425 */
426 static status_t parse(private_encryption_payload_t *this, chunk_t plain)
427 {
428 parser_t *parser;
429 payload_type_t type;
430
431 parser = parser_create(plain);
432 type = this->next_payload;
433 while (type != NO_PAYLOAD)
434 {
435 payload_t *payload;
436
437 if (parser->parse_payload(parser, type, &payload) != SUCCESS)
438 {
439 parser->destroy(parser);
440 return PARSE_ERROR;
441 }
442 if (payload->verify(payload) != SUCCESS)
443 {
444 DBG1(DBG_ENC, "%N verification failed",
445 payload_type_names, payload->get_type(payload));
446 payload->destroy(payload);
447 parser->destroy(parser);
448 return VERIFY_ERROR;
449 }
450 type = payload->get_next_type(payload);
451 this->payloads->insert_last(this->payloads, payload);
452 }
453 parser->destroy(parser);
454 DBG2(DBG_ENC, "parsed content of encryption payload");
455 return SUCCESS;
456 }
457
458 METHOD(encryption_payload_t, decrypt, status_t,
459 private_encryption_payload_t *this, chunk_t assoc)
460 {
461 chunk_t iv, plain, padding, icv, crypt;
462 size_t bs;
463
464 if (this->aead == NULL)
465 {
466 DBG1(DBG_ENC, "decrypting encryption payload failed, transform missing");
467 return INVALID_STATE;
468 }
469
470 /* prepare data to authenticate-decrypt:
471 * | IV | plain | padding | ICV |
472 * \____crypt______/ ^
473 * | /
474 * v /
475 * assoc -> + ------->/
476 */
477
478 bs = this->aead->get_block_size(this->aead);
479 iv.len = this->aead->get_iv_size(this->aead);
480 iv.ptr = this->encrypted.ptr;
481 icv.len = this->aead->get_icv_size(this->aead);
482 icv.ptr = this->encrypted.ptr + this->encrypted.len - icv.len;
483 crypt.ptr = iv.ptr + iv.len;
484 crypt.len = this->encrypted.len - iv.len;
485
486 if (iv.len + icv.len > this->encrypted.len ||
487 (crypt.len - icv.len) % bs)
488 {
489 DBG1(DBG_ENC, "decrypting encryption payload failed, invalid length");
490 return FAILED;
491 }
492
493 assoc = append_header(this, assoc);
494
495 DBG3(DBG_ENC, "encryption payload decryption:");
496 DBG3(DBG_ENC, "IV %B", &iv);
497 DBG3(DBG_ENC, "encrypted %B", &crypt);
498 DBG3(DBG_ENC, "ICV %B", &icv);
499 DBG3(DBG_ENC, "assoc %B", &assoc);
500
501 if (!this->aead->decrypt(this->aead, crypt, assoc, iv, NULL))
502 {
503 DBG1(DBG_ENC, "verifying encryption payload integrity failed");
504 free(assoc.ptr);
505 return FAILED;
506 }
507 free(assoc.ptr);
508
509 plain = chunk_create(crypt.ptr, crypt.len - icv.len);
510 padding.len = plain.ptr[plain.len - 1] + 1;
511 if (padding.len > plain.len)
512 {
513 DBG1(DBG_ENC, "decrypting encryption payload failed, "
514 "padding invalid %B", &crypt);
515 return PARSE_ERROR;
516 }
517 plain.len -= padding.len;
518 padding.ptr = plain.ptr + plain.len;
519
520 DBG3(DBG_ENC, "plain %B", &plain);
521 DBG3(DBG_ENC, "padding %B", &padding);
522
523 return parse(this, plain);
524 }
525
526 METHOD(encryption_payload_t, decrypt_v1, status_t,
527 private_encryption_payload_t *this, chunk_t iv)
528 {
529 if (this->aead == NULL)
530 {
531 DBG1(DBG_ENC, "decryption failed, transform missing");
532 chunk_free(&iv);
533 return INVALID_STATE;
534 }
535
536 /* data must be a multiple of block size */
537 if (iv.len != this->aead->get_block_size(this->aead) ||
538 this->encrypted.len < iv.len || this->encrypted.len % iv.len)
539 {
540 DBG1(DBG_ENC, "decryption failed, invalid length");
541 chunk_free(&iv);
542 return FAILED;
543 }
544
545 DBG3(DBG_ENC, "decrypting payloads:");
546 DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
547
548 this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL);
549 chunk_free(&iv);
550
551 DBG3(DBG_ENC, "plain %B", &this->encrypted);
552
553 return parse(this, this->encrypted);
554 }
555
556 METHOD(encryption_payload_t, set_transform, void,
557 private_encryption_payload_t *this, aead_t* aead)
558 {
559 this->aead = aead;
560 }
561
562 METHOD2(payload_t, encryption_payload_t, destroy, void,
563 private_encryption_payload_t *this)
564 {
565 this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
566 free(this->encrypted.ptr);
567 free(this);
568 }
569
570 /*
571 * Described in header
572 */
573 encryption_payload_t *encryption_payload_create(payload_type_t type)
574 {
575 private_encryption_payload_t *this;
576
577 INIT(this,
578 .public = {
579 .payload_interface = {
580 .verify = _verify,
581 .get_encoding_rules = _get_encoding_rules,
582 .get_header_length = _get_header_length,
583 .get_length = _get_length,
584 .get_next_type = _get_next_type,
585 .set_next_type = _set_next_type,
586 .get_type = _get_type,
587 .destroy = _destroy,
588 },
589 .get_length = _get_length,
590 .add_payload = _add_payload,
591 .remove_payload = _remove_payload,
592 .set_transform = _set_transform,
593 .encrypt = _encrypt,
594 .decrypt = _decrypt,
595 .destroy = _destroy,
596 },
597 .next_payload = NO_PAYLOAD,
598 .payload_length = get_header_length(this),
599 .payloads = linked_list_create(),
600 .type = type,
601 );
602
603 if (type == ENCRYPTED_V1)
604 {
605 this->public.encrypt = _encrypt_v1;
606 this->public.decrypt = _decrypt_v1;
607 }
608
609 return &this->public;
610 }