charon-nm: Set local address to %any so IPv6 may be used as outer address
[strongswan.git] / src / libipsec / esp_packet.c
1 /*
2 * Copyright (C) 2012-2013 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * HSR Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18
19 #include "esp_packet.h"
20
21 #include <library.h>
22 #include <utils/debug.h>
23 #include <crypto/crypters/crypter.h>
24 #include <crypto/signers/signer.h>
25 #include <bio/bio_reader.h>
26 #include <bio/bio_writer.h>
27
28 #ifndef WIN32
29 #include <netinet/in.h>
30 #endif
31
32 typedef struct private_esp_packet_t private_esp_packet_t;
33
34 /**
35 * Private additions to esp_packet_t.
36 */
37 struct private_esp_packet_t {
38
39 /**
40 * Public members
41 */
42 esp_packet_t public;
43
44 /**
45 * Raw ESP packet
46 */
47 packet_t *packet;
48
49 /**
50 * Payload of this packet
51 */
52 ip_packet_t *payload;
53
54 /**
55 * Next Header info (e.g. IPPROTO_IPIP)
56 */
57 uint8_t next_header;
58
59 };
60
61 /**
62 * Forward declaration for clone()
63 */
64 static private_esp_packet_t *esp_packet_create_internal(packet_t *packet);
65
66 METHOD(packet_t, set_source, void,
67 private_esp_packet_t *this, host_t *src)
68 {
69 return this->packet->set_source(this->packet, src);
70 }
71
72 METHOD2(esp_packet_t, packet_t, get_source, host_t*,
73 private_esp_packet_t *this)
74 {
75 return this->packet->get_source(this->packet);
76 }
77
78 METHOD(packet_t, set_destination, void,
79 private_esp_packet_t *this, host_t *dst)
80 {
81 return this->packet->set_destination(this->packet, dst);
82 }
83
84 METHOD2(esp_packet_t, packet_t, get_destination, host_t*,
85 private_esp_packet_t *this)
86 {
87 return this->packet->get_destination(this->packet);
88 }
89
90 METHOD(packet_t, get_data, chunk_t,
91 private_esp_packet_t *this)
92 {
93 return this->packet->get_data(this->packet);
94 }
95
96 METHOD(packet_t, set_data, void,
97 private_esp_packet_t *this, chunk_t data)
98 {
99 return this->packet->set_data(this->packet, data);
100 }
101
102 METHOD(packet_t, get_dscp, uint8_t,
103 private_esp_packet_t *this)
104 {
105 return this->packet->get_dscp(this->packet);
106 }
107
108 METHOD(packet_t, set_dscp, void,
109 private_esp_packet_t *this, uint8_t value)
110 {
111 this->packet->set_dscp(this->packet, value);
112 }
113
114 METHOD(packet_t, skip_bytes, void,
115 private_esp_packet_t *this, size_t bytes)
116 {
117 return this->packet->skip_bytes(this->packet, bytes);
118 }
119
120 METHOD(packet_t, clone_, packet_t*,
121 private_esp_packet_t *this)
122 {
123 private_esp_packet_t *pkt;
124
125 pkt = esp_packet_create_internal(this->packet->clone(this->packet));
126 pkt->payload = this->payload ? this->payload->clone(this->payload) : NULL;
127 pkt->next_header = this->next_header;
128 return &pkt->public.packet;
129 }
130
131 METHOD(esp_packet_t, parse_header, bool,
132 private_esp_packet_t *this, uint32_t *spi)
133 {
134 bio_reader_t *reader;
135 uint32_t seq;
136
137 reader = bio_reader_create(this->packet->get_data(this->packet));
138 if (!reader->read_uint32(reader, spi) ||
139 !reader->read_uint32(reader, &seq))
140 {
141 DBG1(DBG_ESP, "failed to parse ESP header: invalid length");
142 reader->destroy(reader);
143 return FALSE;
144 }
145 reader->destroy(reader);
146
147 DBG2(DBG_ESP, "parsed ESP header with SPI %.8x [seq %u]", *spi, seq);
148 *spi = htonl(*spi);
149 return TRUE;
150 }
151
152 /**
153 * Check padding as specified in RFC 4303
154 */
155 static bool check_padding(chunk_t padding)
156 {
157 size_t i;
158
159 for (i = 0; i < padding.len; ++i)
160 {
161 if (padding.ptr[i] != (uint8_t)(i + 1))
162 {
163 return FALSE;
164 }
165 }
166 return TRUE;
167 }
168
169 /**
170 * Remove the padding from the payload and set the next header info
171 */
172 static bool remove_padding(private_esp_packet_t *this, chunk_t plaintext)
173 {
174 uint8_t next_header, pad_length;
175 chunk_t padding, payload;
176 bio_reader_t *reader;
177
178 reader = bio_reader_create(plaintext);
179 if (!reader->read_uint8_end(reader, &next_header) ||
180 !reader->read_uint8_end(reader, &pad_length))
181 {
182 DBG1(DBG_ESP, "parsing ESP payload failed: invalid length");
183 goto failed;
184 }
185 if (!reader->read_data_end(reader, pad_length, &padding) ||
186 !check_padding(padding))
187 {
188 DBG1(DBG_ESP, "parsing ESP payload failed: invalid padding");
189 goto failed;
190 }
191 this->payload = ip_packet_create(reader->peek(reader));
192 reader->destroy(reader);
193 if (!this->payload)
194 {
195 DBG1(DBG_ESP, "parsing ESP payload failed: unsupported payload");
196 return FALSE;
197 }
198 this->next_header = next_header;
199 payload = this->payload->get_encoding(this->payload);
200
201 DBG3(DBG_ESP, "ESP payload:\n payload %B\n padding %B\n "
202 "padding length = %hhu, next header = %hhu", &payload, &padding,
203 pad_length, this->next_header);
204 return TRUE;
205
206 failed:
207 reader->destroy(reader);
208 chunk_free(&plaintext);
209 return FALSE;
210 }
211
212 METHOD(esp_packet_t, decrypt, status_t,
213 private_esp_packet_t *this, esp_context_t *esp_context)
214 {
215 bio_reader_t *reader;
216 uint32_t spi, seq;
217 chunk_t data, iv, icv, aad, ciphertext, plaintext;
218 aead_t *aead;
219
220 DESTROY_IF(this->payload);
221 this->payload = NULL;
222
223 data = this->packet->get_data(this->packet);
224 aead = esp_context->get_aead(esp_context);
225
226 reader = bio_reader_create(data);
227 if (!reader->read_uint32(reader, &spi) ||
228 !reader->read_uint32(reader, &seq) ||
229 !reader->read_data(reader, aead->get_iv_size(aead), &iv) ||
230 !reader->read_data_end(reader, aead->get_icv_size(aead), &icv) ||
231 reader->remaining(reader) % aead->get_block_size(aead))
232 {
233 DBG1(DBG_ESP, "ESP decryption failed: invalid length");
234 return PARSE_ERROR;
235 }
236 ciphertext = reader->peek(reader);
237 reader->destroy(reader);
238
239 if (!esp_context->verify_seqno(esp_context, seq))
240 {
241 DBG1(DBG_ESP, "ESP sequence number verification failed:\n "
242 "src %H, dst %H, SPI %.8x [seq %u]",
243 get_source(this), get_destination(this), spi, seq);
244 return VERIFY_ERROR;
245 }
246 DBG3(DBG_ESP, "ESP decryption:\n SPI %.8x [seq %u]\n IV %B\n "
247 "encrypted %B\n ICV %B", spi, seq, &iv, &ciphertext, &icv);
248
249 /* include ICV in ciphertext for decryption/verification */
250 ciphertext.len += icv.len;
251 /* aad = spi + seq */
252 aad = chunk_create(data.ptr, 8);
253
254 if (!aead->decrypt(aead, ciphertext, aad, iv, &plaintext))
255 {
256 DBG1(DBG_ESP, "ESP decryption or ICV verification failed");
257 return FAILED;
258 }
259 esp_context->set_authenticated_seqno(esp_context, seq);
260
261 if (!remove_padding(this, plaintext))
262 {
263 return PARSE_ERROR;
264 }
265 return SUCCESS;
266 }
267
268 /**
269 * Generate the padding as specified in RFC4303
270 */
271 static void generate_padding(chunk_t padding)
272 {
273 size_t i;
274
275 for (i = 0; i < padding.len; ++i)
276 {
277 padding.ptr[i] = (uint8_t)(i + 1);
278 }
279 }
280
281 METHOD(esp_packet_t, encrypt, status_t,
282 private_esp_packet_t *this, esp_context_t *esp_context, uint32_t spi)
283 {
284 chunk_t iv, icv, aad, padding, payload, ciphertext;
285 bio_writer_t *writer;
286 uint32_t next_seqno;
287 size_t blocksize, plainlen;
288 aead_t *aead;
289 iv_gen_t *iv_gen;
290
291 this->packet->set_data(this->packet, chunk_empty);
292
293 if (!esp_context->next_seqno(esp_context, &next_seqno))
294 {
295 DBG1(DBG_ESP, "ESP encapsulation failed: sequence numbers cycled");
296 return FAILED;
297 }
298
299 aead = esp_context->get_aead(esp_context);
300 iv_gen = aead->get_iv_gen(aead);
301 if (!iv_gen)
302 {
303 DBG1(DBG_ESP, "ESP encryption failed: no IV generator");
304 return NOT_FOUND;
305 }
306
307 blocksize = aead->get_block_size(aead);
308 iv.len = aead->get_iv_size(aead);
309 icv.len = aead->get_icv_size(aead);
310
311 /* plaintext = payload, padding, pad_length, next_header */
312 payload = this->payload ? this->payload->get_encoding(this->payload)
313 : chunk_empty;
314 plainlen = payload.len + 2;
315 padding.len = pad_len(plainlen, blocksize);
316 /* ICV must be on a 4-byte boundary */
317 padding.len += pad_len(iv.len + plainlen + padding.len, 4);
318 plainlen += padding.len;
319
320 /* len = spi, seq, IV, plaintext, ICV */
321 writer = bio_writer_create(2 * sizeof(uint32_t) + iv.len + plainlen +
322 icv.len);
323 writer->write_uint32(writer, ntohl(spi));
324 writer->write_uint32(writer, next_seqno);
325
326 iv = writer->skip(writer, iv.len);
327 if (!iv_gen->get_iv(iv_gen, next_seqno, iv.len, iv.ptr))
328 {
329 DBG1(DBG_ESP, "ESP encryption failed: could not generate IV");
330 writer->destroy(writer);
331 return FAILED;
332 }
333
334 /* plain-/ciphertext will start here */
335 ciphertext = writer->get_buf(writer);
336 ciphertext.ptr += ciphertext.len;
337 ciphertext.len = plainlen;
338
339 writer->write_data(writer, payload);
340
341 padding = writer->skip(writer, padding.len);
342 generate_padding(padding);
343
344 writer->write_uint8(writer, padding.len);
345 writer->write_uint8(writer, this->next_header);
346
347 /* aad = spi + seq */
348 aad = writer->get_buf(writer);
349 aad.len = 8;
350 icv = writer->skip(writer, icv.len);
351
352 DBG3(DBG_ESP, "ESP before encryption:\n payload = %B\n padding = %B\n "
353 "padding length = %hhu, next header = %hhu", &payload, &padding,
354 (uint8_t)padding.len, this->next_header);
355
356 /* encrypt/authenticate the content inline */
357 if (!aead->encrypt(aead, ciphertext, aad, iv, NULL))
358 {
359 DBG1(DBG_ESP, "ESP encryption or ICV generation failed");
360 writer->destroy(writer);
361 return FAILED;
362 }
363
364 DBG3(DBG_ESP, "ESP packet:\n SPI %.8x [seq %u]\n IV %B\n "
365 "encrypted %B\n ICV %B", ntohl(spi), next_seqno, &iv,
366 &ciphertext, &icv);
367
368 this->packet->set_data(this->packet, writer->extract_buf(writer));
369 writer->destroy(writer);
370 return SUCCESS;
371 }
372
373 METHOD(esp_packet_t, get_next_header, uint8_t,
374 private_esp_packet_t *this)
375 {
376 return this->next_header;
377 }
378
379 METHOD(esp_packet_t, get_payload, ip_packet_t*,
380 private_esp_packet_t *this)
381 {
382 return this->payload;
383 }
384
385 METHOD(esp_packet_t, extract_payload, ip_packet_t*,
386 private_esp_packet_t *this)
387 {
388 ip_packet_t *payload;
389
390 payload = this->payload;
391 this->payload = NULL;
392 return payload;
393 }
394
395 METHOD2(esp_packet_t, packet_t, destroy, void,
396 private_esp_packet_t *this)
397 {
398 DESTROY_IF(this->payload);
399 this->packet->destroy(this->packet);
400 free(this);
401 }
402
403 static private_esp_packet_t *esp_packet_create_internal(packet_t *packet)
404 {
405 private_esp_packet_t *this;
406
407 INIT(this,
408 .public = {
409 .packet = {
410 .set_source = _set_source,
411 .get_source = _get_source,
412 .set_destination = _set_destination,
413 .get_destination = _get_destination,
414 .get_data = _get_data,
415 .set_data = _set_data,
416 .get_dscp = _get_dscp,
417 .set_dscp = _set_dscp,
418 .skip_bytes = _skip_bytes,
419 .clone = _clone_,
420 .destroy = _destroy,
421 },
422 .get_source = _get_source,
423 .get_destination = _get_destination,
424 .get_next_header = _get_next_header,
425 .parse_header = _parse_header,
426 .decrypt = _decrypt,
427 .encrypt = _encrypt,
428 .get_payload = _get_payload,
429 .extract_payload = _extract_payload,
430 .destroy = _destroy,
431 },
432 .packet = packet,
433 .next_header = IPPROTO_NONE,
434 );
435 return this;
436 }
437
438 /**
439 * Described in header.
440 */
441 esp_packet_t *esp_packet_create_from_packet(packet_t *packet)
442 {
443 private_esp_packet_t *this;
444
445 this = esp_packet_create_internal(packet);
446
447 return &this->public;
448 }
449
450 /**
451 * Described in header.
452 */
453 esp_packet_t *esp_packet_create_from_payload(host_t *src, host_t *dst,
454 ip_packet_t *payload)
455 {
456 private_esp_packet_t *this;
457 packet_t *packet;
458
459 packet = packet_create_from_data(src, dst, chunk_empty);
460 this = esp_packet_create_internal(packet);
461 this->payload = payload;
462 if (payload)
463 {
464 this->next_header = payload->get_version(payload) == 4 ? IPPROTO_IPIP
465 : IPPROTO_IPV6;
466 }
467 else
468 {
469 this->next_header = IPPROTO_NONE;
470 }
471 return &this->public;
472 }