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