Thu Jul 20 03:17:59 2017 UTC ()
Dedup error paths (NFC)


(ozaki-r)
diff -r1.66 -r1.67 src/sys/netipsec/xform_ah.c

cvs diff -r1.66 -r1.67 src/sys/netipsec/xform_ah.c (expand / switch to unified diff)

--- src/sys/netipsec/xform_ah.c 2017/07/20 03:12:05 1.66
+++ src/sys/netipsec/xform_ah.c 2017/07/20 03:17:59 1.67
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xform_ah.c,v 1.66 2017/07/20 03:12:05 ozaki-r Exp $ */ 1/* $NetBSD: xform_ah.c,v 1.67 2017/07/20 03:17:59 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */ 2/* $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $ */
3/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */ 3/* $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
4/* 4/*
5 * The authors of this code are John Ioannidis (ji@tla.org), 5 * The authors of this code are John Ioannidis (ji@tla.org),
6 * Angelos D. Keromytis (kermit@csd.uch.gr) and 6 * Angelos D. Keromytis (kermit@csd.uch.gr) and
7 * Niels Provos (provos@physnet.uni-hamburg.de). 7 * Niels Provos (provos@physnet.uni-hamburg.de).
8 * 8 *
9 * The original version of this code was written by John Ioannidis 9 * The original version of this code was written by John Ioannidis
10 * for BSD/OS in Athens, Greece, in November 1995. 10 * for BSD/OS in Athens, Greece, in November 1995.
11 * 11 *
12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 12 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
13 * by Angelos D. Keromytis. 13 * by Angelos D. Keromytis.
14 * 14 *
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * You may use this code under the GNU public license if you so wish. Please 29 * You may use this code under the GNU public license if you so wish. Please
30 * contribute changes back to the authors under this freer than GPL license 30 * contribute changes back to the authors under this freer than GPL license
31 * so that we may further the use of strong encryption without limitations to 31 * so that we may further the use of strong encryption without limitations to
32 * all. 32 * all.
33 * 33 *
34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 34 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 35 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 36 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 37 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
38 * PURPOSE. 38 * PURPOSE.
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.66 2017/07/20 03:12:05 ozaki-r Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.67 2017/07/20 03:17:59 ozaki-r Exp $");
43 43
44#if defined(_KERNEL_OPT) 44#if defined(_KERNEL_OPT)
45#include "opt_inet.h" 45#include "opt_inet.h"
46#include "opt_ipsec.h" 46#include "opt_ipsec.h"
47#endif 47#endif
48 48
49#include <sys/param.h> 49#include <sys/param.h>
50#include <sys/systm.h> 50#include <sys/systm.h>
51#include <sys/mbuf.h> 51#include <sys/mbuf.h>
52#include <sys/socket.h> 52#include <sys/socket.h>
53#include <sys/syslog.h> 53#include <sys/syslog.h>
54#include <sys/kernel.h> 54#include <sys/kernel.h>
55#include <sys/sysctl.h> 55#include <sys/sysctl.h>
@@ -608,166 +608,168 @@ ah_massage_headers(struct mbuf **m0, int @@ -608,166 +608,168 @@ ah_massage_headers(struct mbuf **m0, int
608 } 608 }
609 609
610 return 0; 610 return 0;
611} 611}
612 612
613/* 613/*
614 * ah_input() gets called to verify that an input packet 614 * ah_input() gets called to verify that an input packet
615 * passes authentication. 615 * passes authentication.
616 */ 616 */
617static int 617static int
618ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) 618ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
619{ 619{
620 const struct auth_hash *ahx; 620 const struct auth_hash *ahx;
621 struct tdb_crypto *tc; 621 struct tdb_crypto *tc = NULL;
622 struct newah *ah; 622 struct newah *ah;
623 int hl, rplen, authsize, error; 623 int hl, rplen, authsize, error, stat = AH_STAT_HDROPS;
624 
625 struct cryptodesc *crda; 624 struct cryptodesc *crda;
626 struct cryptop *crp; 625 struct cryptop *crp = NULL;
627 626
628 IPSEC_SPLASSERT_SOFTNET(__func__); 627 IPSEC_SPLASSERT_SOFTNET(__func__);
629 628
630 KASSERT(sav != NULL); 629 KASSERT(sav != NULL);
631 KASSERT(sav->key_auth != NULL); 630 KASSERT(sav->key_auth != NULL);
632 KASSERT(sav->tdb_authalgxform != NULL); 631 KASSERT(sav->tdb_authalgxform != NULL);
633 632
634 /* Figure out header size. */ 633 /* Figure out header size. */
635 rplen = HDRSIZE(sav); 634 rplen = HDRSIZE(sav);
636 635
637 /* XXX don't pullup, just copy header */ 636 /* XXX don't pullup, just copy header */
638 IP6_EXTHDR_GET(ah, struct newah *, m, skip, rplen); 637 IP6_EXTHDR_GET(ah, struct newah *, m, skip, rplen);
639 if (ah == NULL) { 638 if (ah == NULL) {
640 DPRINTF(("%s: cannot pullup header\n", __func__)); 639 DPRINTF(("%s: cannot pullup header\n", __func__));
641 AH_STATINC(AH_STAT_HDROPS); /*XXX*/ 640 error = ENOBUFS;
642 m_freem(m); 641 stat = AH_STAT_HDROPS; /*XXX*/
643 return ENOBUFS; 642 goto bad;
644 } 643 }
645 644
646 /* Check replay window, if applicable. */ 645 /* Check replay window, if applicable. */
647 if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) { 646 if (sav->replay && !ipsec_chkreplay(ntohl(ah->ah_seq), sav)) {
648 char buf[IPSEC_LOGSASTRLEN]; 647 char buf[IPSEC_LOGSASTRLEN];
649 AH_STATINC(AH_STAT_REPLAY); 
650 DPRINTF(("%s: packet replay failure: %s\n", __func__, 648 DPRINTF(("%s: packet replay failure: %s\n", __func__,
651 ipsec_logsastr(sav, buf, sizeof(buf)))); 649 ipsec_logsastr(sav, buf, sizeof(buf))));
652 m_freem(m); 650 stat = AH_STAT_REPLAY;
653 return ENOBUFS; 651 error = ENOBUFS;
 652 goto bad;
654 } 653 }
655 654
656 /* Verify AH header length. */ 655 /* Verify AH header length. */
657 hl = ah->ah_len * sizeof(uint32_t); 656 hl = ah->ah_len * sizeof(uint32_t);
658 ahx = sav->tdb_authalgxform; 657 ahx = sav->tdb_authalgxform;
659 authsize = AUTHSIZE(sav); 658 authsize = AUTHSIZE(sav);
660 if (hl != authsize + rplen - sizeof(struct ah)) { 659 if (hl != authsize + rplen - sizeof(struct ah)) {
661 char buf[IPSEC_ADDRSTRLEN]; 660 char buf[IPSEC_ADDRSTRLEN];
662 DPRINTF(("%s: bad authenticator length %u (expecting %lu)" 661 DPRINTF(("%s: bad authenticator length %u (expecting %lu)"
663 " for packet in SA %s/%08lx\n", __func__, 662 " for packet in SA %s/%08lx\n", __func__,
664 hl, (u_long) (authsize + rplen - sizeof(struct ah)), 663 hl, (u_long) (authsize + rplen - sizeof(struct ah)),
665 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)), 664 ipsec_address(&sav->sah->saidx.dst, buf, sizeof(buf)),
666 (u_long) ntohl(sav->spi))); 665 (u_long) ntohl(sav->spi)));
667 AH_STATINC(AH_STAT_BADAUTHL); 666 stat = AH_STAT_BADAUTHL;
668 m_freem(m); 667 error = EACCES;
669 return EACCES; 668 goto bad;
670 } 669 }
671 AH_STATADD(AH_STAT_IBYTES, m->m_pkthdr.len - skip - hl); 670 AH_STATADD(AH_STAT_IBYTES, m->m_pkthdr.len - skip - hl);
672 671
673 /* Get crypto descriptors. */ 672 /* Get crypto descriptors. */
674 crp = crypto_getreq(1); 673 crp = crypto_getreq(1);
675 if (crp == NULL) { 674 if (crp == NULL) {
676 DPRINTF(("%s: failed to acquire crypto descriptor\n", __func__)); 675 DPRINTF(("%s: failed to acquire crypto descriptor\n", __func__));
677 AH_STATINC(AH_STAT_CRYPTO); 676 stat = AH_STAT_CRYPTO;
678 m_freem(m); 677 error = ENOBUFS;
679 return ENOBUFS; 678 goto bad;
680 } 679 }
681 680
682 crda = crp->crp_desc; 681 crda = crp->crp_desc;
683 KASSERT(crda != NULL); 682 KASSERT(crda != NULL);
684 683
685 crda->crd_skip = 0; 684 crda->crd_skip = 0;
686 crda->crd_len = m->m_pkthdr.len; 685 crda->crd_len = m->m_pkthdr.len;
687 crda->crd_inject = skip + rplen; 686 crda->crd_inject = skip + rplen;
688 687
689 /* Authentication operation. */ 688 /* Authentication operation. */
690 crda->crd_alg = ahx->type; 689 crda->crd_alg = ahx->type;
691 crda->crd_key = _KEYBUF(sav->key_auth); 690 crda->crd_key = _KEYBUF(sav->key_auth);
692 crda->crd_klen = _KEYBITS(sav->key_auth); 691 crda->crd_klen = _KEYBITS(sav->key_auth);
693 692
694 /* Allocate IPsec-specific opaque crypto info. */ 693 /* Allocate IPsec-specific opaque crypto info. */
695 size_t size = sizeof(*tc); 694 size_t size = sizeof(*tc);
696 size_t extra = skip + rplen + authsize; 695 size_t extra = skip + rplen + authsize;
697 size += extra; 696 size += extra;
698 697
699 tc = malloc(size, M_XDATA, M_NOWAIT|M_ZERO); 698 tc = malloc(size, M_XDATA, M_NOWAIT|M_ZERO);
700 if (tc == NULL) { 699 if (tc == NULL) {
701 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__)); 700 DPRINTF(("%s: failed to allocate tdb_crypto\n", __func__));
702 AH_STATINC(AH_STAT_CRYPTO); 701 stat = AH_STAT_CRYPTO;
703 crypto_freereq(crp); 702 error = ENOBUFS;
704 m_freem(m); 703 goto bad;
705 return ENOBUFS; 
706 } 704 }
707 705
708 error = m_makewritable(&m, 0, extra, M_NOWAIT); 706 error = m_makewritable(&m, 0, extra, M_NOWAIT);
709 if (error) { 707 if (error) {
710 m_freem(m); 
711 DPRINTF(("%s: failed to m_makewritable\n", __func__)); 708 DPRINTF(("%s: failed to m_makewritable\n", __func__));
712 AH_STATINC(AH_STAT_HDROPS); 709 goto bad;
713 free(tc, M_XDATA); 
714 crypto_freereq(crp); 
715 return error; 
716 } 710 }
717 711
718 /* 712 /*
719 * Save the authenticator, the skipped portion of the packet, 713 * Save the authenticator, the skipped portion of the packet,
720 * and the AH header. 714 * and the AH header.
721 */ 715 */
722 m_copydata(m, 0, extra, (tc + 1)); 716 m_copydata(m, 0, extra, (tc + 1));
723 /* Zeroize the authenticator on the packet. */ 717 /* Zeroize the authenticator on the packet. */
724 m_copyback(m, skip + rplen, authsize, ipseczeroes); 718 m_copyback(m, skip + rplen, authsize, ipseczeroes);
725 719
726 /* "Massage" the packet headers for crypto processing. */ 720 /* "Massage" the packet headers for crypto processing. */
727 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family, 721 error = ah_massage_headers(&m, sav->sah->saidx.dst.sa.sa_family,
728 skip, ahx->type, 0); 722 skip, ahx->type, 0);
729 if (error != 0) { 723 if (error != 0) {
730 /* NB: mbuf is free'd by ah_massage_headers */ 724 /* NB: mbuf is free'd by ah_massage_headers */
731 AH_STATINC(AH_STAT_HDROPS); 725 m = NULL;
732 free(tc, M_XDATA); 726 goto bad;
733 crypto_freereq(crp); 
734 return error; 
735 } 727 }
736 728
737 /* Crypto operation descriptor. */ 729 /* Crypto operation descriptor. */
738 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */ 730 crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
739 crp->crp_flags = CRYPTO_F_IMBUF; 731 crp->crp_flags = CRYPTO_F_IMBUF;
740 crp->crp_buf = m; 732 crp->crp_buf = m;
741 crp->crp_callback = ah_input_cb; 733 crp->crp_callback = ah_input_cb;
742 crp->crp_sid = sav->tdb_cryptoid; 734 crp->crp_sid = sav->tdb_cryptoid;
743 crp->crp_opaque = tc; 735 crp->crp_opaque = tc;
744 736
745 /* These are passed as-is to the callback. */ 737 /* These are passed as-is to the callback. */
746 tc->tc_spi = sav->spi; 738 tc->tc_spi = sav->spi;
747 tc->tc_dst = sav->sah->saidx.dst; 739 tc->tc_dst = sav->sah->saidx.dst;
748 tc->tc_proto = sav->sah->saidx.proto; 740 tc->tc_proto = sav->sah->saidx.proto;
749 tc->tc_nxt = ah->ah_nxt; 741 tc->tc_nxt = ah->ah_nxt;
750 tc->tc_protoff = protoff; 742 tc->tc_protoff = protoff;
751 tc->tc_skip = skip; 743 tc->tc_skip = skip;
752 tc->tc_sav = sav; 744 tc->tc_sav = sav;
753 KEY_SA_REF(sav); 745 KEY_SA_REF(sav);
754 746
755 DPRINTF(("%s: hash over %d bytes, skip %d: " 747 DPRINTF(("%s: hash over %d bytes, skip %d: "
756 "crda len %d skip %d inject %d\n", __func__, 748 "crda len %d skip %d inject %d\n", __func__,
757 crp->crp_ilen, tc->tc_skip, 749 crp->crp_ilen, tc->tc_skip,
758 crda->crd_len, crda->crd_skip, crda->crd_inject)); 750 crda->crd_len, crda->crd_skip, crda->crd_inject));
759 751
760 return crypto_dispatch(crp); 752 return crypto_dispatch(crp);
 753
 754bad:
 755 if (tc != NULL)
 756 free(tc, M_XDATA);
 757 if (crp != NULL)
 758 crypto_freereq(crp);
 759 if (m != NULL)
 760 m_freem(m);
 761 AH_STATINC(stat);
 762 return error;
761} 763}
762 764
763#ifdef INET6 765#ifdef INET6
764#define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) do { \ 766#define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) do { \
765 if (saidx->dst.sa.sa_family == AF_INET6) { \ 767 if (saidx->dst.sa.sa_family == AF_INET6) { \
766 error = ipsec6_common_input_cb(m, sav, skip, protoff); \ 768 error = ipsec6_common_input_cb(m, sav, skip, protoff); \
767 } else { \ 769 } else { \
768 error = ipsec4_common_input_cb(m, sav, skip, protoff); \ 770 error = ipsec4_common_input_cb(m, sav, skip, protoff); \
769 } \ 771 } \
770} while (0) 772} while (0)
771#else 773#else
772#define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) \ 774#define IPSEC_COMMON_INPUT_CB(m, sav, skip, protoff) \
773 (error = ipsec4_common_input_cb(m, sav, skip, protoff)) 775 (error = ipsec4_common_input_cb(m, sav, skip, protoff))