1 | /* $NetBSD: xform_esp.c,v 1.46 2015/03/30 03:51:50 ozaki-r Exp $ */ |
2 | /* $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */ |
3 | /* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */ |
4 | |
5 | /* |
6 | * The authors of this code are John Ioannidis (ji@tla.org), |
7 | * Angelos D. Keromytis (kermit@csd.uch.gr) and |
8 | * Niels Provos (provos@physnet.uni-hamburg.de). |
9 | * |
10 | * The original version of this code was written by John Ioannidis |
11 | * for BSD/OS in Athens, Greece, in November 1995. |
12 | * |
13 | * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, |
14 | * by Angelos D. Keromytis. |
15 | * |
16 | * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis |
17 | * and Niels Provos. |
18 | * |
19 | * Additional features in 1999 by Angelos D. Keromytis. |
20 | * |
21 | * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, |
22 | * Angelos D. Keromytis and Niels Provos. |
23 | * Copyright (c) 2001 Angelos D. Keromytis. |
24 | * |
25 | * Permission to use, copy, and modify this software with or without fee |
26 | * is hereby granted, provided that this entire notice is included in |
27 | * all copies of any software which is or includes a copy or |
28 | * modification of this software. |
29 | * You may use this code under the GNU public license if you so wish. Please |
30 | * contribute changes back to the authors under this freer than GPL license |
31 | * so that we may further the use of strong encryption without limitations to |
32 | * all. |
33 | * |
34 | * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR |
35 | * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY |
36 | * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE |
37 | * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR |
38 | * PURPOSE. |
39 | */ |
40 | |
41 | #include <sys/cdefs.h> |
42 | __KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.46 2015/03/30 03:51:50 ozaki-r Exp $" ); |
43 | |
44 | #include "opt_inet.h" |
45 | #ifdef __FreeBSD__ |
46 | #include "opt_inet6.h" |
47 | #endif |
48 | #include "opt_ipsec.h" |
49 | |
50 | #include <sys/param.h> |
51 | #include <sys/systm.h> |
52 | #include <sys/mbuf.h> |
53 | #include <sys/socket.h> |
54 | #include <sys/syslog.h> |
55 | #include <sys/kernel.h> |
56 | /*#include <sys/random.h>*/ |
57 | #include <sys/sysctl.h> |
58 | #include <sys/socketvar.h> /* for softnet_lock */ |
59 | |
60 | #include <net/if.h> |
61 | |
62 | #include <netinet/in.h> |
63 | #include <netinet/in_systm.h> |
64 | #include <netinet/ip.h> |
65 | #include <netinet/ip_ecn.h> |
66 | #include <netinet/ip6.h> |
67 | |
68 | #include <net/route.h> |
69 | #include <netipsec/ipsec.h> |
70 | #include <netipsec/ipsec_private.h> |
71 | #include <netipsec/ah.h> |
72 | #include <netipsec/ah_var.h> |
73 | #include <netipsec/esp.h> |
74 | #include <netipsec/esp_var.h> |
75 | #include <netipsec/xform.h> |
76 | |
77 | #ifdef INET6 |
78 | #include <netinet6/ip6_var.h> |
79 | #include <netipsec/ipsec6.h> |
80 | # ifdef __FreeBSD__ |
81 | # include <netinet6/ip6_ecn.h> |
82 | # endif |
83 | #endif |
84 | |
85 | #include <netipsec/key.h> |
86 | #include <netipsec/key_debug.h> |
87 | |
88 | #include <netipsec/ipsec_osdep.h> |
89 | |
90 | #include <opencrypto/cryptodev.h> |
91 | #include <opencrypto/xform.h> |
92 | |
93 | percpu_t *espstat_percpu; |
94 | |
95 | int esp_enable = 1; |
96 | |
97 | #ifdef __FreeBSD__ |
98 | SYSCTL_DECL(_net_inet_esp); |
99 | SYSCTL_INT(_net_inet_esp, OID_AUTO, |
100 | esp_enable, CTLFLAG_RW, &esp_enable, 0, "" ); |
101 | SYSCTL_STRUCT(_net_inet_esp, IPSECCTL_STATS, |
102 | stats, CTLFLAG_RD, &espstat, espstat, "" ); |
103 | #endif /* __FreeBSD__ */ |
104 | |
105 | static int esp_max_ivlen; /* max iv length over all algorithms */ |
106 | |
107 | static int esp_input_cb(struct cryptop *op); |
108 | static int esp_output_cb(struct cryptop *crp); |
109 | |
110 | /* |
111 | * NB: this is public for use by the PF_KEY support. |
112 | * NB: if you add support here; be sure to add code to esp_attach below! |
113 | */ |
114 | const struct enc_xform * |
115 | esp_algorithm_lookup(int alg) |
116 | { |
117 | if (alg >= ESP_ALG_MAX) |
118 | return NULL; |
119 | switch (alg) { |
120 | case SADB_EALG_DESCBC: |
121 | return &enc_xform_des; |
122 | case SADB_EALG_3DESCBC: |
123 | return &enc_xform_3des; |
124 | case SADB_X_EALG_AES: |
125 | return &enc_xform_rijndael128; |
126 | case SADB_X_EALG_BLOWFISHCBC: |
127 | return &enc_xform_blf; |
128 | case SADB_X_EALG_CAST128CBC: |
129 | return &enc_xform_cast5; |
130 | case SADB_X_EALG_SKIPJACK: |
131 | return &enc_xform_skipjack; |
132 | case SADB_X_EALG_CAMELLIACBC: |
133 | return &enc_xform_camellia; |
134 | case SADB_X_EALG_AESCTR: |
135 | return &enc_xform_aes_ctr; |
136 | case SADB_X_EALG_AESGCM16: |
137 | return &enc_xform_aes_gcm; |
138 | case SADB_X_EALG_AESGMAC: |
139 | return &enc_xform_aes_gmac; |
140 | case SADB_EALG_NULL: |
141 | return &enc_xform_null; |
142 | } |
143 | return NULL; |
144 | } |
145 | |
146 | size_t |
147 | esp_hdrsiz(const struct secasvar *sav) |
148 | { |
149 | size_t size; |
150 | |
151 | if (sav != NULL) { |
152 | /*XXX not right for null algorithm--does it matter??*/ |
153 | IPSEC_ASSERT(sav->tdb_encalgxform != NULL, |
154 | ("esp_hdrsiz: SA with null xform" )); |
155 | if (sav->flags & SADB_X_EXT_OLD) |
156 | size = sizeof (struct esp); |
157 | else |
158 | size = sizeof (struct newesp); |
159 | size += sav->tdb_encalgxform->ivsize + 9; |
160 | /*XXX need alg check???*/ |
161 | if (sav->tdb_authalgxform != NULL && sav->replay) |
162 | size += ah_hdrsiz(sav); |
163 | } else { |
164 | /* |
165 | * base header size |
166 | * + max iv length for CBC mode |
167 | * + max pad length |
168 | * + sizeof (pad length field) |
169 | * + sizeof (next header field) |
170 | * + max icv supported. |
171 | */ |
172 | size = sizeof (struct newesp) + esp_max_ivlen + 9 + 16; |
173 | } |
174 | return size; |
175 | } |
176 | |
177 | /* |
178 | * esp_init() is called when an SPI is being set up. |
179 | */ |
180 | static int |
181 | esp_init(struct secasvar *sav, const struct xformsw *xsp) |
182 | { |
183 | const struct enc_xform *txform; |
184 | struct cryptoini cria, crie; |
185 | int keylen; |
186 | int error; |
187 | |
188 | txform = esp_algorithm_lookup(sav->alg_enc); |
189 | if (txform == NULL) { |
190 | DPRINTF(("esp_init: unsupported encryption algorithm %d\n" , |
191 | sav->alg_enc)); |
192 | return EINVAL; |
193 | } |
194 | if (sav->key_enc == NULL) { |
195 | DPRINTF(("esp_init: no encoding key for %s algorithm\n" , |
196 | txform->name)); |
197 | return EINVAL; |
198 | } |
199 | if ((sav->flags&(SADB_X_EXT_OLD|SADB_X_EXT_IV4B)) == SADB_X_EXT_IV4B) { |
200 | DPRINTF(("esp_init: 4-byte IV not supported with protocol\n" )); |
201 | return EINVAL; |
202 | } |
203 | keylen = _KEYLEN(sav->key_enc); |
204 | if (txform->minkey > keylen || keylen > txform->maxkey) { |
205 | DPRINTF(("esp_init: invalid key length %u, must be in " |
206 | "the range [%u..%u] for algorithm %s\n" , |
207 | keylen, txform->minkey, txform->maxkey, |
208 | txform->name)); |
209 | return EINVAL; |
210 | } |
211 | |
212 | sav->ivlen = txform->ivsize; |
213 | |
214 | /* |
215 | * Setup AH-related state. |
216 | */ |
217 | if (sav->alg_auth != 0) { |
218 | error = ah_init0(sav, xsp, &cria); |
219 | if (error) |
220 | return error; |
221 | } |
222 | |
223 | /* NB: override anything set in ah_init0 */ |
224 | sav->tdb_xform = xsp; |
225 | sav->tdb_encalgxform = txform; |
226 | |
227 | if (sav->alg_enc == SADB_X_EALG_AESGCM16 || |
228 | sav->alg_enc == SADB_X_EALG_AESGMAC) { |
229 | switch (keylen) { |
230 | case 20: |
231 | sav->alg_auth = SADB_X_AALG_AES128GMAC; |
232 | sav->tdb_authalgxform = &auth_hash_gmac_aes_128; |
233 | break; |
234 | case 28: |
235 | sav->alg_auth = SADB_X_AALG_AES192GMAC; |
236 | sav->tdb_authalgxform = &auth_hash_gmac_aes_192; |
237 | break; |
238 | case 36: |
239 | sav->alg_auth = SADB_X_AALG_AES256GMAC; |
240 | sav->tdb_authalgxform = &auth_hash_gmac_aes_256; |
241 | break; |
242 | } |
243 | memset(&cria, 0, sizeof(cria)); |
244 | cria.cri_alg = sav->tdb_authalgxform->type; |
245 | cria.cri_klen = _KEYBITS(sav->key_enc); |
246 | cria.cri_key = _KEYBUF(sav->key_enc); |
247 | } |
248 | |
249 | /* Initialize crypto session. */ |
250 | memset(&crie, 0, sizeof (crie)); |
251 | crie.cri_alg = sav->tdb_encalgxform->type; |
252 | crie.cri_klen = _KEYBITS(sav->key_enc); |
253 | crie.cri_key = _KEYBUF(sav->key_enc); |
254 | /* XXX Rounds ? */ |
255 | |
256 | if (sav->tdb_authalgxform && sav->tdb_encalgxform) { |
257 | /* init both auth & enc */ |
258 | crie.cri_next = &cria; |
259 | error = crypto_newsession(&sav->tdb_cryptoid, |
260 | &crie, crypto_support); |
261 | } else if (sav->tdb_encalgxform) { |
262 | error = crypto_newsession(&sav->tdb_cryptoid, |
263 | &crie, crypto_support); |
264 | } else if (sav->tdb_authalgxform) { |
265 | error = crypto_newsession(&sav->tdb_cryptoid, |
266 | &cria, crypto_support); |
267 | } else { |
268 | /* XXX cannot happen? */ |
269 | DPRINTF(("esp_init: no encoding OR authentication xform!\n" )); |
270 | error = EINVAL; |
271 | } |
272 | return error; |
273 | } |
274 | |
275 | /* |
276 | * Paranoia. |
277 | */ |
278 | static int |
279 | esp_zeroize(struct secasvar *sav) |
280 | { |
281 | /* NB: ah_zerorize free's the crypto session state */ |
282 | int error = ah_zeroize(sav); |
283 | |
284 | if (sav->key_enc) |
285 | memset(_KEYBUF(sav->key_enc), 0, _KEYLEN(sav->key_enc)); |
286 | sav->tdb_encalgxform = NULL; |
287 | sav->tdb_xform = NULL; |
288 | return error; |
289 | } |
290 | |
291 | /* |
292 | * ESP input processing, called (eventually) through the protocol switch. |
293 | */ |
294 | static int |
295 | esp_input(struct mbuf *m, const struct secasvar *sav, int skip, int protoff) |
296 | { |
297 | const struct auth_hash *esph; |
298 | const struct enc_xform *espx; |
299 | struct tdb_ident *tdbi; |
300 | struct tdb_crypto *tc; |
301 | int plen, alen, hlen, error; |
302 | struct m_tag *mtag; |
303 | struct newesp *esp; |
304 | |
305 | struct cryptodesc *crde; |
306 | struct cryptop *crp; |
307 | |
308 | IPSEC_SPLASSERT_SOFTNET("esp_input" ); |
309 | |
310 | IPSEC_ASSERT(sav != NULL, ("esp_input: null SA" )); |
311 | IPSEC_ASSERT(sav->tdb_encalgxform != NULL, |
312 | ("esp_input: null encoding xform" )); |
313 | IPSEC_ASSERT((skip&3) == 0 && (m->m_pkthdr.len&3) == 0, |
314 | ("esp_input: misaligned packet, skip %u pkt len %u" , |
315 | skip, m->m_pkthdr.len)); |
316 | |
317 | /* XXX don't pullup, just copy header */ |
318 | IP6_EXTHDR_GET(esp, struct newesp *, m, skip, sizeof (struct newesp)); |
319 | |
320 | esph = sav->tdb_authalgxform; |
321 | espx = sav->tdb_encalgxform; |
322 | |
323 | /* Determine the ESP header length */ |
324 | if (sav->flags & SADB_X_EXT_OLD) |
325 | hlen = sizeof (struct esp) + sav->ivlen; |
326 | else |
327 | hlen = sizeof (struct newesp) + sav->ivlen; |
328 | /* Authenticator hash size */ |
329 | alen = esph ? esph->authsize : 0; |
330 | |
331 | /* |
332 | * Verify payload length is multiple of encryption algorithm |
333 | * block size. |
334 | * |
335 | * NB: This works for the null algorithm because the blocksize |
336 | * is 4 and all packets must be 4-byte aligned regardless |
337 | * of the algorithm. |
338 | */ |
339 | plen = m->m_pkthdr.len - (skip + hlen + alen); |
340 | if ((plen & (espx->blocksize - 1)) || (plen <= 0)) { |
341 | DPRINTF(("esp_input: " |
342 | "payload of %d octets not a multiple of %d octets," |
343 | " SA %s/%08lx\n" , |
344 | plen, espx->blocksize, |
345 | ipsec_address(&sav->sah->saidx.dst), |
346 | (u_long) ntohl(sav->spi))); |
347 | ESP_STATINC(ESP_STAT_BADILEN); |
348 | m_freem(m); |
349 | return EINVAL; |
350 | } |
351 | |
352 | /* |
353 | * Check sequence number. |
354 | */ |
355 | if (esph && sav->replay && !ipsec_chkreplay(ntohl(esp->esp_seq), sav)) { |
356 | DPRINTF(("esp_input: packet replay check for %s\n" , |
357 | ipsec_logsastr(sav))); /*XXX*/ |
358 | ESP_STATINC(ESP_STAT_REPLAY); |
359 | m_freem(m); |
360 | return ENOBUFS; /*XXX*/ |
361 | } |
362 | |
363 | /* Update the counters */ |
364 | ESP_STATADD(ESP_STAT_IBYTES, m->m_pkthdr.len - skip - hlen - alen); |
365 | |
366 | /* Find out if we've already done crypto */ |
367 | for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL); |
368 | mtag != NULL; |
369 | mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) { |
370 | tdbi = (struct tdb_ident *) (mtag + 1); |
371 | if (tdbi->proto == sav->sah->saidx.proto && |
372 | tdbi->spi == sav->spi && |
373 | !memcmp(&tdbi->dst, &sav->sah->saidx.dst, |
374 | sizeof(union sockaddr_union))) |
375 | break; |
376 | } |
377 | |
378 | /* Get crypto descriptors */ |
379 | crp = crypto_getreq(esph && espx ? 2 : 1); |
380 | if (crp == NULL) { |
381 | DPRINTF(("esp_input: failed to acquire crypto descriptors\n" )); |
382 | ESP_STATINC(ESP_STAT_CRYPTO); |
383 | m_freem(m); |
384 | return ENOBUFS; |
385 | } |
386 | |
387 | /* Get IPsec-specific opaque pointer */ |
388 | if (esph == NULL || mtag != NULL) |
389 | tc = (struct tdb_crypto *) malloc(sizeof(struct tdb_crypto), |
390 | M_XDATA, M_NOWAIT|M_ZERO); |
391 | else |
392 | tc = (struct tdb_crypto *) malloc(sizeof(struct tdb_crypto) + alen, |
393 | M_XDATA, M_NOWAIT|M_ZERO); |
394 | if (tc == NULL) { |
395 | crypto_freereq(crp); |
396 | DPRINTF(("esp_input: failed to allocate tdb_crypto\n" )); |
397 | ESP_STATINC(ESP_STAT_CRYPTO); |
398 | m_freem(m); |
399 | return ENOBUFS; |
400 | } |
401 | |
402 | error = m_makewritable(&m, 0, m->m_pkthdr.len, M_NOWAIT); |
403 | if (error) { |
404 | m_freem(m); |
405 | free(tc, M_XDATA); |
406 | crypto_freereq(crp); |
407 | DPRINTF(("esp_input: m_makewritable failed\n" )); |
408 | ESP_STATINC(ESP_STAT_CRYPTO); |
409 | return error; |
410 | } |
411 | |
412 | tc->tc_ptr = mtag; |
413 | |
414 | if (esph) { |
415 | struct cryptodesc *crda = crp->crp_desc; |
416 | |
417 | IPSEC_ASSERT(crda != NULL, ("esp_input: null ah crypto descriptor" )); |
418 | |
419 | /* Authentication descriptor */ |
420 | crda->crd_skip = skip; |
421 | if (espx && espx->type == CRYPTO_AES_GCM_16) |
422 | crda->crd_len = hlen - sav->ivlen; |
423 | else |
424 | crda->crd_len = m->m_pkthdr.len - (skip + alen); |
425 | crda->crd_inject = m->m_pkthdr.len - alen; |
426 | |
427 | crda->crd_alg = esph->type; |
428 | if (espx && (espx->type == CRYPTO_AES_GCM_16 || |
429 | espx->type == CRYPTO_AES_GMAC)) { |
430 | crda->crd_key = _KEYBUF(sav->key_enc); |
431 | crda->crd_klen = _KEYBITS(sav->key_enc); |
432 | } else { |
433 | crda->crd_key = _KEYBUF(sav->key_auth); |
434 | crda->crd_klen = _KEYBITS(sav->key_auth); |
435 | } |
436 | |
437 | /* Copy the authenticator */ |
438 | if (mtag == NULL) |
439 | m_copydata(m, m->m_pkthdr.len - alen, alen, |
440 | (tc + 1)); |
441 | |
442 | /* Chain authentication request */ |
443 | crde = crda->crd_next; |
444 | } else { |
445 | crde = crp->crp_desc; |
446 | } |
447 | |
448 | /* Crypto operation descriptor */ |
449 | crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ |
450 | crp->crp_flags = CRYPTO_F_IMBUF; |
451 | crp->crp_buf = m; |
452 | crp->crp_callback = esp_input_cb; |
453 | crp->crp_sid = sav->tdb_cryptoid; |
454 | crp->crp_opaque = tc; |
455 | |
456 | /* These are passed as-is to the callback */ |
457 | tc->tc_spi = sav->spi; |
458 | tc->tc_dst = sav->sah->saidx.dst; |
459 | tc->tc_proto = sav->sah->saidx.proto; |
460 | tc->tc_protoff = protoff; |
461 | tc->tc_skip = skip; |
462 | |
463 | /* Decryption descriptor */ |
464 | if (espx) { |
465 | IPSEC_ASSERT(crde != NULL, ("esp_input: null esp crypto descriptor" )); |
466 | crde->crd_skip = skip + hlen; |
467 | if (espx->type == CRYPTO_AES_GMAC) |
468 | crde->crd_len = 0; |
469 | else |
470 | crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); |
471 | crde->crd_inject = skip + hlen - sav->ivlen; |
472 | |
473 | crde->crd_alg = espx->type; |
474 | crde->crd_key = _KEYBUF(sav->key_enc); |
475 | crde->crd_klen = _KEYBITS(sav->key_enc); |
476 | /* XXX Rounds ? */ |
477 | } |
478 | |
479 | if (mtag == NULL) |
480 | return crypto_dispatch(crp); |
481 | else |
482 | return esp_input_cb(crp); |
483 | } |
484 | |
485 | #ifdef INET6 |
486 | #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) do { \ |
487 | if (saidx->dst.sa.sa_family == AF_INET6) { \ |
488 | error = ipsec6_common_input_cb(m, sav, skip, protoff, mtag); \ |
489 | } else { \ |
490 | error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag); \ |
491 | } \ |
492 | } while (0) |
493 | #else |
494 | #define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag) \ |
495 | (error = ipsec4_common_input_cb(m, sav, skip, protoff, mtag)) |
496 | #endif |
497 | |
498 | /* |
499 | * ESP input callback from the crypto driver. |
500 | */ |
501 | static int |
502 | esp_input_cb(struct cryptop *crp) |
503 | { |
504 | u_int8_t lastthree[3], aalg[AH_ALEN_MAX]; |
505 | int s, hlen, skip, protoff, error; |
506 | struct mbuf *m; |
507 | struct cryptodesc *crd __diagused; |
508 | const struct auth_hash *esph; |
509 | struct tdb_crypto *tc; |
510 | struct m_tag *mtag; |
511 | struct secasvar *sav; |
512 | struct secasindex *saidx; |
513 | void *ptr; |
514 | u_int16_t dport; |
515 | u_int16_t sport; |
516 | |
517 | crd = crp->crp_desc; |
518 | IPSEC_ASSERT(crd != NULL, ("esp_input_cb: null crypto descriptor!" )); |
519 | |
520 | tc = (struct tdb_crypto *) crp->crp_opaque; |
521 | IPSEC_ASSERT(tc != NULL, ("esp_input_cb: null opaque crypto data area!" )); |
522 | skip = tc->tc_skip; |
523 | protoff = tc->tc_protoff; |
524 | mtag = (struct m_tag *) tc->tc_ptr; |
525 | m = (struct mbuf *) crp->crp_buf; |
526 | |
527 | /* find the source port for NAT-T */ |
528 | nat_t_ports_get(m, &dport, &sport); |
529 | |
530 | s = splsoftnet(); |
531 | mutex_enter(softnet_lock); |
532 | |
533 | sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, sport, dport); |
534 | if (sav == NULL) { |
535 | ESP_STATINC(ESP_STAT_NOTDB); |
536 | DPRINTF(("esp_input_cb: SA expired while in crypto " |
537 | "(SA %s/%08lx proto %u)\n" , ipsec_address(&tc->tc_dst), |
538 | (u_long) ntohl(tc->tc_spi), tc->tc_proto)); |
539 | error = ENOBUFS; /*XXX*/ |
540 | goto bad; |
541 | } |
542 | |
543 | saidx = &sav->sah->saidx; |
544 | IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET || |
545 | saidx->dst.sa.sa_family == AF_INET6, |
546 | ("esp_input_cb: unexpected protocol family %u" , |
547 | saidx->dst.sa.sa_family)); |
548 | |
549 | esph = sav->tdb_authalgxform; |
550 | |
551 | /* Check for crypto errors */ |
552 | if (crp->crp_etype) { |
553 | /* Reset the session ID */ |
554 | if (sav->tdb_cryptoid != 0) |
555 | sav->tdb_cryptoid = crp->crp_sid; |
556 | |
557 | if (crp->crp_etype == EAGAIN) { |
558 | KEY_FREESAV(&sav); |
559 | mutex_exit(softnet_lock); |
560 | splx(s); |
561 | return crypto_dispatch(crp); |
562 | } |
563 | |
564 | ESP_STATINC(ESP_STAT_NOXFORM); |
565 | DPRINTF(("esp_input_cb: crypto error %d\n" , crp->crp_etype)); |
566 | error = crp->crp_etype; |
567 | goto bad; |
568 | } |
569 | |
570 | /* Shouldn't happen... */ |
571 | if (m == NULL) { |
572 | ESP_STATINC(ESP_STAT_CRYPTO); |
573 | DPRINTF(("esp_input_cb: bogus returned buffer from crypto\n" )); |
574 | error = EINVAL; |
575 | goto bad; |
576 | } |
577 | ESP_STATINC(ESP_STAT_HIST + sav->alg_enc); |
578 | |
579 | /* If authentication was performed, check now. */ |
580 | if (esph != NULL) { |
581 | /* |
582 | * If we have a tag, it means an IPsec-aware NIC did |
583 | * the verification for us. Otherwise we need to |
584 | * check the authentication calculation. |
585 | */ |
586 | AH_STATINC(AH_STAT_HIST + sav->alg_auth); |
587 | if (mtag == NULL) { |
588 | /* Copy the authenticator from the packet */ |
589 | m_copydata(m, m->m_pkthdr.len - esph->authsize, |
590 | esph->authsize, aalg); |
591 | |
592 | ptr = (tc + 1); |
593 | |
594 | /* Verify authenticator */ |
595 | if (!consttime_memequal(ptr, aalg, esph->authsize)) { |
596 | DPRINTF(("esp_input_cb: " |
597 | "authentication hash mismatch for packet in SA %s/%08lx\n" , |
598 | ipsec_address(&saidx->dst), |
599 | (u_long) ntohl(sav->spi))); |
600 | ESP_STATINC(ESP_STAT_BADAUTH); |
601 | error = EACCES; |
602 | goto bad; |
603 | } |
604 | } |
605 | |
606 | /* Remove trailing authenticator */ |
607 | m_adj(m, -(esph->authsize)); |
608 | } |
609 | |
610 | /* Release the crypto descriptors */ |
611 | free(tc, M_XDATA), tc = NULL; |
612 | crypto_freereq(crp), crp = NULL; |
613 | |
614 | /* |
615 | * Packet is now decrypted. |
616 | */ |
617 | m->m_flags |= M_DECRYPTED; |
618 | |
619 | /* |
620 | * Update replay sequence number, if appropriate. |
621 | */ |
622 | if (sav->replay) { |
623 | u_int32_t seq; |
624 | |
625 | m_copydata(m, skip + offsetof(struct newesp, esp_seq), |
626 | sizeof (seq), &seq); |
627 | if (ipsec_updatereplay(ntohl(seq), sav)) { |
628 | DPRINTF(("%s: packet replay check for %s\n" , __func__, |
629 | ipsec_logsastr(sav))); |
630 | ESP_STATINC(ESP_STAT_REPLAY); |
631 | error = ENOBUFS; |
632 | goto bad; |
633 | } |
634 | } |
635 | |
636 | /* Determine the ESP header length */ |
637 | if (sav->flags & SADB_X_EXT_OLD) |
638 | hlen = sizeof (struct esp) + sav->ivlen; |
639 | else |
640 | hlen = sizeof (struct newesp) + sav->ivlen; |
641 | |
642 | /* Remove the ESP header and IV from the mbuf. */ |
643 | error = m_striphdr(m, skip, hlen); |
644 | if (error) { |
645 | ESP_STATINC(ESP_STAT_HDROPS); |
646 | DPRINTF(("esp_input_cb: bad mbuf chain, SA %s/%08lx\n" , |
647 | ipsec_address(&sav->sah->saidx.dst), |
648 | (u_long) ntohl(sav->spi))); |
649 | goto bad; |
650 | } |
651 | |
652 | /* Save the last three bytes of decrypted data */ |
653 | m_copydata(m, m->m_pkthdr.len - 3, 3, lastthree); |
654 | |
655 | /* Verify pad length */ |
656 | if (lastthree[1] + 2 > m->m_pkthdr.len - skip) { |
657 | ESP_STATINC(ESP_STAT_BADILEN); |
658 | DPRINTF(("esp_input_cb: invalid padding length %d " |
659 | "for %u byte packet in SA %s/%08lx\n" , |
660 | lastthree[1], m->m_pkthdr.len - skip, |
661 | ipsec_address(&sav->sah->saidx.dst), |
662 | (u_long) ntohl(sav->spi))); |
663 | error = EINVAL; |
664 | goto bad; |
665 | } |
666 | |
667 | /* Verify correct decryption by checking the last padding bytes */ |
668 | if ((sav->flags & SADB_X_EXT_PMASK) != SADB_X_EXT_PRAND) { |
669 | if (lastthree[1] != lastthree[0] && lastthree[1] != 0) { |
670 | ESP_STATINC(ESP_STAT_BADENC); |
671 | DPRINTF(("esp_input_cb: decryption failed " |
672 | "for packet in SA %s/%08lx\n" , |
673 | ipsec_address(&sav->sah->saidx.dst), |
674 | (u_long) ntohl(sav->spi))); |
675 | DPRINTF(("esp_input_cb: %x %x\n" , lastthree[0], lastthree[1])); |
676 | error = EINVAL; |
677 | goto bad; |
678 | } |
679 | } |
680 | |
681 | /* Trim the mbuf chain to remove trailing authenticator and padding */ |
682 | m_adj(m, -(lastthree[1] + 2)); |
683 | |
684 | /* Restore the Next Protocol field */ |
685 | m_copyback(m, protoff, sizeof (u_int8_t), lastthree + 2); |
686 | |
687 | IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag); |
688 | |
689 | KEY_FREESAV(&sav); |
690 | mutex_exit(softnet_lock); |
691 | splx(s); |
692 | return error; |
693 | bad: |
694 | if (sav) |
695 | KEY_FREESAV(&sav); |
696 | mutex_exit(softnet_lock); |
697 | splx(s); |
698 | if (m != NULL) |
699 | m_freem(m); |
700 | if (tc != NULL) |
701 | free(tc, M_XDATA); |
702 | if (crp != NULL) |
703 | crypto_freereq(crp); |
704 | return error; |
705 | } |
706 | |
707 | /* |
708 | * ESP output routine, called by ipsec[46]_process_packet(). |
709 | */ |
710 | static int |
711 | esp_output( |
712 | struct mbuf *m, |
713 | struct ipsecrequest *isr, |
714 | struct mbuf **mp, |
715 | int skip, |
716 | int protoff |
717 | ) |
718 | { |
719 | const struct enc_xform *espx; |
720 | const struct auth_hash *esph; |
721 | int hlen, rlen, padding, blks, alen, i, roff; |
722 | struct mbuf *mo = NULL; |
723 | struct tdb_crypto *tc; |
724 | const struct secasvar *sav; |
725 | struct secasindex *saidx; |
726 | unsigned char *pad; |
727 | u_int8_t prot; |
728 | int error, maxpacketsize; |
729 | |
730 | struct cryptodesc *crde = NULL, *crda = NULL; |
731 | struct cryptop *crp; |
732 | |
733 | IPSEC_SPLASSERT_SOFTNET("esp_output" ); |
734 | |
735 | sav = isr->sav; |
736 | IPSEC_ASSERT(sav != NULL, ("esp_output: null SA" )); |
737 | esph = sav->tdb_authalgxform; |
738 | espx = sav->tdb_encalgxform; |
739 | IPSEC_ASSERT(espx != NULL, ("esp_output: null encoding xform" )); |
740 | |
741 | if (sav->flags & SADB_X_EXT_OLD) |
742 | hlen = sizeof (struct esp) + sav->ivlen; |
743 | else |
744 | hlen = sizeof (struct newesp) + sav->ivlen; |
745 | |
746 | rlen = m->m_pkthdr.len - skip; /* Raw payload length. */ |
747 | /* |
748 | * NB: The null encoding transform has a blocksize of 4 |
749 | * so that headers are properly aligned. |
750 | */ |
751 | blks = espx->blocksize; /* IV blocksize */ |
752 | |
753 | /* XXX clamp padding length a la KAME??? */ |
754 | padding = ((blks - ((rlen + 2) % blks)) % blks) + 2; |
755 | |
756 | if (esph) |
757 | alen = esph->authsize; |
758 | else |
759 | alen = 0; |
760 | |
761 | ESP_STATINC(ESP_STAT_OUTPUT); |
762 | |
763 | saidx = &sav->sah->saidx; |
764 | /* Check for maximum packet size violations. */ |
765 | switch (saidx->dst.sa.sa_family) { |
766 | #ifdef INET |
767 | case AF_INET: |
768 | maxpacketsize = IP_MAXPACKET; |
769 | break; |
770 | #endif /* INET */ |
771 | #ifdef INET6 |
772 | case AF_INET6: |
773 | maxpacketsize = IPV6_MAXPACKET; |
774 | break; |
775 | #endif /* INET6 */ |
776 | default: |
777 | DPRINTF(("esp_output: unknown/unsupported protocol " |
778 | "family %d, SA %s/%08lx\n" , |
779 | saidx->dst.sa.sa_family, ipsec_address(&saidx->dst), |
780 | (u_long) ntohl(sav->spi))); |
781 | ESP_STATINC(ESP_STAT_NOPF); |
782 | error = EPFNOSUPPORT; |
783 | goto bad; |
784 | } |
785 | if (skip + hlen + rlen + padding + alen > maxpacketsize) { |
786 | DPRINTF(("esp_output: packet in SA %s/%08lx got too big " |
787 | "(len %u, max len %u)\n" , |
788 | ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi), |
789 | skip + hlen + rlen + padding + alen, maxpacketsize)); |
790 | ESP_STATINC(ESP_STAT_TOOBIG); |
791 | error = EMSGSIZE; |
792 | goto bad; |
793 | } |
794 | |
795 | /* Update the counters. */ |
796 | ESP_STATADD(ESP_STAT_OBYTES, m->m_pkthdr.len - skip); |
797 | |
798 | m = m_clone(m); |
799 | if (m == NULL) { |
800 | DPRINTF(("esp_output: cannot clone mbuf chain, SA %s/%08lx\n" , |
801 | ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi))); |
802 | ESP_STATINC(ESP_STAT_HDROPS); |
803 | error = ENOBUFS; |
804 | goto bad; |
805 | } |
806 | |
807 | /* Inject ESP header. */ |
808 | mo = m_makespace(m, skip, hlen, &roff); |
809 | if (mo == NULL) { |
810 | DPRINTF(("esp_output: failed to inject %u byte ESP hdr for SA " |
811 | "%s/%08lx\n" , |
812 | hlen, ipsec_address(&saidx->dst), |
813 | (u_long) ntohl(sav->spi))); |
814 | ESP_STATINC(ESP_STAT_HDROPS); /* XXX diffs from openbsd */ |
815 | error = ENOBUFS; |
816 | goto bad; |
817 | } |
818 | |
819 | /* Initialize ESP header. */ |
820 | memcpy(mtod(mo, char *) + roff, &sav->spi, sizeof(u_int32_t)); |
821 | if (sav->replay) { |
822 | u_int32_t replay; |
823 | |
824 | #ifdef IPSEC_DEBUG |
825 | /* Emulate replay attack when ipsec_replay is TRUE. */ |
826 | if (!ipsec_replay) |
827 | #endif |
828 | sav->replay->count++; |
829 | |
830 | replay = htonl(sav->replay->count); |
831 | bcopy(&replay, |
832 | mtod(mo,char *) + roff + sizeof(u_int32_t), |
833 | sizeof(u_int32_t)); |
834 | } |
835 | |
836 | /* |
837 | * Add padding -- better to do it ourselves than use the crypto engine, |
838 | * although if/when we support compression, we'd have to do that. |
839 | */ |
840 | pad = (u_char *) m_pad(m, padding + alen); |
841 | if (pad == NULL) { |
842 | DPRINTF(("esp_output: m_pad failed for SA %s/%08lx\n" , |
843 | ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi))); |
844 | m = NULL; /* NB: free'd by m_pad */ |
845 | error = ENOBUFS; |
846 | goto bad; |
847 | } |
848 | |
849 | /* |
850 | * Add padding: random, zero, or self-describing. |
851 | * XXX catch unexpected setting |
852 | */ |
853 | switch (sav->flags & SADB_X_EXT_PMASK) { |
854 | case SADB_X_EXT_PRAND: |
855 | (void) read_random(pad, padding - 2); |
856 | break; |
857 | case SADB_X_EXT_PZERO: |
858 | memset(pad, 0, padding - 2); |
859 | break; |
860 | case SADB_X_EXT_PSEQ: |
861 | for (i = 0; i < padding - 2; i++) |
862 | pad[i] = i+1; |
863 | break; |
864 | } |
865 | |
866 | /* Fix padding length and Next Protocol in padding itself. */ |
867 | pad[padding - 2] = padding - 2; |
868 | m_copydata(m, protoff, sizeof(u_int8_t), pad + padding - 1); |
869 | |
870 | /* Fix Next Protocol in IPv4/IPv6 header. */ |
871 | prot = IPPROTO_ESP; |
872 | m_copyback(m, protoff, sizeof(u_int8_t), (u_char *) &prot); |
873 | |
874 | /* Get crypto descriptors. */ |
875 | crp = crypto_getreq(esph && espx ? 2 : 1); |
876 | if (crp == NULL) { |
877 | DPRINTF(("esp_output: failed to acquire crypto descriptors\n" )); |
878 | ESP_STATINC(ESP_STAT_CRYPTO); |
879 | error = ENOBUFS; |
880 | goto bad; |
881 | } |
882 | |
883 | if (espx) { |
884 | crde = crp->crp_desc; |
885 | crda = crde->crd_next; |
886 | |
887 | /* Encryption descriptor. */ |
888 | crde->crd_skip = skip + hlen; |
889 | if (espx->type == CRYPTO_AES_GMAC) |
890 | crde->crd_len = 0; |
891 | else |
892 | crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen); |
893 | crde->crd_flags = CRD_F_ENCRYPT; |
894 | crde->crd_inject = skip + hlen - sav->ivlen; |
895 | |
896 | /* Encryption operation. */ |
897 | crde->crd_alg = espx->type; |
898 | crde->crd_key = _KEYBUF(sav->key_enc); |
899 | crde->crd_klen = _KEYBITS(sav->key_enc); |
900 | /* XXX Rounds ? */ |
901 | } else |
902 | crda = crp->crp_desc; |
903 | |
904 | /* IPsec-specific opaque crypto info. */ |
905 | tc = (struct tdb_crypto *) malloc(sizeof(struct tdb_crypto), |
906 | M_XDATA, M_NOWAIT|M_ZERO); |
907 | if (tc == NULL) { |
908 | crypto_freereq(crp); |
909 | DPRINTF(("esp_output: failed to allocate tdb_crypto\n" )); |
910 | ESP_STATINC(ESP_STAT_CRYPTO); |
911 | error = ENOBUFS; |
912 | goto bad; |
913 | } |
914 | |
915 | /* Callback parameters */ |
916 | tc->tc_isr = isr; |
917 | tc->tc_spi = sav->spi; |
918 | tc->tc_dst = saidx->dst; |
919 | tc->tc_proto = saidx->proto; |
920 | |
921 | /* Crypto operation descriptor. */ |
922 | crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ |
923 | crp->crp_flags = CRYPTO_F_IMBUF; |
924 | crp->crp_buf = m; |
925 | crp->crp_callback = esp_output_cb; |
926 | crp->crp_opaque = tc; |
927 | crp->crp_sid = sav->tdb_cryptoid; |
928 | |
929 | if (esph) { |
930 | /* Authentication descriptor. */ |
931 | crda->crd_skip = skip; |
932 | if (espx && espx->type == CRYPTO_AES_GCM_16) |
933 | crda->crd_len = hlen - sav->ivlen; |
934 | else |
935 | crda->crd_len = m->m_pkthdr.len - (skip + alen); |
936 | crda->crd_inject = m->m_pkthdr.len - alen; |
937 | |
938 | /* Authentication operation. */ |
939 | crda->crd_alg = esph->type; |
940 | if (espx && (espx->type == CRYPTO_AES_GCM_16 || |
941 | espx->type == CRYPTO_AES_GMAC)) { |
942 | crda->crd_key = _KEYBUF(sav->key_enc); |
943 | crda->crd_klen = _KEYBITS(sav->key_enc); |
944 | } else { |
945 | crda->crd_key = _KEYBUF(sav->key_auth); |
946 | crda->crd_klen = _KEYBITS(sav->key_auth); |
947 | } |
948 | } |
949 | |
950 | return crypto_dispatch(crp); |
951 | bad: |
952 | if (m) |
953 | m_freem(m); |
954 | return (error); |
955 | } |
956 | |
957 | /* |
958 | * ESP output callback from the crypto driver. |
959 | */ |
960 | static int |
961 | esp_output_cb(struct cryptop *crp) |
962 | { |
963 | struct tdb_crypto *tc; |
964 | struct ipsecrequest *isr; |
965 | struct secasvar *sav; |
966 | struct mbuf *m; |
967 | int s, err, error; |
968 | |
969 | tc = (struct tdb_crypto *) crp->crp_opaque; |
970 | IPSEC_ASSERT(tc != NULL, ("esp_output_cb: null opaque data area!" )); |
971 | m = (struct mbuf *) crp->crp_buf; |
972 | |
973 | s = splsoftnet(); |
974 | mutex_enter(softnet_lock); |
975 | |
976 | isr = tc->tc_isr; |
977 | sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi, 0, 0); |
978 | if (sav == NULL) { |
979 | ESP_STATINC(ESP_STAT_NOTDB); |
980 | DPRINTF(("esp_output_cb: SA expired while in crypto " |
981 | "(SA %s/%08lx proto %u)\n" , ipsec_address(&tc->tc_dst), |
982 | (u_long) ntohl(tc->tc_spi), tc->tc_proto)); |
983 | error = ENOBUFS; /*XXX*/ |
984 | goto bad; |
985 | } |
986 | IPSEC_ASSERT(isr->sav == sav, |
987 | ("esp_output_cb: SA changed was %p now %p\n" , isr->sav, sav)); |
988 | |
989 | /* Check for crypto errors. */ |
990 | if (crp->crp_etype) { |
991 | /* Reset session ID. */ |
992 | if (sav->tdb_cryptoid != 0) |
993 | sav->tdb_cryptoid = crp->crp_sid; |
994 | |
995 | if (crp->crp_etype == EAGAIN) { |
996 | KEY_FREESAV(&sav); |
997 | mutex_exit(softnet_lock); |
998 | splx(s); |
999 | return crypto_dispatch(crp); |
1000 | } |
1001 | |
1002 | ESP_STATINC(ESP_STAT_NOXFORM); |
1003 | DPRINTF(("esp_output_cb: crypto error %d\n" , crp->crp_etype)); |
1004 | error = crp->crp_etype; |
1005 | goto bad; |
1006 | } |
1007 | |
1008 | /* Shouldn't happen... */ |
1009 | if (m == NULL) { |
1010 | ESP_STATINC(ESP_STAT_CRYPTO); |
1011 | DPRINTF(("esp_output_cb: bogus returned buffer from crypto\n" )); |
1012 | error = EINVAL; |
1013 | goto bad; |
1014 | } |
1015 | ESP_STATINC(ESP_STAT_HIST + sav->alg_enc); |
1016 | if (sav->tdb_authalgxform != NULL) |
1017 | AH_STATINC(AH_STAT_HIST + sav->alg_auth); |
1018 | |
1019 | /* Release crypto descriptors. */ |
1020 | free(tc, M_XDATA); |
1021 | crypto_freereq(crp); |
1022 | |
1023 | #ifdef IPSEC_DEBUG |
1024 | /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ |
1025 | if (ipsec_integrity) { |
1026 | static unsigned char ipseczeroes[AH_ALEN_MAX]; |
1027 | const struct auth_hash *esph; |
1028 | |
1029 | /* |
1030 | * Corrupt HMAC if we want to test integrity verification of |
1031 | * the other side. |
1032 | */ |
1033 | esph = sav->tdb_authalgxform; |
1034 | if (esph != NULL) { |
1035 | m_copyback(m, m->m_pkthdr.len - esph->authsize, |
1036 | esph->authsize, ipseczeroes); |
1037 | } |
1038 | } |
1039 | #endif |
1040 | |
1041 | /* NB: m is reclaimed by ipsec_process_done. */ |
1042 | err = ipsec_process_done(m, isr); |
1043 | KEY_FREESAV(&sav); |
1044 | mutex_exit(softnet_lock); |
1045 | splx(s); |
1046 | return err; |
1047 | bad: |
1048 | if (sav) |
1049 | KEY_FREESAV(&sav); |
1050 | mutex_exit(softnet_lock); |
1051 | splx(s); |
1052 | if (m) |
1053 | m_freem(m); |
1054 | free(tc, M_XDATA); |
1055 | crypto_freereq(crp); |
1056 | return error; |
1057 | } |
1058 | |
1059 | static struct xformsw esp_xformsw = { |
1060 | XF_ESP, XFT_CONF|XFT_AUTH, "IPsec ESP" , |
1061 | esp_init, esp_zeroize, esp_input, |
1062 | esp_output, |
1063 | NULL, |
1064 | }; |
1065 | |
1066 | INITFN void |
1067 | esp_attach(void) |
1068 | { |
1069 | |
1070 | espstat_percpu = percpu_alloc(sizeof(uint64_t) * ESP_NSTATS); |
1071 | |
1072 | #define MAXIV(xform) \ |
1073 | if (xform.ivsize > esp_max_ivlen) \ |
1074 | esp_max_ivlen = xform.ivsize \ |
1075 | |
1076 | esp_max_ivlen = 0; |
1077 | MAXIV(enc_xform_des); /* SADB_EALG_DESCBC */ |
1078 | MAXIV(enc_xform_3des); /* SADB_EALG_3DESCBC */ |
1079 | MAXIV(enc_xform_rijndael128); /* SADB_X_EALG_AES */ |
1080 | MAXIV(enc_xform_blf); /* SADB_X_EALG_BLOWFISHCBC */ |
1081 | MAXIV(enc_xform_cast5); /* SADB_X_EALG_CAST128CBC */ |
1082 | MAXIV(enc_xform_skipjack); /* SADB_X_EALG_SKIPJACK */ |
1083 | MAXIV(enc_xform_camellia); /* SADB_X_EALG_CAMELLIACBC */ |
1084 | MAXIV(enc_xform_aes_ctr); /* SADB_X_EALG_AESCTR */ |
1085 | MAXIV(enc_xform_null); /* SADB_EALG_NULL */ |
1086 | |
1087 | xform_register(&esp_xformsw); |
1088 | #undef MAXIV |
1089 | } |
1090 | #ifdef __FreeBSD__ |
1091 | SYSINIT(esp_xform_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, esp_attach, NULL) |
1092 | #else |
1093 | #endif |
1094 | |