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 --- |