diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-05-30 12:14:00 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2001-05-30 12:14:00 +0000 |
commit | 5a8d3a660ffa2f702399c0a3b2ad186708166d5e (patch) | |
tree | 847ffa0643e5addb49602cfc614957caabe545a9 | |
parent | bcb2f5d31ec7ac7867241d34de691663bf8266b2 (diff) |
Handle TDBF_SKIPCRYPTO on output, and PACKET_TAG_IPSEC_IN_CRYPTO_DONE
on input.
-rw-r--r-- | sys/netinet/ip_ah.c | 285 | ||||
-rw-r--r-- | sys/netinet/ip_esp.c | 110 |
2 files changed, 235 insertions, 160 deletions
diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index 03d0d9d1224..fc8cc4a92a8 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.55 2001/05/27 03:51:31 angelos Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.56 2001/05/30 12:13:59 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -501,7 +501,9 @@ int ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) { struct auth_hash *ahx = (struct auth_hash *) tdb->tdb_authalgxform; + struct tdb_ident *tdbi; struct tdb_crypto *tc; + struct m_tag *mtag; u_int32_t btsx; u_int8_t hl; int rplen; @@ -604,50 +606,74 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) crda->crd_key = tdb->tdb_amxkey; crda->crd_klen = tdb->tdb_amxkeylen * 8; - /* Allocate IPsec-specific opaque crypto info */ - MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), - M_XDATA, M_NOWAIT); - if (tc == NULL) + /* Find out if we've already done crypto */ + for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL); + mtag != NULL; + mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) { - m_freem(m); - crypto_freereq(crp); - DPRINTF(("ah_input(): failed to allocate tdb_crypto\n")); - ahstat.ahs_crypto++; - return ENOBUFS; + tdbi = (struct tdb_ident *) (mtag + 1); + if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi && + !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union))) + break; } - bzero(tc, sizeof(struct tdb_crypto)); - /* - * Save the authenticator, the skipped portion of the packet, and the - * AH header. - */ - MALLOC(tc->tc_ptr, caddr_t, skip + rplen + ahx->authsize, - M_XDATA, M_NOWAIT); - if (tc->tc_ptr == 0) + /* Allocate IPsec-specific opaque crypto info */ + if (mtag == NULL) + MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto) + skip + + rplen + ahx->authsize, M_XDATA, M_NOWAIT); + else + { +#ifdef DEBUG + /* + * Check that it has the proper length -- i.e., contains the + * authenticator. + */ + if (mtag->m_tag_len != sizeof(struct tdb_ident) + ahx->authsize) + { + m_freem(m); + crypto_freereq(crp); + DPRINTF(("ah_input(): tag had wrong length (%d, should be %d)\n", + mtag->m_tag_len, + sizeof(struct tdb_ident) + ahx->authsize)); + ahstat.ahs_crypto++; + return EINVAL; + } +#endif + MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA, + M_NOWAIT); + } + if (tc == NULL) { m_freem(m); - FREE(tc, M_XDATA); crypto_freereq(crp); - DPRINTF(("ah_input(): failed to allocate auth array\n")); + DPRINTF(("ah_input(): failed to allocate tdb_crypto\n")); ahstat.ahs_crypto++; return ENOBUFS; } - /* Save data */ - m_copydata(m, 0, skip + rplen + ahx->authsize, tc->tc_ptr); - - /* Zeroize the authenticator on the packet */ - m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes); + bzero(tc, sizeof(struct tdb_crypto)); - /* "Massage" the packet headers for crypto processing */ - if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, - skip, ahx->type, 0)) != 0) + /* Only save information if crypto processing is needed */ + if (mtag == NULL) { - /* mbuf will be free'd by callee */ - FREE(tc->tc_ptr, M_XDATA); - FREE(tc, M_XDATA); - crypto_freereq(crp); - return btsx; + /* + * Save the authenticator, the skipped portion of the packet, + * and the AH header. + */ + m_copydata(m, 0, skip + rplen + ahx->authsize, (caddr_t) (tc + 1)); + + /* Zeroize the authenticator on the packet */ + m_copyback(m, skip + rplen, ahx->authsize, ipseczeroes); + + /* "Massage" the packet headers for crypto processing */ + if ((btsx = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, + skip, ahx->type, 0)) != 0) + { + /* mbuf will be free'd by callee */ + FREE(tc, M_XDATA); + crypto_freereq(crp); + return btsx; + } } /* Crypto operation descriptor */ @@ -663,9 +689,13 @@ ah_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) tc->tc_protoff = protoff; tc->tc_spi = tdb->tdb_spi; tc->tc_proto = tdb->tdb_sproto; + tc->tc_ptr = (caddr_t) mtag; /* Save the mtag we've identified */ bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union)); - return crypto_dispatch(crp); + if (mtag == NULL) + return crypto_dispatch(crp); + else + return ah_input_cb(crp); } /* @@ -680,9 +710,11 @@ ah_input_cb(void *op) struct cryptodesc *crd; struct auth_hash *ahx; struct tdb_crypto *tc; + caddr_t ptr, authptr; struct cryptop *crp; + struct m_tag *mtag; struct tdb *tdb; - caddr_t ptr = 0; + u_int8_t prot; int s, err; crp = (struct cryptop *) op; @@ -691,7 +723,7 @@ ah_input_cb(void *op) tc = (struct tdb_crypto *) crp->crp_opaque; skip = tc->tc_skip; protoff = tc->tc_protoff; - ptr = tc->tc_ptr; + mtag = (struct m_tag *) tc->tc_ptr; m = (struct mbuf *) crp->crp_buf; s = spltdb(); @@ -724,9 +756,14 @@ ah_input_cb(void *op) error = crp->crp_etype; goto baddone; } + else + { + crypto_freereq(crp); /* No longer needed */ + crp = NULL; + } /* Shouldn't happen... */ - if (!m) + if (m == NULL) { ahstat.ahs_crypto++; DPRINTF(("ah_input_cb(): bogus returned buffer from crypto\n")); @@ -739,11 +776,36 @@ ah_input_cb(void *op) else rplen = AH_FLENGTH; - /* Copy computed authenticator */ + /* Copy authenticator off the packet. */ m_copydata(m, skip + rplen, ahx->authsize, calc); + /* + * If we have an mtag, it means we can get the authenticator off + * of it, as opposed to right after the tdb_crypto. + */ + if (mtag == NULL) + { + ptr = (caddr_t) (tc + 1); + authptr = ptr + skip + rplen; + + /* Fix the Next Protocol field */ + ((u_int8_t *) ptr)[protoff] = ((u_int8_t *) ptr)[skip]; + + /* Copyback the saved (uncooked) network headers */ + m_copyback(m, 0, skip, ptr); + } + else + { + authptr = (caddr_t) (mtag + 1); + authptr += sizeof(struct tdb_crypto); + + /* Fix the Next Protocol field */ + m_copydata(m, skip, sizeof(u_int8_t), &prot); + m_copyback(m, protoff, sizeof(u_int8_t), &prot); + } + /* Verify authenticator */ - if (bcmp(ptr + skip + rplen, calc, ahx->authsize)) + if (bcmp(authptr, calc, ahx->authsize)) { DPRINTF(("ah_input(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); ahstat.ahs_badauth++; @@ -751,17 +813,6 @@ ah_input_cb(void *op) goto baddone; } - /* Fix the Next Protocol field */ - ((u_int8_t *) ptr)[protoff] = - ((u_int8_t *) ptr)[skip]; - - /* Copyback the saved (uncooked) network headers */ - m_copyback(m, 0, skip, ptr); - - /* No longer needed */ - FREE(ptr, M_XDATA); - crypto_freereq(crp); - /* Record the beginning of the AH header */ m1 = m_getptr(m, skip, &roff); if (m1 == NULL) @@ -825,21 +876,18 @@ ah_input_cb(void *op) m->m_pkthdr.len -= rplen + ahx->authsize; } - err = ipsec_common_input_cb(m, tdb, skip, protoff, NULL); + err = ipsec_common_input_cb(m, tdb, skip, protoff, mtag); splx(s); return err; baddone: splx(s); - if (m) + if (m != NULL) m_freem(m); - /* We have to free this manually */ - if (ptr) - FREE(ptr, M_XDATA); - - crypto_freereq(crp); + if (crp != NULL) + crypto_freereq(crp); return error; } @@ -857,8 +905,8 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, struct mbuf *mo, *mi; struct cryptop *crp; u_int16_t iplen; - u_int8_t prot; int len, rplen; + u_int8_t prot; struct ah *ah; #if NBPFILTER > 0 @@ -1044,8 +1092,12 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, crda->crd_klen = tdb->tdb_amxkeylen * 8; /* Allocate IPsec-specific opaque crypto info */ - MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA, - M_NOWAIT); + if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) + MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto) + skip, + M_XDATA, M_NOWAIT); + else + MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), M_XDATA, + M_NOWAIT); if (tc == NULL) { m_freem(m); @@ -1054,64 +1106,64 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, ahstat.ahs_crypto++; return ENOBUFS; } + bzero(tc, sizeof(struct tdb_crypto)); /* Save the skipped portion of the packet */ - MALLOC(tc->tc_ptr, caddr_t, skip, M_XDATA, M_NOWAIT); - if (tc->tc_ptr == 0) - { - FREE(tc, M_XDATA); - m_freem(m); - crypto_freereq(crp); - DPRINTF(("ah_output(): failed to allocate auth array\n")); - ahstat.ahs_crypto++; - return ENOBUFS; - } - else - m_copydata(m, 0, skip, tc->tc_ptr); - - /* - * Fix IP header length on the header used for authentication. We don't - * need to fix the original header length as it will be fixed by our - * caller. - */ - switch (tdb->tdb_dst.sa.sa_family) + if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) { + m_copydata(m, 0, skip, (caddr_t) (tc + 1)); + + /* + * Fix IP header length on the header used for authentication. We don't + * need to fix the original header length as it will be fixed by our + * caller. + */ + switch (tdb->tdb_dst.sa.sa_family) + { #ifdef INET - case AF_INET: - bcopy(tc->tc_ptr + offsetof(struct ip, ip_len), - (caddr_t) &iplen, sizeof(u_int16_t)); - iplen = htons(ntohs(iplen) + rplen + ahx->authsize); - m_copyback(m, offsetof(struct ip, ip_len), sizeof(u_int16_t), - (caddr_t) &iplen); - break; + case AF_INET: + bcopy(((caddr_t)(tc + 1)) + offsetof(struct ip, ip_len), + (caddr_t) &iplen, sizeof(u_int16_t)); + iplen = htons(ntohs(iplen) + rplen + ahx->authsize); + m_copyback(m, offsetof(struct ip, ip_len), sizeof(u_int16_t), + (caddr_t) &iplen); + break; #endif /* INET */ #ifdef INET6 - case AF_INET6: - bcopy(tc->tc_ptr + offsetof(struct ip6_hdr, ip6_plen), - (caddr_t) &iplen, sizeof(u_int16_t)); - iplen = htons(ntohs(iplen) + rplen + ahx->authsize); - m_copyback(m, offsetof(struct ip6_hdr, ip6_plen), - sizeof(u_int16_t), (caddr_t) &iplen); - break; + case AF_INET6: + bcopy(((caddr_t)(tc + 1)) + offsetof(struct ip6_hdr, ip6_plen), + (caddr_t) &iplen, sizeof(u_int16_t)); + iplen = htons(ntohs(iplen) + rplen + ahx->authsize); + m_copyback(m, offsetof(struct ip6_hdr, ip6_plen), + sizeof(u_int16_t), (caddr_t) &iplen); + break; #endif /* INET6 */ - } + } + + /* Fix the Next Header field in saved header. */ + ((u_int8_t *) (tc + 1))[protoff] = IPPROTO_AH; - /* Update the Next Protocol field in the IP header and the saved data */ - prot = IPPROTO_AH; - m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot); - ((u_int8_t *) tc->tc_ptr)[protoff] = IPPROTO_AH; + /* Update the Next Protocol field in the IP header. */ + prot = IPPROTO_AH; + m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot); - /* "Massage" the packet headers for crypto processing */ - if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, - skip, ahx->type, 1)) != 0) + /* "Massage" the packet headers for crypto processing */ + if ((len = ah_massage_headers(&m, tdb->tdb_dst.sa.sa_family, + skip, ahx->type, 1)) != 0) + { + /* mbuf will be free'd by callee */ + FREE(tc, M_XDATA); + crypto_freereq(crp); + return len; + } + } + else { - /* mbuf will be free'd by callee */ - FREE(tc->tc_ptr, M_XDATA); - FREE(tc, M_XDATA); - crypto_freereq(crp); - return len; + /* Update the Next Protocol field in the IP header. */ + prot = IPPROTO_AH; + m_copyback(m, protoff, sizeof(u_int8_t), (caddr_t) &prot); } /* Crypto operation descriptor */ @@ -1136,7 +1188,10 @@ ah_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, bcopy(&tdb2->tdb_dst, &tc->tc_dst2, sizeof(union sockaddr_union)); } - return crypto_dispatch(crp); + if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) + return crypto_dispatch(crp); + else + return ah_output_cb(crp); } /* @@ -1149,15 +1204,15 @@ ah_output_cb(void *op) int skip, protoff, error; struct tdb_crypto *tc; struct cryptop *crp; - caddr_t ptr = 0; struct mbuf *m; + caddr_t ptr; int err, s; crp = (struct cryptop *) op; tc = (struct tdb_crypto *) crp->crp_opaque; skip = tc->tc_skip; protoff = tc->tc_protoff; - ptr = tc->tc_ptr; + ptr = (caddr_t) (tc + 1); m = (struct mbuf *) crp->crp_buf; s = spltdb(); @@ -1193,7 +1248,7 @@ ah_output_cb(void *op) } /* Shouldn't happen... */ - if (!m) + if (m == NULL) { ahstat.ahs_crypto++; DPRINTF(("ah_output_cb(): bogus returned buffer from crypto\n")); @@ -1202,10 +1257,10 @@ ah_output_cb(void *op) } /* Copy original headers (with the new protocol number) back in place */ - m_copyback(m, 0, skip, ptr); + if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) + m_copyback(m, 0, skip, ptr); /* No longer needed */ - FREE(ptr, M_XDATA); crypto_freereq(crp); err = ipsp_process_done(m, tdb, tdb2); @@ -1215,13 +1270,9 @@ ah_output_cb(void *op) baddone: splx(s); - if (m) + if (m != NULL) m_freem(m); - /* We have to free this manually */ - if (ptr) - FREE(ptr, M_XDATA); - crypto_freereq(crp); return error; diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index 3577e6babad..7d9248cf33b 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp.c,v 1.60 2001/05/27 03:48:34 angelos Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.61 2001/05/30 12:13:58 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -278,8 +278,10 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) { struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform; struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform; + struct tdb_ident *tdbi; struct tdb_crypto *tc; int plen, alen, hlen; + struct m_tag *mtag; u_int32_t btsx; struct cryptodesc *crde = NULL, *crda = NULL; @@ -368,6 +370,31 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) tdb->tdb_flags &= ~TDBF_SOFT_BYTES; /* Turn off checking */ } + /* Find out if we've already done crypto */ + for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL); + mtag != NULL; + mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) + { + tdbi = (struct tdb_ident *) (mtag + 1); + if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi && + !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union))) + break; + } +#ifdef DEBUG + /* + * Check the the length of the tag is correct, i.e., it contains the + * authenticator. + */ + if (mtag != NULL && mtag->m_tag_len != sizeof(struct tdb_ident) + alen) + { + m_freem(m); + DPRINTF(("esp_input(): bad tag length %d (should be %d)\n", + mtag->m_tag_len, sizeof(struct tdb_ident) + alen)); + espstat.esps_crypto++; + return EINVAL; + } +#endif + /* Get crypto descriptors */ crp = crypto_getreq(esph && espx ? 2 : 1); if (crp == NULL) @@ -379,8 +406,12 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) } /* Get IPsec-specific opaque pointer */ - MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), - M_XDATA, M_NOWAIT); + if (esph == NULL || mtag != NULL) + MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), + M_XDATA, M_NOWAIT); + else + MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto) + alen, + M_XDATA, M_NOWAIT); if (tc == NULL) { m_freem(m); @@ -389,7 +420,9 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) espstat.esps_crypto++; return ENOBUFS; } + bzero(tc, sizeof(struct tdb_crypto)); + tc->tc_ptr = (caddr_t) mtag; if (esph) { @@ -405,25 +438,12 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) crda->crd_key = tdb->tdb_amxkey; crda->crd_klen = tdb->tdb_amxkeylen * 8; - /* Keep a copy of the authenticator */ - MALLOC(tc->tc_ptr, caddr_t, alen, M_XDATA, M_NOWAIT); - if (tc->tc_ptr == 0) - { - FREE(tc, M_XDATA); - m_freem(m); - crypto_freereq(crp); - DPRINTF(("esp_input(): failed to allocate auth array\n")); - espstat.esps_crypto++; - return ENOBUFS; - } - /* Copy the authenticator */ - m_copydata(m, m->m_pkthdr.len - alen, alen, tc->tc_ptr); + if (mtag == NULL) + m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) (tc + 1)); } else - { - crde = crp->crp_desc; - } + crde = crp->crp_desc; /* Crypto operation descriptor */ crp->crp_ilen = m->m_pkthdr.len; /* Total input length */ @@ -465,7 +485,10 @@ esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff) /* XXX Rounds ? */ } - return crypto_dispatch(crp); + if (mtag == NULL) + return crypto_dispatch(crp); + else + return esp_input_cb(crp); } /* @@ -482,9 +505,10 @@ esp_input_cb(void *op) struct enc_xform *espx; struct tdb_crypto *tc; struct cryptop *crp; + struct m_tag *mtag; struct tdb *tdb; - caddr_t ptr = 0; int s, err = 0; + caddr_t ptr; crp = (struct cryptop *) op; crd = crp->crp_desc; @@ -492,7 +516,7 @@ esp_input_cb(void *op) tc = (struct tdb_crypto *) crp->crp_opaque; skip = tc->tc_skip; protoff = tc->tc_protoff; - ptr = tc->tc_ptr; + mtag = (struct m_tag *) tc->tc_ptr; m = (struct mbuf *) crp->crp_buf; s = spltdb(); @@ -529,7 +553,7 @@ esp_input_cb(void *op) } /* Shouldn't happen... */ - if (!m) + if (m == NULL) { espstat.esps_crypto++; DPRINTF(("esp_input_cb(): bogus returned buffer from crypto\n")); @@ -543,6 +567,14 @@ esp_input_cb(void *op) /* Copy the authenticator from the packet */ m_copydata(m, m->m_pkthdr.len - esph->authsize, esph->authsize, aalg); + if (mtag != NULL) + { + ptr = (caddr_t) (mtag + 1); + ptr += sizeof(struct tdb_ident); + } + else + ptr = (caddr_t) (tc + 1); + /* Verify authenticator */ if (bcmp(ptr, aalg, esph->authsize)) { @@ -554,9 +586,6 @@ esp_input_cb(void *op) /* Remove trailing authenticator */ m_adj(m, -(esph->authsize)); - - /* We have to manually free this */ - FREE(ptr, M_XDATA); } /* Release the crypto descriptors */ @@ -663,7 +692,7 @@ esp_input_cb(void *op) m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2); /* Back to generic IPsec input processing */ - err = ipsec_common_input_cb(m, tdb, skip, protoff, NULL); + err = ipsec_common_input_cb(m, tdb, skip, protoff, mtag); splx(s); return err; @@ -673,10 +702,6 @@ esp_input_cb(void *op) if (m) m_freem(m); - /* We have to manually free this */ - if (ptr) - FREE(ptr, M_XDATA); - crypto_freereq(crp); return error; @@ -883,14 +908,10 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, /* Self-describing padding ? */ if (!(tdb->tdb_flags & TDBF_RANDOMPADDING)) - { - for (ilen = 0; ilen < padding - 2; ilen++) - pad[ilen] = ilen + 1; - } + for (ilen = 0; ilen < padding - 2; ilen++) + pad[ilen] = ilen + 1; else - { - get_random_bytes((void *) pad, padding - 2); /* Random padding */ - } + get_random_bytes((void *) pad, padding - 2); /* Random padding */ /* Fix padding length and Next Protocol in padding itself */ pad[padding - 2] = padding - 2; @@ -921,7 +942,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, crde->crd_flags = CRD_F_ENCRYPT; crde->crd_inject = skip + hlen - tdb->tdb_ivlen; - if (tdb->tdb_flags & TDBF_HALFIV) + if (tdb->tdb_flags & TDBF_HALFIV) { /* Copy half-iv in the packet */ m_copyback(m, crde->crd_inject, tdb->tdb_ivlen, tdb->tdb_iv); @@ -945,7 +966,7 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, /* IPsec-specific opaque crypto info */ MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto), - M_XDATA, M_NOWAIT); + M_XDATA, M_NOWAIT); if (tc == NULL) { m_freem(m); @@ -954,8 +975,8 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, espstat.esps_crypto++; return ENOBUFS; } - bzero(tc, sizeof(struct tdb_crypto)); + bzero(tc, sizeof(struct tdb_crypto)); tc->tc_spi = tdb->tdb_spi; tc->tc_proto = tdb->tdb_sproto; bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union)); @@ -988,7 +1009,10 @@ esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip, crda->crd_klen = tdb->tdb_amxkeylen * 8; } - return crypto_dispatch(crp); + if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0) + return crypto_dispatch(crp); + else + return esp_output_cb(crp); } /* @@ -1040,7 +1064,7 @@ esp_output_cb(void *op) } /* Shouldn't happen... */ - if (!m) + if (m == NULL) { espstat.esps_crypto++; DPRINTF(("esp_output_cb(): bogus returned buffer from crypto\n")); |