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