Deleted Added
full compact
xform_ah.c (179290) xform_ah.c (181803)
1/* $FreeBSD: head/sys/netipsec/xform_ah.c 179290 2008-05-24 15:32:46Z bz $ */
1/* $FreeBSD: head/sys/netipsec/xform_ah.c 181803 2008-08-17 23:27:27Z bz $ */
2/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
3/*-
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
7 *
8 * The original version of this code was written by John Ioannidis
9 * for BSD/OS in Athens, Greece, in November 1995.

--- 31 unchanged lines hidden (view full) ---

41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/mbuf.h>
45#include <sys/socket.h>
46#include <sys/syslog.h>
47#include <sys/kernel.h>
48#include <sys/sysctl.h>
2/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
3/*-
4 * The authors of this code are John Ioannidis (ji@tla.org),
5 * Angelos D. Keromytis (kermit@csd.uch.gr) and
6 * Niels Provos (provos@physnet.uni-hamburg.de).
7 *
8 * The original version of this code was written by John Ioannidis
9 * for BSD/OS in Athens, Greece, in November 1995.

--- 31 unchanged lines hidden (view full) ---

41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/mbuf.h>
45#include <sys/socket.h>
46#include <sys/syslog.h>
47#include <sys/kernel.h>
48#include <sys/sysctl.h>
49#include <sys/vimage.h>
49
50#include <net/if.h>
51
52#include <netinet/in.h>
53#include <netinet/in_systm.h>
54#include <netinet/ip.h>
55#include <netinet/ip_ecn.h>
56#include <netinet/ip6.h>

--- 156 unchanged lines hidden (view full) ---

213static int
214ah_init(struct secasvar *sav, struct xformsw *xsp)
215{
216 struct cryptoini cria;
217 int error;
218
219 error = ah_init0(sav, xsp, &cria);
220 return error ? error :
50
51#include <net/if.h>
52
53#include <netinet/in.h>
54#include <netinet/in_systm.h>
55#include <netinet/ip.h>
56#include <netinet/ip_ecn.h>
57#include <netinet/ip6.h>

--- 156 unchanged lines hidden (view full) ---

214static int
215ah_init(struct secasvar *sav, struct xformsw *xsp)
216{
217 struct cryptoini cria;
218 int error;
219
220 error = ah_init0(sav, xsp, &cria);
221 return error ? error :
221 crypto_newsession(&sav->tdb_cryptoid, &cria, crypto_support);
222 crypto_newsession(&sav->tdb_cryptoid, &cria, V_crypto_support);
222}
223
224/*
225 * Paranoia.
226 *
227 * NB: public for use by esp_zeroize (XXX).
228 */
229int

--- 42 unchanged lines hidden (view full) ---

272 *m0 = m = m_pullup(m, skip);
273 if (m == NULL) {
274 DPRINTF(("%s: m_pullup failed\n", __func__));
275 return ENOBUFS;
276 }
277
278 /* Fix the IP header */
279 ip = mtod(m, struct ip *);
223}
224
225/*
226 * Paranoia.
227 *
228 * NB: public for use by esp_zeroize (XXX).
229 */
230int

--- 42 unchanged lines hidden (view full) ---

273 *m0 = m = m_pullup(m, skip);
274 if (m == NULL) {
275 DPRINTF(("%s: m_pullup failed\n", __func__));
276 return ENOBUFS;
277 }
278
279 /* Fix the IP header */
280 ip = mtod(m, struct ip *);
280 if (ah_cleartos)
281 if (V_ah_cleartos)
281 ip->ip_tos = 0;
282 ip->ip_ttl = 0;
283 ip->ip_sum = 0;
284
285 /*
286 * On input, fix ip_len which has been byte-swapped
287 * at ip_input().
288 */

--- 279 unchanged lines hidden (view full) ---

568
569 /* Figure out header size. */
570 rplen = HDRSIZE(sav);
571
572 /* XXX don't pullup, just copy header */
573 IP6_EXTHDR_GET(ah, struct newah *, m, skip, rplen);
574 if (ah == NULL) {
575 DPRINTF(("ah_input: cannot pullup header\n"));
282 ip->ip_tos = 0;
283 ip->ip_ttl = 0;
284 ip->ip_sum = 0;
285
286 /*
287 * On input, fix ip_len which has been byte-swapped
288 * at ip_input().
289 */

--- 279 unchanged lines hidden (view full) ---

569
570 /* Figure out header size. */
571 rplen = HDRSIZE(sav);
572
573 /* XXX don't pullup, just copy header */
574 IP6_EXTHDR_GET(ah, struct newah *, m, skip, rplen);
575 if (ah == NULL) {
576 DPRINTF(("ah_input: cannot pullup header\n"));
576 ahstat.ahs_hdrops++; /*XXX*/
577 V_ahstat.ahs_hdrops++; /*XXX*/
577 m_freem(m);
578 return ENOBUFS;
579 }
580
581 /* Check replay window, if applicable. */
582 if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
578 m_freem(m);
579 return ENOBUFS;
580 }
581
582 /* Check replay window, if applicable. */
583 if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
583 ahstat.ahs_replay++;
584 V_ahstat.ahs_replay++;
584 DPRINTF(("%s: packet replay failure: %s\n", __func__,
585 ipsec_logsastr(sav)));
586 m_freem(m);
587 return ENOBUFS;
588 }
589
590 /* Verify AH header length. */
591 hl = ah->ah_len * sizeof (u_int32_t);
592 ahx = sav->tdb_authalgxform;
593 authsize = AUTHSIZE(sav);
594 if (hl != authsize + rplen - sizeof (struct ah)) {
595 DPRINTF(("%s: bad authenticator length %u (expecting %lu)"
596 " for packet in SA %s/%08lx\n", __func__,
597 hl, (u_long) (authsize + rplen - sizeof (struct ah)),
598 ipsec_address(&sav->sah->saidx.dst),
599 (u_long) ntohl(sav->spi)));
585 DPRINTF(("%s: packet replay failure: %s\n", __func__,
586 ipsec_logsastr(sav)));
587 m_freem(m);
588 return ENOBUFS;
589 }
590
591 /* Verify AH header length. */
592 hl = ah->ah_len * sizeof (u_int32_t);
593 ahx = sav->tdb_authalgxform;
594 authsize = AUTHSIZE(sav);
595 if (hl != authsize + rplen - sizeof (struct ah)) {
596 DPRINTF(("%s: bad authenticator length %u (expecting %lu)"
597 " for packet in SA %s/%08lx\n", __func__,
598 hl, (u_long) (authsize + rplen - sizeof (struct ah)),
599 ipsec_address(&sav->sah->saidx.dst),
600 (u_long) ntohl(sav->spi)));
600 ahstat.ahs_badauthl++;
601 V_ahstat.ahs_badauthl++;
601 m_freem(m);
602 return EACCES;
603 }
602 m_freem(m);
603 return EACCES;
604 }
604 ahstat.ahs_ibytes += m->m_pkthdr.len - skip - hl;
605 V_ahstat.ahs_ibytes += m->m_pkthdr.len - skip - hl;
605
606 /* Get crypto descriptors. */
607 crp = crypto_getreq(1);
608 if (crp == NULL) {
609 DPRINTF(("%s: failed to acquire crypto descriptor\n",__func__));
606
607 /* Get crypto descriptors. */
608 crp = crypto_getreq(1);
609 if (crp == NULL) {
610 DPRINTF(("%s: failed to acquire crypto descriptor\n",__func__));
610 ahstat.ahs_crypto++;
611 V_ahstat.ahs_crypto++;
611 m_freem(m);
612 return ENOBUFS;
613 }
614
615 crda = crp->crp_desc;
616 IPSEC_ASSERT(crda != NULL, ("null crypto descriptor"));
617
618 crda->crd_skip = 0;

--- 23 unchanged lines hidden (view full) ---

642 skip + rplen + authsize, M_XDATA, M_NOWAIT|M_ZERO);
643 } else {
644 /* Hash verification has already been done successfully. */
645 tc = (struct tdb_crypto *) malloc(sizeof (struct tdb_crypto),
646 M_XDATA, M_NOWAIT|M_ZERO);
647 }
648 if (tc == NULL) {
649 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
612 m_freem(m);
613 return ENOBUFS;
614 }
615
616 crda = crp->crp_desc;
617 IPSEC_ASSERT(crda != NULL, ("null crypto descriptor"));
618
619 crda->crd_skip = 0;

--- 23 unchanged lines hidden (view full) ---

643 skip + rplen + authsize, M_XDATA, M_NOWAIT|M_ZERO);
644 } else {
645 /* Hash verification has already been done successfully. */
646 tc = (struct tdb_crypto *) malloc(sizeof (struct tdb_crypto),
647 M_XDATA, M_NOWAIT|M_ZERO);
648 }
649 if (tc == NULL) {
650 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
650 ahstat.ahs_crypto++;
651 V_ahstat.ahs_crypto++;
651 crypto_freereq(crp);
652 m_freem(m);
653 return ENOBUFS;
654 }
655
656 /* Only save information if crypto processing is needed. */
657 if (mtag == NULL) {
658 int error;

--- 7 unchanged lines hidden (view full) ---

666 /* Zeroize the authenticator on the packet. */
667 m_copyback(m, skip + rplen, authsize, ipseczeroes);
668
669 /* "Massage" the packet headers for crypto processing. */
670 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
671 skip, ahx->type, 0);
672 if (error != 0) {
673 /* NB: mbuf is free'd by ah_massage_headers */
652 crypto_freereq(crp);
653 m_freem(m);
654 return ENOBUFS;
655 }
656
657 /* Only save information if crypto processing is needed. */
658 if (mtag == NULL) {
659 int error;

--- 7 unchanged lines hidden (view full) ---

667 /* Zeroize the authenticator on the packet. */
668 m_copyback(m, skip + rplen, authsize, ipseczeroes);
669
670 /* "Massage" the packet headers for crypto processing. */
671 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
672 skip, ahx->type, 0);
673 if (error != 0) {
674 /* NB: mbuf is free'd by ah_massage_headers */
674 ahstat.ahs_hdrops++;
675 V_ahstat.ahs_hdrops++;
675 free(tc, M_XDATA);
676 crypto_freereq(crp);
677 return error;
678 }
679 }
680
681 /* Crypto operation descriptor. */
682 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */

--- 57 unchanged lines hidden (view full) ---

740 skip = tc->tc_skip;
741 nxt = tc->tc_nxt;
742 protoff = tc->tc_protoff;
743 mtag = (struct m_tag *) tc->tc_ptr;
744 m = (struct mbuf *) crp->crp_buf;
745
746 sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
747 if (sav == NULL) {
676 free(tc, M_XDATA);
677 crypto_freereq(crp);
678 return error;
679 }
680 }
681
682 /* Crypto operation descriptor. */
683 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */

--- 57 unchanged lines hidden (view full) ---

741 skip = tc->tc_skip;
742 nxt = tc->tc_nxt;
743 protoff = tc->tc_protoff;
744 mtag = (struct m_tag *) tc->tc_ptr;
745 m = (struct mbuf *) crp->crp_buf;
746
747 sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
748 if (sav == NULL) {
748 ahstat.ahs_notdb++;
749 V_ahstat.ahs_notdb++;
749 DPRINTF(("%s: SA expired while in crypto\n", __func__));
750 error = ENOBUFS; /*XXX*/
751 goto bad;
752 }
753
754 saidx = &sav->sah->saidx;
755 IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
756 saidx->dst.sa.sa_family == AF_INET6,

--- 6 unchanged lines hidden (view full) ---

763 if (sav->tdb_cryptoid != 0)
764 sav->tdb_cryptoid = crp->crp_sid;
765
766 if (crp->crp_etype == EAGAIN) {
767 error = crypto_dispatch(crp);
768 return error;
769 }
770
750 DPRINTF(("%s: SA expired while in crypto\n", __func__));
751 error = ENOBUFS; /*XXX*/
752 goto bad;
753 }
754
755 saidx = &sav->sah->saidx;
756 IPSEC_ASSERT(saidx->dst.sa.sa_family == AF_INET ||
757 saidx->dst.sa.sa_family == AF_INET6,

--- 6 unchanged lines hidden (view full) ---

764 if (sav->tdb_cryptoid != 0)
765 sav->tdb_cryptoid = crp->crp_sid;
766
767 if (crp->crp_etype == EAGAIN) {
768 error = crypto_dispatch(crp);
769 return error;
770 }
771
771 ahstat.ahs_noxform++;
772 V_ahstat.ahs_noxform++;
772 DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
773 error = crp->crp_etype;
774 goto bad;
775 } else {
773 DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
774 error = crp->crp_etype;
775 goto bad;
776 } else {
776 ahstat.ahs_hist[sav->alg_auth]++;
777 V_ahstat.ahs_hist[sav->alg_auth]++;
777 crypto_freereq(crp); /* No longer needed. */
778 crp = NULL;
779 }
780
781 /* Shouldn't happen... */
782 if (m == NULL) {
778 crypto_freereq(crp); /* No longer needed. */
779 crp = NULL;
780 }
781
782 /* Shouldn't happen... */
783 if (m == NULL) {
783 ahstat.ahs_crypto++;
784 V_ahstat.ahs_crypto++;
784 DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
785 error = EINVAL;
786 goto bad;
787 }
788
789 /* Figure out header size. */
790 rplen = HDRSIZE(sav);
791 authsize = AUTHSIZE(sav);

--- 9 unchanged lines hidden (view full) ---

801 ptr = (caddr_t) (tc + 1);
802
803 /* Verify authenticator. */
804 if (bcmp(ptr + skip + rplen, calc, authsize)) {
805 DPRINTF(("%s: authentication hash mismatch for packet "
806 "in SA %s/%08lx\n", __func__,
807 ipsec_address(&saidx->dst),
808 (u_long) ntohl(sav->spi)));
785 DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
786 error = EINVAL;
787 goto bad;
788 }
789
790 /* Figure out header size. */
791 rplen = HDRSIZE(sav);
792 authsize = AUTHSIZE(sav);

--- 9 unchanged lines hidden (view full) ---

802 ptr = (caddr_t) (tc + 1);
803
804 /* Verify authenticator. */
805 if (bcmp(ptr + skip + rplen, calc, authsize)) {
806 DPRINTF(("%s: authentication hash mismatch for packet "
807 "in SA %s/%08lx\n", __func__,
808 ipsec_address(&saidx->dst),
809 (u_long) ntohl(sav->spi)));
809 ahstat.ahs_badauth++;
810 V_ahstat.ahs_badauth++;
810 error = EACCES;
811 goto bad;
812 }
813
814 /* Fix the Next Protocol field. */
815 ((u_int8_t *) ptr)[protoff] = nxt;
816
817 /* Copyback the saved (uncooked) network headers. */

--- 14 unchanged lines hidden (view full) ---

832 * Update replay sequence number, if appropriate.
833 */
834 if (sav->replay) {
835 u_int32_t seq;
836
837 m_copydata(m, skip + offsetof(struct newah, ah_seq),
838 sizeof (seq), (caddr_t) &seq);
839 if (ipsec_updatereplay(ntohl(seq), sav)) {
811 error = EACCES;
812 goto bad;
813 }
814
815 /* Fix the Next Protocol field. */
816 ((u_int8_t *) ptr)[protoff] = nxt;
817
818 /* Copyback the saved (uncooked) network headers. */

--- 14 unchanged lines hidden (view full) ---

833 * Update replay sequence number, if appropriate.
834 */
835 if (sav->replay) {
836 u_int32_t seq;
837
838 m_copydata(m, skip + offsetof(struct newah, ah_seq),
839 sizeof (seq), (caddr_t) &seq);
840 if (ipsec_updatereplay(ntohl(seq), sav)) {
840 ahstat.ahs_replay++;
841 V_ahstat.ahs_replay++;
841 error = ENOBUFS; /*XXX as above*/
842 goto bad;
843 }
844 }
845
846 /*
847 * Remove the AH header and authenticator from the mbuf.
848 */
849 error = m_striphdr(m, skip, rplen + authsize);
850 if (error) {
851 DPRINTF(("%s: mangled mbuf chain for SA %s/%08lx\n", __func__,
852 ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
853
842 error = ENOBUFS; /*XXX as above*/
843 goto bad;
844 }
845 }
846
847 /*
848 * Remove the AH header and authenticator from the mbuf.
849 */
850 error = m_striphdr(m, skip, rplen + authsize);
851 if (error) {
852 DPRINTF(("%s: mangled mbuf chain for SA %s/%08lx\n", __func__,
853 ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi)));
854
854 ahstat.ahs_hdrops++;
855 V_ahstat.ahs_hdrops++;
855 goto bad;
856 }
857
858 IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
859
860 KEY_FREESAV(&sav);
861 return error;
862bad:

--- 30 unchanged lines hidden (view full) ---

893 u_int8_t prot;
894 struct newah *ah;
895
896 sav = isr->sav;
897 IPSEC_ASSERT(sav != NULL, ("null SA"));
898 ahx = sav->tdb_authalgxform;
899 IPSEC_ASSERT(ahx != NULL, ("null authentication xform"));
900
856 goto bad;
857 }
858
859 IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff, mtag);
860
861 KEY_FREESAV(&sav);
862 return error;
863bad:

--- 30 unchanged lines hidden (view full) ---

894 u_int8_t prot;
895 struct newah *ah;
896
897 sav = isr->sav;
898 IPSEC_ASSERT(sav != NULL, ("null SA"));
899 ahx = sav->tdb_authalgxform;
900 IPSEC_ASSERT(ahx != NULL, ("null authentication xform"));
901
901 ahstat.ahs_output++;
902 V_ahstat.ahs_output++;
902
903 /* Figure out header size. */
904 rplen = HDRSIZE(sav);
905
906 /* Check for maximum packet size violations. */
907 switch (sav->sah->saidx.dst.sa.sa_family) {
908#ifdef INET
909 case AF_INET:

--- 6 unchanged lines hidden (view full) ---

916 break;
917#endif /* INET6 */
918 default:
919 DPRINTF(("%s: unknown/unsupported protocol family %u, "
920 "SA %s/%08lx\n", __func__,
921 sav->sah->saidx.dst.sa.sa_family,
922 ipsec_address(&sav->sah->saidx.dst),
923 (u_long) ntohl(sav->spi)));
903
904 /* Figure out header size. */
905 rplen = HDRSIZE(sav);
906
907 /* Check for maximum packet size violations. */
908 switch (sav->sah->saidx.dst.sa.sa_family) {
909#ifdef INET
910 case AF_INET:

--- 6 unchanged lines hidden (view full) ---

917 break;
918#endif /* INET6 */
919 default:
920 DPRINTF(("%s: unknown/unsupported protocol family %u, "
921 "SA %s/%08lx\n", __func__,
922 sav->sah->saidx.dst.sa.sa_family,
923 ipsec_address(&sav->sah->saidx.dst),
924 (u_long) ntohl(sav->spi)));
924 ahstat.ahs_nopf++;
925 V_ahstat.ahs_nopf++;
925 error = EPFNOSUPPORT;
926 goto bad;
927 }
928 authsize = AUTHSIZE(sav);
929 if (rplen + authsize + m->m_pkthdr.len > maxpacketsize) {
930 DPRINTF(("%s: packet in SA %s/%08lx got too big "
931 "(len %u, max len %u)\n", __func__,
932 ipsec_address(&sav->sah->saidx.dst),
933 (u_long) ntohl(sav->spi),
934 rplen + authsize + m->m_pkthdr.len, maxpacketsize));
926 error = EPFNOSUPPORT;
927 goto bad;
928 }
929 authsize = AUTHSIZE(sav);
930 if (rplen + authsize + m->m_pkthdr.len > maxpacketsize) {
931 DPRINTF(("%s: packet in SA %s/%08lx got too big "
932 "(len %u, max len %u)\n", __func__,
933 ipsec_address(&sav->sah->saidx.dst),
934 (u_long) ntohl(sav->spi),
935 rplen + authsize + m->m_pkthdr.len, maxpacketsize));
935 ahstat.ahs_toobig++;
936 V_ahstat.ahs_toobig++;
936 error = EMSGSIZE;
937 goto bad;
938 }
939
940 /* Update the counters. */
937 error = EMSGSIZE;
938 goto bad;
939 }
940
941 /* Update the counters. */
941 ahstat.ahs_obytes += m->m_pkthdr.len - skip;
942 V_ahstat.ahs_obytes += m->m_pkthdr.len - skip;
942
943 m = m_unshare(m, M_NOWAIT);
944 if (m == NULL) {
945 DPRINTF(("%s: cannot clone mbuf chain, SA %s/%08lx\n", __func__,
946 ipsec_address(&sav->sah->saidx.dst),
947 (u_long) ntohl(sav->spi)));
943
944 m = m_unshare(m, M_NOWAIT);
945 if (m == NULL) {
946 DPRINTF(("%s: cannot clone mbuf chain, SA %s/%08lx\n", __func__,
947 ipsec_address(&sav->sah->saidx.dst),
948 (u_long) ntohl(sav->spi)));
948 ahstat.ahs_hdrops++;
949 V_ahstat.ahs_hdrops++;
949 error = ENOBUFS;
950 goto bad;
951 }
952
953 /* Inject AH header. */
954 mi = m_makespace(m, skip, rplen + authsize, &roff);
955 if (mi == NULL) {
956 DPRINTF(("%s: failed to inject %u byte AH header for SA "
957 "%s/%08lx\n", __func__,
958 rplen + authsize,
959 ipsec_address(&sav->sah->saidx.dst),
960 (u_long) ntohl(sav->spi)));
950 error = ENOBUFS;
951 goto bad;
952 }
953
954 /* Inject AH header. */
955 mi = m_makespace(m, skip, rplen + authsize, &roff);
956 if (mi == NULL) {
957 DPRINTF(("%s: failed to inject %u byte AH header for SA "
958 "%s/%08lx\n", __func__,
959 rplen + authsize,
960 ipsec_address(&sav->sah->saidx.dst),
961 (u_long) ntohl(sav->spi)));
961 ahstat.ahs_hdrops++; /*XXX differs from openbsd */
962 V_ahstat.ahs_hdrops++; /*XXX differs from openbsd */
962 error = ENOBUFS;
963 goto bad;
964 }
965
966 /*
967 * The AH header is guaranteed by m_makespace() to be in
968 * contiguous memory, at roff bytes offset into the returned mbuf.
969 */

--- 11 unchanged lines hidden (view full) ---

981 /* Insert packet replay counter, as requested. */
982 if (sav->replay) {
983 if (sav->replay->count == ~0 &&
984 (sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
985 DPRINTF(("%s: replay counter wrapped for SA %s/%08lx\n",
986 __func__,
987 ipsec_address(&sav->sah->saidx.dst),
988 (u_long) ntohl(sav->spi)));
963 error = ENOBUFS;
964 goto bad;
965 }
966
967 /*
968 * The AH header is guaranteed by m_makespace() to be in
969 * contiguous memory, at roff bytes offset into the returned mbuf.
970 */

--- 11 unchanged lines hidden (view full) ---

982 /* Insert packet replay counter, as requested. */
983 if (sav->replay) {
984 if (sav->replay->count == ~0 &&
985 (sav->flags & SADB_X_EXT_CYCSEQ) == 0) {
986 DPRINTF(("%s: replay counter wrapped for SA %s/%08lx\n",
987 __func__,
988 ipsec_address(&sav->sah->saidx.dst),
989 (u_long) ntohl(sav->spi)));
989 ahstat.ahs_wrap++;
990 V_ahstat.ahs_wrap++;
990 error = EINVAL;
991 goto bad;
992 }
993#ifdef REGRESSION
994 /* Emulate replay attack when ipsec_replay is TRUE. */
991 error = EINVAL;
992 goto bad;
993 }
994#ifdef REGRESSION
995 /* Emulate replay attack when ipsec_replay is TRUE. */
995 if (!ipsec_replay)
996 if (!V_ipsec_replay)
996#endif
997 sav->replay->count++;
998 ah->ah_seq = htonl(sav->replay->count);
999 }
1000
1001 /* Get crypto descriptors. */
1002 crp = crypto_getreq(1);
1003 if (crp == NULL) {
1004 DPRINTF(("%s: failed to acquire crypto descriptors\n",
1005 __func__));
997#endif
998 sav->replay->count++;
999 ah->ah_seq = htonl(sav->replay->count);
1000 }
1001
1002 /* Get crypto descriptors. */
1003 crp = crypto_getreq(1);
1004 if (crp == NULL) {
1005 DPRINTF(("%s: failed to acquire crypto descriptors\n",
1006 __func__));
1006 ahstat.ahs_crypto++;
1007 V_ahstat.ahs_crypto++;
1007 error = ENOBUFS;
1008 goto bad;
1009 }
1010
1011 crda = crp->crp_desc;
1012
1013 crda->crd_skip = 0;
1014 crda->crd_inject = skip + rplen;

--- 5 unchanged lines hidden (view full) ---

1020 crda->crd_klen = _KEYBITS(sav->key_auth);
1021
1022 /* Allocate IPsec-specific opaque crypto info. */
1023 tc = (struct tdb_crypto *) malloc(
1024 sizeof(struct tdb_crypto) + skip, M_XDATA, M_NOWAIT|M_ZERO);
1025 if (tc == NULL) {
1026 crypto_freereq(crp);
1027 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
1008 error = ENOBUFS;
1009 goto bad;
1010 }
1011
1012 crda = crp->crp_desc;
1013
1014 crda->crd_skip = 0;
1015 crda->crd_inject = skip + rplen;

--- 5 unchanged lines hidden (view full) ---

1021 crda->crd_klen = _KEYBITS(sav->key_auth);
1022
1023 /* Allocate IPsec-specific opaque crypto info. */
1024 tc = (struct tdb_crypto *) malloc(
1025 sizeof(struct tdb_crypto) + skip, M_XDATA, M_NOWAIT|M_ZERO);
1026 if (tc == NULL) {
1027 crypto_freereq(crp);
1028 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
1028 ahstat.ahs_crypto++;
1029 V_ahstat.ahs_crypto++;
1029 error = ENOBUFS;
1030 goto bad;
1031 }
1032
1033 /* Save the skipped portion of the packet. */
1034 m_copydata(m, 0, skip, (caddr_t) (tc + 1));
1035
1036 /*

--- 85 unchanged lines hidden (view full) ---

1122 protoff = tc->tc_protoff;
1123 ptr = (caddr_t) (tc + 1);
1124 m = (struct mbuf *) crp->crp_buf;
1125
1126 isr = tc->tc_isr;
1127 IPSECREQUEST_LOCK(isr);
1128 sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
1129 if (sav == NULL) {
1030 error = ENOBUFS;
1031 goto bad;
1032 }
1033
1034 /* Save the skipped portion of the packet. */
1035 m_copydata(m, 0, skip, (caddr_t) (tc + 1));
1036
1037 /*

--- 85 unchanged lines hidden (view full) ---

1123 protoff = tc->tc_protoff;
1124 ptr = (caddr_t) (tc + 1);
1125 m = (struct mbuf *) crp->crp_buf;
1126
1127 isr = tc->tc_isr;
1128 IPSECREQUEST_LOCK(isr);
1129 sav = KEY_ALLOCSA(&tc->tc_dst, tc->tc_proto, tc->tc_spi);
1130 if (sav == NULL) {
1130 ahstat.ahs_notdb++;
1131 V_ahstat.ahs_notdb++;
1131 DPRINTF(("%s: SA expired while in crypto\n", __func__));
1132 error = ENOBUFS; /*XXX*/
1133 goto bad;
1134 }
1135 IPSEC_ASSERT(isr->sav == sav, ("SA changed\n"));
1136
1137 /* Check for crypto errors. */
1138 if (crp->crp_etype) {
1139 if (sav->tdb_cryptoid != 0)
1140 sav->tdb_cryptoid = crp->crp_sid;
1141
1142 if (crp->crp_etype == EAGAIN) {
1143 KEY_FREESAV(&sav);
1144 IPSECREQUEST_UNLOCK(isr);
1145 error = crypto_dispatch(crp);
1146 return error;
1147 }
1148
1132 DPRINTF(("%s: SA expired while in crypto\n", __func__));
1133 error = ENOBUFS; /*XXX*/
1134 goto bad;
1135 }
1136 IPSEC_ASSERT(isr->sav == sav, ("SA changed\n"));
1137
1138 /* Check for crypto errors. */
1139 if (crp->crp_etype) {
1140 if (sav->tdb_cryptoid != 0)
1141 sav->tdb_cryptoid = crp->crp_sid;
1142
1143 if (crp->crp_etype == EAGAIN) {
1144 KEY_FREESAV(&sav);
1145 IPSECREQUEST_UNLOCK(isr);
1146 error = crypto_dispatch(crp);
1147 return error;
1148 }
1149
1149 ahstat.ahs_noxform++;
1150 V_ahstat.ahs_noxform++;
1150 DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
1151 error = crp->crp_etype;
1152 goto bad;
1153 }
1154
1155 /* Shouldn't happen... */
1156 if (m == NULL) {
1151 DPRINTF(("%s: crypto error %d\n", __func__, crp->crp_etype));
1152 error = crp->crp_etype;
1153 goto bad;
1154 }
1155
1156 /* Shouldn't happen... */
1157 if (m == NULL) {
1157 ahstat.ahs_crypto++;
1158 V_ahstat.ahs_crypto++;
1158 DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
1159 error = EINVAL;
1160 goto bad;
1161 }
1159 DPRINTF(("%s: bogus returned buffer from crypto\n", __func__));
1160 error = EINVAL;
1161 goto bad;
1162 }
1162 ahstat.ahs_hist[sav->alg_auth]++;
1163 V_ahstat.ahs_hist[sav->alg_auth]++;
1163
1164 /*
1165 * Copy original headers (with the new protocol number) back
1166 * in place.
1167 */
1168 m_copyback(m, 0, skip, ptr);
1169
1170 /* No longer needed. */
1171 free(tc, M_XDATA);
1172 crypto_freereq(crp);
1173
1174#ifdef REGRESSION
1175 /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */
1164
1165 /*
1166 * Copy original headers (with the new protocol number) back
1167 * in place.
1168 */
1169 m_copyback(m, 0, skip, ptr);
1170
1171 /* No longer needed. */
1172 free(tc, M_XDATA);
1173 crypto_freereq(crp);
1174
1175#ifdef REGRESSION
1176 /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */
1176 if (ipsec_integrity) {
1177 if (V_ipsec_integrity) {
1177 int alen;
1178
1179 /*
1180 * Corrupt HMAC if we want to test integrity verification of
1181 * the other side.
1182 */
1183 alen = AUTHSIZE(sav);
1184 m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes);

--- 30 unchanged lines hidden ---
1178 int alen;
1179
1180 /*
1181 * Corrupt HMAC if we want to test integrity verification of
1182 * the other side.
1183 */
1184 alen = AUTHSIZE(sav);
1185 m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes);

--- 30 unchanged lines hidden ---