Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/perseant-stdc-iso10646]: src/sys/netipsec 3197901



details:   https://anonhg.NetBSD.org/src/rev/3092d9008d9e
branches:  perseant-stdc-iso10646
changeset: 850671:3092d9008d9e
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Tue Jul 18 04:01:05 2017 +0000

description:
3197901

diffstat:

 sys/netipsec/xform_ah.c |  1319 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1319 insertions(+), 0 deletions(-)

diffs (truncated from 1323 to 300 lines):

diff -r 57f75ce3a346 -r 3092d9008d9e sys/netipsec/xform_ah.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/netipsec/xform_ah.c   Tue Jul 18 04:01:05 2017 +0000
@@ -0,0 +1,1319 @@
+/*     $NetBSD: xform_ah.c,v 1.62.2.2 2017/07/18 04:01:05 ozaki-r Exp $        */
+/*     $FreeBSD: src/sys/netipsec/xform_ah.c,v 1.1.4.1 2003/01/24 05:11:36 sam Exp $   */
+/*     $OpenBSD: ip_ah.c,v 1.63 2001/06/26 06:18:58 angelos Exp $ */
+/*
+ * The authors of this code are John Ioannidis (ji%tla.org@localhost),
+ * Angelos D. Keromytis (kermit%csd.uch.gr@localhost) and
+ * Niels Provos (provos%physnet.uni-hamburg.de@localhost).
+ *
+ * The original version of this code was written by John Ioannidis
+ * for BSD/OS in Athens, Greece, in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Additional features in 1999 by Angelos D. Keromytis and Niklas Hallqvist.
+ *
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
+ * Angelos D. Keromytis and Niels Provos.
+ * Copyright (c) 1999 Niklas Hallqvist.
+ * Copyright (c) 2001 Angelos D. Keromytis.
+ *
+ * Permission to use, copy, and modify this software with or without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: xform_ah.c,v 1.62.2.2 2017/07/18 04:01:05 ozaki-r Exp $");
+
+#if defined(_KERNEL_OPT)
+#include "opt_inet.h"
+#include "opt_ipsec.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/socketvar.h> /* for softnet_lock */
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_ecn.h>
+#include <netinet/ip6.h>
+
+#include <net/route.h>
+#include <netipsec/ipsec.h>
+#include <netipsec/ipsec_private.h>
+#include <netipsec/ah.h>
+#include <netipsec/ah_var.h>
+#include <netipsec/xform.h>
+
+#ifdef INET6
+#include <netinet6/ip6_var.h>
+#include <netinet6/scope6_var.h>
+#include <netipsec/ipsec6.h>
+#endif
+
+#include <netipsec/key.h>
+#include <netipsec/key_debug.h>
+
+#include <opencrypto/cryptodev.h>
+
+/*
+ * Return header size in bytes.  The old protocol did not support
+ * the replay counter; the new protocol always includes the counter.
+ */
+#define HDRSIZE(sav) \
+       (((sav)->flags & SADB_X_EXT_OLD) ? \
+               sizeof(struct ah) : sizeof(struct ah) + sizeof(uint32_t))
+/*
+ * Return authenticator size in bytes.  The old protocol is known
+ * to use a fixed 16-byte authenticator.  The new algorithm gets
+ * this size from the xform but is (currently) always 12.
+ */
+#define        AUTHSIZE(sav) \
+       ((sav->flags & SADB_X_EXT_OLD) ? 16 : (sav)->tdb_authalgxform->authsize)
+
+percpu_t *ahstat_percpu;
+
+int    ah_enable = 1;                  /* control flow of packets with AH */
+int    ip4_ah_cleartos = 1;            /* clear ip_tos when doing AH calc */
+
+#ifdef __FreeBSD__
+SYSCTL_DECL(_net_inet_ah);
+SYSCTL_INT(_net_inet_ah, OID_AUTO,
+       ah_enable,      CTLFLAG_RW,     &ah_enable,     0, "");
+SYSCTL_INT(_net_inet_ah, OID_AUTO,
+       ah_cleartos,    CTLFLAG_RW,     &ip4_ah_cleartos,       0, "");
+SYSCTL_STRUCT(_net_inet_ah, IPSECCTL_STATS,
+       stats,          CTLFLAG_RD,     &ahstat,        ahstat, "");
+
+#endif /* __FreeBSD__ */
+
+static unsigned char ipseczeroes[256]; /* larger than an ip6 extension hdr */
+
+static int ah_max_authsize;            /* max authsize over all algorithms */
+
+static int ah_input_cb(struct cryptop *);
+static int ah_output_cb(struct cryptop *);
+
+const uint8_t ah_stats[256] = { SADB_AALG_STATS_INIT };
+
+/*
+ * NB: this is public for use by the PF_KEY support.
+ */
+const struct auth_hash *
+ah_algorithm_lookup(int alg)
+{
+
+       switch (alg) {
+       case SADB_X_AALG_NULL:
+               return &auth_hash_null;
+       case SADB_AALG_MD5HMAC:
+               return &auth_hash_hmac_md5_96;
+       case SADB_AALG_SHA1HMAC:
+               return &auth_hash_hmac_sha1_96;
+       case SADB_X_AALG_RIPEMD160HMAC:
+               return &auth_hash_hmac_ripemd_160_96;
+       case SADB_X_AALG_MD5:
+               return &auth_hash_key_md5;
+       case SADB_X_AALG_SHA:
+               return &auth_hash_key_sha1;
+       case SADB_X_AALG_SHA2_256:
+               return &auth_hash_hmac_sha2_256;
+       case SADB_X_AALG_SHA2_384:
+               return &auth_hash_hmac_sha2_384;
+       case SADB_X_AALG_SHA2_512:
+               return &auth_hash_hmac_sha2_512;
+       case SADB_X_AALG_AES_XCBC_MAC:
+               return &auth_hash_aes_xcbc_mac_96;
+       }
+       return NULL;
+}
+
+size_t
+ah_hdrsiz(const struct secasvar *sav)
+{
+       size_t size;
+
+       if (sav != NULL) {
+               int authsize;
+               KASSERT(sav->tdb_authalgxform != NULL);
+               /*XXX not right for null algorithm--does it matter??*/
+               authsize = AUTHSIZE(sav);
+               size = roundup(authsize, sizeof(uint32_t)) + HDRSIZE(sav);
+       } else {
+               /* default guess */
+               size = sizeof(struct ah) + sizeof(uint32_t) + ah_max_authsize;
+       }
+       return size;
+}
+
+/*
+ * NB: public for use by esp_init.
+ */
+int
+ah_init0(struct secasvar *sav, const struct xformsw *xsp,
+        struct cryptoini *cria)
+{
+       const struct auth_hash *thash;
+       int keylen;
+
+       thash = ah_algorithm_lookup(sav->alg_auth);
+       if (thash == NULL) {
+               DPRINTF(("%s: unsupported authentication algorithm %u\n",
+                       __func__, sav->alg_auth));
+               return EINVAL;
+       }
+       /*
+        * Verify the replay state block allocation is consistent with
+        * the protocol type.  We check here so we can make assumptions
+        * later during protocol processing.
+        */
+       /* NB: replay state is setup elsewhere (sigh) */
+       if (((sav->flags&SADB_X_EXT_OLD) == 0) ^ (sav->replay != NULL)) {
+               DPRINTF(("%s: replay state block inconsistency, "
+                       "%s algorithm %s replay state\n", __func__,
+                       (sav->flags & SADB_X_EXT_OLD) ? "old" : "new",
+                       sav->replay == NULL ? "without" : "with"));
+               return EINVAL;
+       }
+       if (sav->key_auth == NULL) {
+               DPRINTF(("%s: no authentication key for %s algorithm\n",
+                       __func__, thash->name));
+               return EINVAL;
+       }
+       keylen = _KEYLEN(sav->key_auth);
+       if (keylen != thash->keysize && thash->keysize != 0) {
+               DPRINTF(("%s: invalid keylength %d, algorithm %s requires "
+                        "keysize %d\n", __func__,
+                        keylen, thash->name, thash->keysize));
+               return EINVAL;
+       }
+
+       sav->tdb_xform = xsp;
+       sav->tdb_authalgxform = thash;
+
+       /* Initialize crypto session. */
+       memset(cria, 0, sizeof(*cria));
+       cria->cri_alg = sav->tdb_authalgxform->type;
+       cria->cri_klen = _KEYBITS(sav->key_auth);
+       cria->cri_key = _KEYBUF(sav->key_auth);
+
+       return 0;
+}
+
+/*
+ * ah_init() is called when an SPI is being set up.
+ */
+static int
+ah_init(struct secasvar *sav, const struct xformsw *xsp)
+{
+       struct cryptoini cria;
+       int error;
+
+       error = ah_init0(sav, xsp, &cria);
+       if (!error)
+               error = crypto_newsession(&sav->tdb_cryptoid,
+                                          &cria, crypto_support);
+       return error;
+}
+
+/*
+ * Paranoia.
+ *
+ * NB: public for use by esp_zeroize (XXX).
+ */
+int
+ah_zeroize(struct secasvar *sav)
+{
+       int err;
+
+       if (sav->key_auth) {
+               explicit_memset(_KEYBUF(sav->key_auth), 0,
+                   _KEYLEN(sav->key_auth));
+       }
+
+       err = crypto_freesession(sav->tdb_cryptoid);
+       sav->tdb_cryptoid = 0;
+       sav->tdb_authalgxform = NULL;
+       sav->tdb_xform = NULL;
+       return err;
+}
+
+/*
+ * Massage IPv4/IPv6 headers for AH processing.
+ */
+static int
+ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
+{
+       struct mbuf *m = *m0;
+       unsigned char *ptr;
+       int off, count;
+
+#ifdef INET
+       struct ip *ip;
+#endif /* INET */
+
+#ifdef INET6
+       struct ip6_ext *ip6e;
+       struct ip6_hdr ip6;
+       struct ip6_rthdr *rh;
+       int alloc, ad, nxt;
+#endif /* INET6 */
+
+       switch (proto) {
+#ifdef INET
+       case AF_INET:
+               /*
+                * This is the least painful way of dealing with IPv4 header
+                * and option processing -- just make sure they're in
+                * contiguous memory.
+                */
+               *m0 = m = m_pullup(m, skip);
+               if (m == NULL) {



Home | Main Index | Thread Index | Old Index