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