Line data Source code
1 : /* $OpenBSD: ip_esp.c,v 1.158 2018/08/28 15:15:02 mpi Exp $ */
2 : /*
3 : * The authors of this code are John Ioannidis (ji@tla.org),
4 : * Angelos D. Keromytis (kermit@csd.uch.gr) and
5 : * Niels Provos (provos@physnet.uni-hamburg.de).
6 : *
7 : * The original version of this code was written by John Ioannidis
8 : * for BSD/OS in Athens, Greece, in November 1995.
9 : *
10 : * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11 : * by Angelos D. Keromytis.
12 : *
13 : * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14 : * and Niels Provos.
15 : *
16 : * Additional features in 1999 by Angelos D. Keromytis.
17 : *
18 : * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19 : * Angelos D. Keromytis and Niels Provos.
20 : * Copyright (c) 2001 Angelos D. Keromytis.
21 : *
22 : * Permission to use, copy, and modify this software with or without fee
23 : * is hereby granted, provided that this entire notice is included in
24 : * all copies of any software which is or includes a copy or
25 : * modification of this software.
26 : * You may use this code under the GNU public license if you so wish. Please
27 : * contribute changes back to the authors under this freer than GPL license
28 : * so that we may further the use of strong encryption without limitations to
29 : * all.
30 : *
31 : * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
32 : * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
33 : * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
34 : * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
35 : * PURPOSE.
36 : */
37 :
38 : #include "pfsync.h"
39 :
40 : #include <sys/param.h>
41 : #include <sys/systm.h>
42 : #include <sys/mbuf.h>
43 : #include <sys/socket.h>
44 :
45 : #include <net/if.h>
46 : #include <net/if_var.h>
47 : #include <net/bpf.h>
48 :
49 : #include <netinet/in.h>
50 : #include <netinet/ip.h>
51 : #include <netinet/ip_var.h>
52 :
53 : #ifdef INET6
54 : #include <netinet/ip6.h>
55 : #endif /* INET6 */
56 :
57 : #include <netinet/ip_ipsp.h>
58 : #include <netinet/ip_esp.h>
59 : #include <net/pfkeyv2.h>
60 : #include <net/if_enc.h>
61 :
62 : #if NPFSYNC > 0
63 : #include <net/pfvar.h>
64 : #include <net/if_pfsync.h>
65 : #endif /* NPFSYNC > 0 */
66 :
67 : #include <crypto/cryptodev.h>
68 : #include <crypto/xform.h>
69 :
70 : #include "bpfilter.h"
71 :
72 : #ifdef ENCDEBUG
73 : #define DPRINTF(x) if (encdebug) printf x
74 : #else
75 : #define DPRINTF(x)
76 : #endif
77 :
78 : /*
79 : * esp_attach() is called from the transformation initialization code.
80 : */
81 : int
82 0 : esp_attach(void)
83 : {
84 0 : return 0;
85 : }
86 :
87 : /*
88 : * esp_init() is called when an SPI is being set up.
89 : */
90 : int
91 0 : esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
92 : {
93 : struct enc_xform *txform = NULL;
94 : struct auth_hash *thash = NULL;
95 0 : struct cryptoini cria, crie, crin;
96 :
97 0 : if (!ii->ii_encalg && !ii->ii_authalg) {
98 : DPRINTF(("esp_init(): neither authentication nor encryption "
99 : "algorithm given"));
100 0 : return EINVAL;
101 : }
102 :
103 0 : if (ii->ii_encalg) {
104 0 : switch (ii->ii_encalg) {
105 : case SADB_EALG_NULL:
106 : txform = &enc_xform_null;
107 0 : break;
108 :
109 : case SADB_EALG_3DESCBC:
110 : txform = &enc_xform_3des;
111 0 : break;
112 :
113 : case SADB_X_EALG_AES:
114 : txform = &enc_xform_aes;
115 0 : break;
116 :
117 : case SADB_X_EALG_AESCTR:
118 : txform = &enc_xform_aes_ctr;
119 0 : break;
120 :
121 : case SADB_X_EALG_AESGCM16:
122 : txform = &enc_xform_aes_gcm;
123 0 : break;
124 :
125 : case SADB_X_EALG_AESGMAC:
126 : txform = &enc_xform_aes_gmac;
127 0 : break;
128 :
129 : case SADB_X_EALG_CHACHA20POLY1305:
130 : txform = &enc_xform_chacha20_poly1305;
131 0 : break;
132 :
133 : case SADB_X_EALG_BLF:
134 : txform = &enc_xform_blf;
135 0 : break;
136 :
137 : case SADB_X_EALG_CAST:
138 : txform = &enc_xform_cast5;
139 0 : break;
140 :
141 : default:
142 : DPRINTF(("esp_init(): unsupported encryption "
143 : "algorithm %d specified\n", ii->ii_encalg));
144 0 : return EINVAL;
145 : }
146 :
147 0 : if (ii->ii_enckeylen < txform->minkey) {
148 : DPRINTF(("esp_init(): keylength %d too small "
149 : "(min length is %d) for algorithm %s\n",
150 : ii->ii_enckeylen, txform->minkey, txform->name));
151 0 : return EINVAL;
152 : }
153 :
154 0 : if (ii->ii_enckeylen > txform->maxkey) {
155 : DPRINTF(("esp_init(): keylength %d too large "
156 : "(max length is %d) for algorithm %s\n",
157 : ii->ii_enckeylen, txform->maxkey, txform->name));
158 0 : return EINVAL;
159 : }
160 :
161 0 : if (ii->ii_encalg == SADB_X_EALG_AESGCM16 ||
162 0 : ii->ii_encalg == SADB_X_EALG_AESGMAC) {
163 0 : switch (ii->ii_enckeylen) {
164 : case 20:
165 0 : ii->ii_authalg = SADB_X_AALG_AES128GMAC;
166 0 : break;
167 : case 28:
168 0 : ii->ii_authalg = SADB_X_AALG_AES192GMAC;
169 0 : break;
170 : case 36:
171 0 : ii->ii_authalg = SADB_X_AALG_AES256GMAC;
172 0 : break;
173 : }
174 0 : ii->ii_authkeylen = ii->ii_enckeylen;
175 0 : ii->ii_authkey = ii->ii_enckey;
176 0 : } else if (ii->ii_encalg == SADB_X_EALG_CHACHA20POLY1305) {
177 0 : ii->ii_authalg = SADB_X_AALG_CHACHA20POLY1305;
178 0 : ii->ii_authkeylen = ii->ii_enckeylen;
179 0 : ii->ii_authkey = ii->ii_enckey;
180 0 : }
181 :
182 0 : tdbp->tdb_encalgxform = txform;
183 :
184 : DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n",
185 : txform->name));
186 :
187 0 : tdbp->tdb_ivlen = txform->ivsize;
188 0 : }
189 :
190 0 : if (ii->ii_authalg) {
191 0 : switch (ii->ii_authalg) {
192 : case SADB_AALG_MD5HMAC:
193 : thash = &auth_hash_hmac_md5_96;
194 0 : break;
195 :
196 : case SADB_AALG_SHA1HMAC:
197 : thash = &auth_hash_hmac_sha1_96;
198 0 : break;
199 :
200 : case SADB_X_AALG_RIPEMD160HMAC:
201 : thash = &auth_hash_hmac_ripemd_160_96;
202 0 : break;
203 :
204 : case SADB_X_AALG_SHA2_256:
205 : thash = &auth_hash_hmac_sha2_256_128;
206 0 : break;
207 :
208 : case SADB_X_AALG_SHA2_384:
209 : thash = &auth_hash_hmac_sha2_384_192;
210 0 : break;
211 :
212 : case SADB_X_AALG_SHA2_512:
213 : thash = &auth_hash_hmac_sha2_512_256;
214 0 : break;
215 :
216 : case SADB_X_AALG_AES128GMAC:
217 : thash = &auth_hash_gmac_aes_128;
218 0 : break;
219 :
220 : case SADB_X_AALG_AES192GMAC:
221 : thash = &auth_hash_gmac_aes_192;
222 0 : break;
223 :
224 : case SADB_X_AALG_AES256GMAC:
225 : thash = &auth_hash_gmac_aes_256;
226 0 : break;
227 :
228 : case SADB_X_AALG_CHACHA20POLY1305:
229 : thash = &auth_hash_chacha20_poly1305;
230 0 : break;
231 :
232 : default:
233 : DPRINTF(("esp_init(): unsupported authentication "
234 : "algorithm %d specified\n", ii->ii_authalg));
235 0 : return EINVAL;
236 : }
237 :
238 0 : if (ii->ii_authkeylen != thash->keysize) {
239 : DPRINTF(("esp_init(): keylength %d doesn't match "
240 : "algorithm %s keysize (%d)\n", ii->ii_authkeylen,
241 : thash->name, thash->keysize));
242 0 : return EINVAL;
243 : }
244 :
245 0 : tdbp->tdb_authalgxform = thash;
246 :
247 : DPRINTF(("esp_init(): initialized TDB with hash algorithm %s\n",
248 : thash->name));
249 0 : }
250 :
251 0 : tdbp->tdb_xform = xsp;
252 0 : tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
253 :
254 : /* Initialize crypto session */
255 0 : if (tdbp->tdb_encalgxform) {
256 : /* Save the raw keys */
257 0 : tdbp->tdb_emxkeylen = ii->ii_enckeylen;
258 0 : tdbp->tdb_emxkey = malloc(tdbp->tdb_emxkeylen, M_XDATA,
259 : M_WAITOK);
260 0 : memcpy(tdbp->tdb_emxkey, ii->ii_enckey, tdbp->tdb_emxkeylen);
261 :
262 0 : memset(&crie, 0, sizeof(crie));
263 :
264 0 : crie.cri_alg = tdbp->tdb_encalgxform->type;
265 :
266 0 : if (tdbp->tdb_authalgxform)
267 0 : crie.cri_next = &cria;
268 : else
269 0 : crie.cri_next = NULL;
270 :
271 0 : crie.cri_klen = ii->ii_enckeylen * 8;
272 0 : crie.cri_key = ii->ii_enckey;
273 : /* XXX Rounds ? */
274 0 : }
275 :
276 0 : if (tdbp->tdb_authalgxform) {
277 : /* Save the raw keys */
278 0 : tdbp->tdb_amxkeylen = ii->ii_authkeylen;
279 0 : tdbp->tdb_amxkey = malloc(tdbp->tdb_amxkeylen, M_XDATA,
280 : M_WAITOK);
281 0 : memcpy(tdbp->tdb_amxkey, ii->ii_authkey, tdbp->tdb_amxkeylen);
282 :
283 0 : memset(&cria, 0, sizeof(cria));
284 :
285 0 : cria.cri_alg = tdbp->tdb_authalgxform->type;
286 :
287 0 : if ((tdbp->tdb_wnd > 0) && (tdbp->tdb_flags & TDBF_ESN)) {
288 0 : memset(&crin, 0, sizeof(crin));
289 0 : crin.cri_alg = CRYPTO_ESN;
290 0 : cria.cri_next = &crin;
291 0 : }
292 :
293 0 : cria.cri_klen = ii->ii_authkeylen * 8;
294 0 : cria.cri_key = ii->ii_authkey;
295 0 : }
296 :
297 0 : return crypto_newsession(&tdbp->tdb_cryptoid,
298 0 : (tdbp->tdb_encalgxform ? &crie : &cria), 0);
299 0 : }
300 :
301 : /*
302 : * Paranoia.
303 : */
304 : int
305 0 : esp_zeroize(struct tdb *tdbp)
306 : {
307 : int err;
308 :
309 0 : if (tdbp->tdb_amxkey) {
310 0 : explicit_bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
311 0 : free(tdbp->tdb_amxkey, M_XDATA, tdbp->tdb_amxkeylen);
312 0 : tdbp->tdb_amxkey = NULL;
313 0 : }
314 :
315 0 : if (tdbp->tdb_emxkey) {
316 0 : explicit_bzero(tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
317 0 : free(tdbp->tdb_emxkey, M_XDATA, tdbp->tdb_emxkeylen);
318 0 : tdbp->tdb_emxkey = NULL;
319 0 : }
320 :
321 0 : err = crypto_freesession(tdbp->tdb_cryptoid);
322 0 : tdbp->tdb_cryptoid = 0;
323 0 : return err;
324 : }
325 :
326 : #define MAXBUFSIZ (AH_ALEN_MAX > ESP_MAX_IVS ? AH_ALEN_MAX : ESP_MAX_IVS)
327 :
328 : /*
329 : * ESP input processing, called (eventually) through the protocol switch.
330 : */
331 : int
332 0 : esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
333 : {
334 0 : struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
335 0 : struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
336 : struct cryptodesc *crde = NULL, *crda = NULL;
337 : struct cryptop *crp = NULL;
338 : struct tdb_crypto *tc = NULL;
339 : int plen, alen, hlen, error;
340 0 : u_int32_t btsx, esn;
341 : u_int64_t ibytes;
342 : #ifdef ENCDEBUG
343 : char buf[INET6_ADDRSTRLEN];
344 : #endif
345 :
346 : /* Determine the ESP header length */
347 0 : hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
348 0 : alen = esph ? esph->authsize : 0;
349 0 : plen = m->m_pkthdr.len - (skip + hlen + alen);
350 0 : if (plen <= 0) {
351 : DPRINTF(("%s: invalid payload length\n", __func__));
352 0 : espstat_inc(esps_badilen);
353 : error = EINVAL;
354 0 : goto drop;
355 : }
356 :
357 0 : if (espx) {
358 : /*
359 : * Verify payload length is multiple of encryption algorithm
360 : * block size.
361 : */
362 0 : if (plen & (espx->blocksize - 1)) {
363 : DPRINTF(("%s: payload of %d octets not a multiple of %d"
364 : " octets, SA %s/%08x\n", __func__,
365 : plen, espx->blocksize, ipsp_address(&tdb->tdb_dst,
366 : buf, sizeof(buf)), ntohl(tdb->tdb_spi)));
367 0 : espstat_inc(esps_badilen);
368 : error = EINVAL;
369 0 : goto drop;
370 : }
371 : }
372 :
373 : /* Replay window checking, if appropriate -- no value commitment. */
374 0 : if (tdb->tdb_wnd > 0) {
375 0 : m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
376 : (unsigned char *) &btsx);
377 0 : btsx = ntohl(btsx);
378 :
379 0 : switch (checkreplaywindow(tdb, btsx, &esn, 0)) {
380 : case 0: /* All's well */
381 : break;
382 : case 1:
383 : DPRINTF(("%s: replay counter wrapped for SA %s/%08x\n",
384 : __func__,
385 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
386 : ntohl(tdb->tdb_spi)));
387 0 : espstat_inc(esps_wrap);
388 : error = EACCES;
389 0 : goto drop;
390 : case 2:
391 : DPRINTF(("%s: old packet received in SA %s/%08x\n",
392 : __func__,
393 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
394 : ntohl(tdb->tdb_spi)));
395 0 : espstat_inc(esps_replay);
396 : error = EACCES;
397 0 : goto drop;
398 : case 3:
399 : DPRINTF(("%s: duplicate packet received"
400 : " in SA %s/%08x\n", __func__,
401 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
402 : ntohl(tdb->tdb_spi)));
403 0 : espstat_inc(esps_replay);
404 : error = EACCES;
405 0 : goto drop;
406 : default:
407 : DPRINTF(("%s: bogus value from"
408 : " checkreplaywindow() in SA %s/%08x\n",
409 : __func__,
410 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
411 : ntohl(tdb->tdb_spi)));
412 0 : espstat_inc(esps_replay);
413 : error = EACCES;
414 0 : goto drop;
415 : }
416 : }
417 :
418 : /* Update the counters */
419 0 : ibytes = m->m_pkthdr.len - skip - hlen - alen;
420 0 : tdb->tdb_cur_bytes += ibytes;
421 0 : tdb->tdb_ibytes += ibytes;
422 0 : espstat_add(esps_ibytes, ibytes);
423 :
424 : /* Hard expiration */
425 0 : if ((tdb->tdb_flags & TDBF_BYTES) &&
426 0 : (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
427 0 : pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
428 0 : tdb_delete(tdb);
429 : error = ENXIO;
430 0 : goto drop;
431 : }
432 :
433 : /* Notify on soft expiration */
434 0 : if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
435 0 : (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
436 0 : pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
437 0 : tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */
438 0 : }
439 :
440 : /* Get crypto descriptors */
441 0 : crp = crypto_getreq(esph && espx ? 2 : 1);
442 0 : if (crp == NULL) {
443 : DPRINTF(("%s: failed to acquire crypto descriptors\n", __func__));
444 0 : espstat_inc(esps_crypto);
445 : error = ENOBUFS;
446 0 : goto drop;
447 : }
448 :
449 : /* Get IPsec-specific opaque pointer */
450 0 : if (esph == NULL)
451 0 : tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO);
452 : else
453 0 : tc = malloc(sizeof(*tc) + alen, M_XDATA, M_NOWAIT | M_ZERO);
454 0 : if (tc == NULL) {
455 : DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
456 0 : espstat_inc(esps_crypto);
457 : error = ENOBUFS;
458 0 : goto drop;
459 : }
460 :
461 0 : if (esph) {
462 : crda = &crp->crp_desc[0];
463 0 : crde = &crp->crp_desc[1];
464 :
465 : /* Authentication descriptor */
466 0 : crda->crd_skip = skip;
467 0 : crda->crd_inject = m->m_pkthdr.len - alen;
468 :
469 0 : crda->crd_alg = esph->type;
470 0 : crda->crd_key = tdb->tdb_amxkey;
471 0 : crda->crd_klen = tdb->tdb_amxkeylen * 8;
472 :
473 0 : if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN)) {
474 0 : esn = htonl(esn);
475 0 : memcpy(crda->crd_esn, &esn, 4);
476 0 : crda->crd_flags |= CRD_F_ESN;
477 0 : }
478 :
479 0 : if (espx &&
480 0 : (espx->type == CRYPTO_AES_GCM_16 ||
481 0 : espx->type == CRYPTO_CHACHA20_POLY1305))
482 0 : crda->crd_len = hlen - tdb->tdb_ivlen;
483 : else
484 0 : crda->crd_len = m->m_pkthdr.len - (skip + alen);
485 :
486 : /* Copy the authenticator */
487 0 : m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t)(tc + 1));
488 0 : } else
489 : crde = &crp->crp_desc[0];
490 :
491 : /* Crypto operation descriptor */
492 0 : crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
493 0 : crp->crp_flags = CRYPTO_F_IMBUF;
494 0 : crp->crp_buf = (caddr_t)m;
495 0 : crp->crp_callback = ipsec_input_cb;
496 0 : crp->crp_sid = tdb->tdb_cryptoid;
497 0 : crp->crp_opaque = (caddr_t)tc;
498 :
499 : /* These are passed as-is to the callback */
500 0 : tc->tc_skip = skip;
501 0 : tc->tc_protoff = protoff;
502 0 : tc->tc_spi = tdb->tdb_spi;
503 0 : tc->tc_proto = tdb->tdb_sproto;
504 0 : tc->tc_rdomain = tdb->tdb_rdomain;
505 0 : tc->tc_dst = tdb->tdb_dst;
506 :
507 : /* Decryption descriptor */
508 0 : if (espx) {
509 0 : crde->crd_skip = skip + hlen;
510 0 : crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
511 0 : crde->crd_alg = espx->type;
512 0 : crde->crd_key = tdb->tdb_emxkey;
513 0 : crde->crd_klen = tdb->tdb_emxkeylen * 8;
514 : /* XXX Rounds ? */
515 :
516 0 : if (crde->crd_alg == CRYPTO_AES_GMAC)
517 0 : crde->crd_len = 0;
518 : else
519 0 : crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
520 : }
521 :
522 0 : return crypto_dispatch(crp);
523 :
524 : drop:
525 0 : m_freem(m);
526 0 : crypto_freereq(crp);
527 0 : free(tc, M_XDATA, 0);
528 0 : return error;
529 0 : }
530 :
531 : /*
532 : * ESP input callback, called directly by the crypto driver.
533 : */
534 : int
535 0 : esp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen)
536 : {
537 0 : u_int8_t lastthree[3], aalg[AH_HMAC_MAX_HASHLEN];
538 0 : int hlen, roff, skip, protoff;
539 : struct mbuf *m1, *mo;
540 : struct auth_hash *esph;
541 0 : u_int32_t btsx, esn;
542 : caddr_t ptr;
543 : #ifdef ENCDEBUG
544 : char buf[INET6_ADDRSTRLEN];
545 : #endif
546 :
547 0 : skip = tc->tc_skip;
548 0 : protoff = tc->tc_protoff;
549 :
550 0 : NET_ASSERT_LOCKED();
551 :
552 0 : esph = (struct auth_hash *) tdb->tdb_authalgxform;
553 :
554 : /* If authentication was performed, check now. */
555 0 : if (esph != NULL) {
556 : /* Copy the authenticator from the packet */
557 0 : m_copydata(m, m->m_pkthdr.len - esph->authsize,
558 0 : esph->authsize, aalg);
559 :
560 0 : ptr = (caddr_t) (tc + 1);
561 :
562 : /* Verify authenticator */
563 0 : if (timingsafe_bcmp(ptr, aalg, esph->authsize)) {
564 : DPRINTF(("%s: authentication "
565 : "failed for packet in SA %s/%08x\n", __func__,
566 : ipsp_address(&tdb->tdb_dst, buf,
567 : sizeof(buf)), ntohl(tdb->tdb_spi)));
568 0 : espstat_inc(esps_badauth);
569 0 : goto baddone;
570 : }
571 :
572 : /* Remove trailing authenticator */
573 0 : m_adj(m, -(esph->authsize));
574 0 : }
575 :
576 : /* Replay window checking, if appropriate */
577 0 : if (tdb->tdb_wnd > 0) {
578 0 : m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
579 : (unsigned char *) &btsx);
580 0 : btsx = ntohl(btsx);
581 :
582 0 : switch (checkreplaywindow(tdb, btsx, &esn, 1)) {
583 : case 0: /* All's well */
584 : #if NPFSYNC > 0
585 0 : pfsync_update_tdb(tdb,0);
586 : #endif
587 : break;
588 :
589 : case 1:
590 : DPRINTF(("%s: replay counter wrapped for SA %s/%08x\n",
591 : __func__,
592 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
593 : ntohl(tdb->tdb_spi)));
594 0 : espstat_inc(esps_wrap);
595 0 : goto baddone;
596 : case 2:
597 : DPRINTF(("%s: old packet received in SA %s/%08x\n",
598 : __func__,
599 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
600 : ntohl(tdb->tdb_spi)));
601 0 : espstat_inc(esps_replay);
602 0 : goto baddone;
603 : case 3:
604 : DPRINTF(("%s: duplicate packet received"
605 : " in SA %s/%08x\n", __func__,
606 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
607 : ntohl(tdb->tdb_spi)));
608 0 : espstat_inc(esps_replay);
609 0 : goto baddone;
610 : default:
611 : DPRINTF(("%s: bogus value from"
612 : " checkreplaywindow() in SA %s/%08x\n", __func__,
613 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
614 : ntohl(tdb->tdb_spi)));
615 0 : espstat_inc(esps_replay);
616 0 : goto baddone;
617 : }
618 0 : }
619 :
620 : /* Determine the ESP header length */
621 0 : hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen;
622 :
623 : /* Find beginning of ESP header */
624 0 : m1 = m_getptr(m, skip, &roff);
625 0 : if (m1 == NULL) {
626 : DPRINTF(("%s: bad mbuf chain, SA %s/%08x\n", __func__,
627 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
628 : ntohl(tdb->tdb_spi)));
629 0 : espstat_inc(esps_hdrops);
630 0 : goto baddone;
631 : }
632 :
633 : /* Remove the ESP header and IV from the mbuf. */
634 0 : if (roff == 0) {
635 : /* The ESP header was conveniently at the beginning of the mbuf */
636 0 : m_adj(m1, hlen);
637 : /*
638 : * If m1 is the first mbuf, it has set M_PKTHDR and m_adj()
639 : * has already adjusted the packet header length for us.
640 : */
641 0 : if (m1 != m)
642 0 : m->m_pkthdr.len -= hlen;
643 0 : } else if (roff + hlen >= m1->m_len) {
644 : int adjlen;
645 :
646 : /*
647 : * Part or all of the ESP header is at the end of this mbuf, so
648 : * first let's remove the remainder of the ESP header from the
649 : * beginning of the remainder of the mbuf chain, if any.
650 : */
651 0 : if (roff + hlen > m1->m_len) {
652 0 : adjlen = roff + hlen - m1->m_len;
653 :
654 : /* Adjust the next mbuf by the remainder */
655 0 : m_adj(m1->m_next, adjlen);
656 :
657 : /* The second mbuf is guaranteed not to have a pkthdr */
658 0 : m->m_pkthdr.len -= adjlen;
659 0 : }
660 :
661 : /* Now, let's unlink the mbuf chain for a second...*/
662 0 : mo = m1->m_next;
663 0 : m1->m_next = NULL;
664 :
665 : /* ...and trim the end of the first part of the chain...sick */
666 0 : adjlen = m1->m_len - roff;
667 0 : m_adj(m1, -adjlen);
668 : /*
669 : * If m1 is the first mbuf, it has set M_PKTHDR and m_adj()
670 : * has already adjusted the packet header length for us.
671 : */
672 0 : if (m1 != m)
673 0 : m->m_pkthdr.len -= adjlen;
674 :
675 : /* Finally, let's relink */
676 0 : m1->m_next = mo;
677 0 : } else {
678 : /*
679 : * The ESP header lies in the "middle" of the mbuf...do an
680 : * overlapping copy of the remainder of the mbuf over the ESP
681 : * header.
682 : */
683 0 : memmove(mtod(m1, u_char *) + roff,
684 : mtod(m1, u_char *) + roff + hlen,
685 : m1->m_len - (roff + hlen));
686 0 : m1->m_len -= hlen;
687 0 : m->m_pkthdr.len -= hlen;
688 : }
689 :
690 : /* Save the last three bytes of decrypted data */
691 0 : m_copydata(m, m->m_pkthdr.len - 3, 3, lastthree);
692 :
693 : /* Verify pad length */
694 0 : if (lastthree[1] + 2 > m->m_pkthdr.len - skip) {
695 : DPRINTF(("%s: invalid padding length %d for packet in "
696 : "SA %s/%08x\n", __func__, lastthree[1],
697 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
698 : ntohl(tdb->tdb_spi)));
699 0 : espstat_inc(esps_badilen);
700 0 : goto baddone;
701 : }
702 :
703 : /* Verify correct decryption by checking the last padding bytes */
704 0 : if ((lastthree[1] != lastthree[0]) && (lastthree[1] != 0)) {
705 : DPRINTF(("%s: decryption failed for packet in SA %s/%08x\n",
706 : __func__, ipsp_address(&tdb->tdb_dst, buf,
707 : sizeof(buf)), ntohl(tdb->tdb_spi)));
708 0 : espstat_inc(esps_badenc);
709 0 : goto baddone;
710 : }
711 :
712 : /* Trim the mbuf chain to remove the trailing authenticator and padding */
713 0 : m_adj(m, -(lastthree[1] + 2));
714 :
715 : /* Restore the Next Protocol field */
716 0 : m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2, M_NOWAIT);
717 :
718 : /* Release the crypto descriptors */
719 0 : free(tc, M_XDATA, 0);
720 :
721 : /* Back to generic IPsec input processing */
722 0 : return ipsec_common_input_cb(m, tdb, skip, protoff);
723 :
724 : baddone:
725 0 : m_freem(m);
726 0 : free(tc, M_XDATA, 0);
727 0 : return -1;
728 0 : }
729 :
730 : /*
731 : * ESP output routine, called by ipsp_process_packet().
732 : */
733 : int
734 0 : esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
735 : int protoff)
736 : {
737 0 : struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
738 0 : struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
739 0 : int ilen, hlen, rlen, padding, blks, alen, roff, error;
740 : u_int32_t replay;
741 : struct mbuf *mi, *mo = (struct mbuf *) NULL;
742 : struct tdb_crypto *tc = NULL;
743 : unsigned char *pad;
744 0 : u_int8_t prot;
745 : #ifdef ENCDEBUG
746 : char buf[INET6_ADDRSTRLEN];
747 : #endif
748 : struct cryptodesc *crde = NULL, *crda = NULL;
749 : struct cryptop *crp = NULL;
750 : #if NBPFILTER > 0
751 : struct ifnet *encif;
752 :
753 0 : if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) != NULL) {
754 0 : encif->if_opackets++;
755 0 : encif->if_obytes += m->m_pkthdr.len;
756 :
757 0 : if (encif->if_bpf) {
758 0 : struct enchdr hdr;
759 :
760 0 : memset(&hdr, 0, sizeof(hdr));
761 :
762 0 : hdr.af = tdb->tdb_dst.sa.sa_family;
763 0 : hdr.spi = tdb->tdb_spi;
764 0 : if (espx)
765 0 : hdr.flags |= M_CONF;
766 0 : if (esph)
767 0 : hdr.flags |= M_AUTH;
768 :
769 0 : bpf_mtap_hdr(encif->if_bpf, (char *)&hdr,
770 : ENC_HDRLEN, m, BPF_DIRECTION_OUT, NULL);
771 0 : }
772 : }
773 : #endif
774 :
775 0 : hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen;
776 :
777 0 : rlen = m->m_pkthdr.len - skip; /* Raw payload length. */
778 0 : if (espx)
779 0 : blks = MAX(espx->blocksize, 4);
780 : else
781 : blks = 4; /* If no encryption, we have to be 4-byte aligned. */
782 :
783 0 : padding = ((blks - ((rlen + 2) % blks)) % blks) + 2;
784 :
785 0 : alen = esph ? esph->authsize : 0;
786 0 : espstat_inc(esps_output);
787 :
788 0 : switch (tdb->tdb_dst.sa.sa_family) {
789 : case AF_INET:
790 : /* Check for IP maximum packet size violations. */
791 0 : if (skip + hlen + rlen + padding + alen > IP_MAXPACKET) {
792 : DPRINTF(("%s: packet in SA %s/%08x got too big\n",
793 : __func__, ipsp_address(&tdb->tdb_dst, buf,
794 : sizeof(buf)),
795 : ntohl(tdb->tdb_spi)));
796 0 : espstat_inc(esps_toobig);
797 : error = EMSGSIZE;
798 0 : goto drop;
799 : }
800 : break;
801 :
802 : #ifdef INET6
803 : case AF_INET6:
804 : /* Check for IPv6 maximum packet size violations. */
805 0 : if (skip + hlen + rlen + padding + alen > IPV6_MAXPACKET) {
806 : DPRINTF(("%s: packet in SA %s/%08x got too big\n",
807 : __func__, ipsp_address(&tdb->tdb_dst, buf,
808 : sizeof(buf)), ntohl(tdb->tdb_spi)));
809 0 : espstat_inc(esps_toobig);
810 : error = EMSGSIZE;
811 0 : goto drop;
812 : }
813 : break;
814 : #endif /* INET6 */
815 :
816 : default:
817 : DPRINTF(("%s: unknown/unsupported protocol family %d, "
818 : "SA %s/%08x\n", __func__, tdb->tdb_dst.sa.sa_family,
819 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
820 : ntohl(tdb->tdb_spi)));
821 0 : espstat_inc(esps_nopf);
822 : error = EPFNOSUPPORT;
823 0 : goto drop;
824 : }
825 :
826 : /* Update the counters. */
827 0 : tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
828 0 : espstat_add(esps_obytes, m->m_pkthdr.len - skip);
829 :
830 : /* Hard byte expiration. */
831 0 : if (tdb->tdb_flags & TDBF_BYTES &&
832 0 : tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
833 0 : pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
834 0 : tdb_delete(tdb);
835 : error = EINVAL;
836 0 : goto drop;
837 : }
838 :
839 : /* Soft byte expiration. */
840 0 : if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
841 0 : tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
842 0 : pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
843 0 : tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking. */
844 0 : }
845 :
846 : /*
847 : * Loop through mbuf chain; if we find a readonly mbuf,
848 : * copy the packet.
849 : */
850 : mi = m;
851 0 : while (mi != NULL && !M_READONLY(mi))
852 0 : mi = mi->m_next;
853 :
854 0 : if (mi != NULL) {
855 0 : struct mbuf *n = m_dup_pkt(m, 0, M_DONTWAIT);
856 :
857 0 : if (n == NULL) {
858 : DPRINTF(("%s: bad mbuf chain, SA %s/%08x\n", __func__,
859 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
860 : ntohl(tdb->tdb_spi)));
861 0 : espstat_inc(esps_hdrops);
862 : error = ENOBUFS;
863 0 : goto drop;
864 : }
865 :
866 0 : m_freem(m);
867 : m = n;
868 0 : }
869 :
870 : /* Inject ESP header. */
871 0 : mo = m_makespace(m, skip, hlen, &roff);
872 0 : if (mo == NULL) {
873 : DPRINTF(("%s: failed to inject ESP header for SA %s/%08x\n",
874 : __func__, ipsp_address(&tdb->tdb_dst, buf,
875 : sizeof(buf)), ntohl(tdb->tdb_spi)));
876 0 : espstat_inc(esps_hdrops);
877 : error = ENOBUFS;
878 0 : goto drop;
879 : }
880 :
881 : /* Initialize ESP header. */
882 0 : memcpy(mtod(mo, caddr_t) + roff, (caddr_t) &tdb->tdb_spi,
883 : sizeof(u_int32_t));
884 0 : tdb->tdb_rpl++;
885 0 : replay = htonl((u_int32_t)tdb->tdb_rpl);
886 0 : memcpy(mtod(mo, caddr_t) + roff + sizeof(u_int32_t), (caddr_t) &replay,
887 : sizeof(u_int32_t));
888 :
889 : #if NPFSYNC > 0
890 0 : pfsync_update_tdb(tdb,1);
891 : #endif
892 :
893 : /*
894 : * Add padding -- better to do it ourselves than use the crypto engine,
895 : * although if/when we support compression, we'd have to do that.
896 : */
897 0 : mo = m_makespace(m, m->m_pkthdr.len, padding + alen, &roff);
898 0 : if (mo == NULL) {
899 : DPRINTF(("%s: m_makespace() failed for SA %s/%08x\n", __func__,
900 : ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
901 : ntohl(tdb->tdb_spi)));
902 0 : espstat_inc(esps_hdrops);
903 : error = ENOBUFS;
904 0 : goto drop;
905 : }
906 0 : pad = mtod(mo, caddr_t) + roff;
907 :
908 : /* Apply self-describing padding */
909 0 : for (ilen = 0; ilen < padding - 2; ilen++)
910 0 : pad[ilen] = ilen + 1;
911 :
912 : /* Fix padding length and Next Protocol in padding itself. */
913 0 : pad[padding - 2] = padding - 2;
914 0 : m_copydata(m, protoff, sizeof(u_int8_t), pad + padding - 1);
915 :
916 : /* Fix Next Protocol in IPv4/IPv6 header. */
917 0 : prot = IPPROTO_ESP;
918 0 : m_copyback(m, protoff, sizeof(u_int8_t), &prot, M_NOWAIT);
919 :
920 : /* Get crypto descriptors. */
921 0 : crp = crypto_getreq(esph && espx ? 2 : 1);
922 0 : if (crp == NULL) {
923 : DPRINTF(("%s: failed to acquire crypto descriptors\n",
924 : __func__));
925 0 : espstat_inc(esps_crypto);
926 : error = ENOBUFS;
927 0 : goto drop;
928 : }
929 :
930 0 : if (espx) {
931 : crde = &crp->crp_desc[0];
932 0 : crda = &crp->crp_desc[1];
933 :
934 : /* Encryption descriptor. */
935 0 : crde->crd_skip = skip + hlen;
936 0 : crde->crd_flags = CRD_F_ENCRYPT;
937 0 : crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
938 :
939 : /* Encryption operation. */
940 0 : crde->crd_alg = espx->type;
941 0 : crde->crd_key = tdb->tdb_emxkey;
942 0 : crde->crd_klen = tdb->tdb_emxkeylen * 8;
943 : /* XXX Rounds ? */
944 :
945 0 : if (crde->crd_alg == CRYPTO_AES_GMAC)
946 0 : crde->crd_len = 0;
947 : else
948 0 : crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
949 : } else
950 : crda = &crp->crp_desc[0];
951 :
952 : /* IPsec-specific opaque crypto info. */
953 0 : tc = malloc(sizeof(*tc), M_XDATA, M_NOWAIT | M_ZERO);
954 0 : if (tc == NULL) {
955 : DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
956 0 : espstat_inc(esps_crypto);
957 : error = ENOBUFS;
958 0 : goto drop;
959 : }
960 :
961 0 : tc->tc_spi = tdb->tdb_spi;
962 0 : tc->tc_proto = tdb->tdb_sproto;
963 0 : tc->tc_rdomain = tdb->tdb_rdomain;
964 0 : tc->tc_dst = tdb->tdb_dst;
965 :
966 : /* Crypto operation descriptor. */
967 0 : crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
968 0 : crp->crp_flags = CRYPTO_F_IMBUF;
969 0 : crp->crp_buf = (caddr_t)m;
970 0 : crp->crp_callback = ipsec_output_cb;
971 0 : crp->crp_opaque = (caddr_t)tc;
972 0 : crp->crp_sid = tdb->tdb_cryptoid;
973 :
974 0 : if (esph) {
975 : /* Authentication descriptor. */
976 0 : crda->crd_skip = skip;
977 0 : crda->crd_inject = m->m_pkthdr.len - alen;
978 :
979 : /* Authentication operation. */
980 0 : crda->crd_alg = esph->type;
981 0 : crda->crd_key = tdb->tdb_amxkey;
982 0 : crda->crd_klen = tdb->tdb_amxkeylen * 8;
983 :
984 0 : if ((tdb->tdb_wnd > 0) && (tdb->tdb_flags & TDBF_ESN)) {
985 : u_int32_t esn;
986 :
987 0 : esn = htonl((u_int32_t)(tdb->tdb_rpl >> 32));
988 0 : memcpy(crda->crd_esn, &esn, 4);
989 0 : crda->crd_flags |= CRD_F_ESN;
990 0 : }
991 :
992 0 : if (espx &&
993 0 : (espx->type == CRYPTO_AES_GCM_16 ||
994 0 : espx->type == CRYPTO_CHACHA20_POLY1305))
995 0 : crda->crd_len = hlen - tdb->tdb_ivlen;
996 : else
997 0 : crda->crd_len = m->m_pkthdr.len - (skip + alen);
998 : }
999 :
1000 0 : return crypto_dispatch(crp);
1001 :
1002 : drop:
1003 0 : m_freem(m);
1004 0 : crypto_freereq(crp);
1005 0 : free(tc, M_XDATA, 0);
1006 0 : return error;
1007 0 : }
1008 :
1009 : int
1010 0 : esp_output_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int ilen,
1011 : int olen)
1012 : {
1013 : /* Release crypto descriptors. */
1014 0 : free(tc, M_XDATA, 0);
1015 :
1016 : /* Call the IPsec input callback. */
1017 0 : if (ipsp_process_done(m, tdb)) {
1018 0 : espstat_inc(esps_outfail);
1019 0 : return -1;
1020 : }
1021 :
1022 0 : return 0;
1023 0 : }
1024 :
1025 : #define SEEN_SIZE howmany(TDB_REPLAYMAX, 32)
1026 :
1027 : /*
1028 : * return 0 on success
1029 : * return 1 for counter == 0
1030 : * return 2 for very old packet
1031 : * return 3 for packet within current window but already received
1032 : */
1033 : int
1034 0 : checkreplaywindow(struct tdb *tdb, u_int32_t seq, u_int32_t *seqh, int commit)
1035 : {
1036 : u_int32_t tl, th, wl;
1037 : u_int32_t packet, window = TDB_REPLAYMAX - TDB_REPLAYWASTE;
1038 0 : int idx, esn = tdb->tdb_flags & TDBF_ESN;
1039 :
1040 0 : tl = (u_int32_t)tdb->tdb_rpl;
1041 0 : th = (u_int32_t)(tdb->tdb_rpl >> 32);
1042 :
1043 : /* Zero SN is not allowed */
1044 0 : if ((esn && seq == 0 && tl <= AH_HMAC_INITIAL_RPL && th == 0) ||
1045 0 : (!esn && seq == 0))
1046 0 : return (1);
1047 :
1048 0 : if (th == 0 && tl < window)
1049 0 : window = tl;
1050 : /* Current replay window starts here */
1051 0 : wl = tl - window + 1;
1052 :
1053 0 : idx = (seq % TDB_REPLAYMAX) / 32;
1054 0 : packet = 1 << (31 - (seq & 31));
1055 :
1056 : /*
1057 : * We keep the high part intact when:
1058 : * 1) the SN is within [wl, 0xffffffff] and the whole window is
1059 : * within one subspace;
1060 : * 2) the SN is within [0, wl) and window spans two subspaces.
1061 : */
1062 0 : if ((tl >= window - 1 && seq >= wl) ||
1063 0 : (tl < window - 1 && seq < wl)) {
1064 0 : *seqh = th;
1065 0 : if (seq > tl) {
1066 0 : if (commit) {
1067 0 : if (seq - tl > window)
1068 0 : memset(tdb->tdb_seen, 0,
1069 : sizeof(tdb->tdb_seen));
1070 : else {
1071 0 : int i = (tl % TDB_REPLAYMAX) / 32;
1072 :
1073 0 : while (i != idx) {
1074 0 : i = (i + 1) % SEEN_SIZE;
1075 0 : tdb->tdb_seen[i] = 0;
1076 : }
1077 : }
1078 0 : tdb->tdb_seen[idx] |= packet;
1079 0 : tdb->tdb_rpl = ((u_int64_t)*seqh << 32) | seq;
1080 0 : }
1081 : } else {
1082 0 : if (tl - seq >= window)
1083 0 : return (2);
1084 0 : if (tdb->tdb_seen[idx] & packet)
1085 0 : return (3);
1086 0 : if (commit)
1087 0 : tdb->tdb_seen[idx] |= packet;
1088 : }
1089 0 : return (0);
1090 : }
1091 :
1092 : /* Can't wrap if not doing ESN */
1093 0 : if (!esn)
1094 0 : return (2);
1095 :
1096 : /*
1097 : * SN is within [wl, 0xffffffff] and wl is within
1098 : * [0xffffffff-window, 0xffffffff]. This means we got a SN
1099 : * which is within our replay window, but in the previous
1100 : * subspace.
1101 : */
1102 0 : if (tl < window - 1 && seq >= wl) {
1103 0 : if (tdb->tdb_seen[idx] & packet)
1104 0 : return (3);
1105 0 : *seqh = th - 1;
1106 0 : if (commit)
1107 0 : tdb->tdb_seen[idx] |= packet;
1108 0 : return (0);
1109 : }
1110 :
1111 : /*
1112 : * SN has wrapped and the last authenticated SN is in the old
1113 : * subspace.
1114 : */
1115 0 : *seqh = th + 1;
1116 0 : if (*seqh == 0) /* Don't let high bit to wrap */
1117 0 : return (1);
1118 0 : if (commit) {
1119 0 : if (seq - tl > window)
1120 0 : memset(tdb->tdb_seen, 0, sizeof(tdb->tdb_seen));
1121 : else {
1122 0 : int i = (tl % TDB_REPLAYMAX) / 32;
1123 :
1124 0 : while (i != idx) {
1125 0 : i = (i + 1) % SEEN_SIZE;
1126 0 : tdb->tdb_seen[i] = 0;
1127 : }
1128 : }
1129 0 : tdb->tdb_seen[idx] |= packet;
1130 0 : tdb->tdb_rpl = ((u_int64_t)*seqh << 32) | seq;
1131 0 : }
1132 :
1133 0 : return (0);
1134 0 : }
|