From 173a0d4a18fc85fb24673e846edb09f017eefe19 Mon Sep 17 00:00:00 2001 From: maxv Date: Wed, 30 May 2018 16:32:26 +0000 Subject: [PATCH] Simplify the padding computation. Until now 'padlen' contained the ESP Trailer (two bytes), and we were doing minus two all the time. Declare 'tlen', which contains padlen+ESP_Trailer+ICV, and use 'struct esptail' instead of hardcoding the construction of the trailer. 'padlen' now indicates only the length of the padding, so no need to do -2. --- sys/netipsec/xform_esp.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index bf9a086ba387..d1fd7eec4f07 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -1,4 +1,4 @@ -/* $NetBSD: xform_esp.c,v 1.90 2018/05/30 16:15:19 maxv Exp $ */ +/* $NetBSD: xform_esp.c,v 1.91 2018/05/30 16:32:26 maxv Exp $ */ /* $FreeBSD: xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $ */ /* $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */ @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.90 2018/05/30 16:15:19 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.91 2018/05/30 16:32:26 maxv Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -687,13 +687,14 @@ esp_output(struct mbuf *m, const struct ipsecrequest *isr, struct secasvar *sav, char buf[IPSEC_ADDRSTRLEN]; const struct enc_xform *espx; const struct auth_hash *esph; - int hlen, rlen, padlen, blks, alen, i, roff; + int hlen, rlen, tlen, padlen, blks, alen, i, roff; struct mbuf *mo = NULL; struct tdb_crypto *tc; struct secasindex *saidx; unsigned char *tail; uint8_t prot; int error, maxpacketsize; + struct esptail *esptail; struct cryptodesc *crde = NULL, *crda = NULL; struct cryptop *crp; @@ -721,8 +722,11 @@ esp_output(struct mbuf *m, const struct ipsecrequest *isr, struct secasvar *sav, /* Raw payload length. */ rlen = m->m_pkthdr.len - skip; - /* XXX clamp padding length a la KAME??? */ - padlen = ((blks - ((rlen + 2) % blks)) % blks) + 2; + /* Encryption padding. */ + padlen = ((blks - ((rlen + sizeof(struct esptail)) % blks)) % blks); + + /* Length of what we append (tail). */ + tlen = padlen + sizeof(struct esptail) + alen; ESP_STATINC(ESP_STAT_OUTPUT); @@ -748,12 +752,12 @@ esp_output(struct mbuf *m, const struct ipsecrequest *isr, struct secasvar *sav, error = EPFNOSUPPORT; goto bad; } - if (skip + hlen + rlen + padlen + alen > maxpacketsize) { + if (skip + hlen + rlen + tlen > maxpacketsize) { DPRINTF(("%s: packet in SA %s/%08lx got too big (len %u, " "max len %u)\n", __func__, ipsec_address(&saidx->dst, buf, sizeof(buf)), (u_long) ntohl(sav->spi), - skip + hlen + rlen + padlen + alen, maxpacketsize)); + skip + hlen + rlen + tlen, maxpacketsize)); ESP_STATINC(ESP_STAT_TOOBIG); error = EMSGSIZE; goto bad; @@ -803,7 +807,7 @@ esp_output(struct mbuf *m, const struct ipsecrequest *isr, struct secasvar *sav, /* * Grow the mbuf, we will append data at the tail. */ - tail = m_pad(m, padlen + alen); + tail = m_pad(m, tlen); if (tail == NULL) { DPRINTF(("%s: m_pad failed for SA %s/%08lx\n", __func__, ipsec_address(&saidx->dst, buf, sizeof(buf)), @@ -818,21 +822,22 @@ esp_output(struct mbuf *m, const struct ipsecrequest *isr, struct secasvar *sav, */ switch (sav->flags & SADB_X_EXT_PMASK) { case SADB_X_EXT_PSEQ: - for (i = 0; i < padlen - 2; i++) + for (i = 0; i < padlen; i++) tail[i] = i + 1; break; case SADB_X_EXT_PRAND: - (void)cprng_fast(tail, padlen - 2); + (void)cprng_fast(tail, padlen); break; case SADB_X_EXT_PZERO: default: - memset(tail, 0, padlen - 2); + memset(tail, 0, padlen); break; } - /* Fix padding length and Next Protocol in padding itself. */ - tail[padlen - 2] = padlen - 2; - m_copydata(m, protoff, sizeof(uint8_t), tail + padlen - 1); + /* Build the ESP Trailer. */ + esptail = (struct esptail *)&tail[padlen]; + esptail->esp_padlen = padlen; + m_copydata(m, protoff, sizeof(uint8_t), &esptail->esp_nxt); /* Fix Next Protocol in IPv4/IPv6 header. */ prot = IPPROTO_ESP;