Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 Import IPsec ESP from netbsd-cryptosrc-intl.



details:   https://anonhg.NetBSD.org/src/rev/24f9a6ab0996
branches:  trunk
changeset: 487910:24f9a6ab0996
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Jun 14 19:39:42 2000 +0000

description:
Import IPsec ESP from netbsd-cryptosrc-intl.

diffstat:

 sys/netinet6/esp_core.c   |  1282 +++++++++++++++++++++++++++++++++++++++++++++
 sys/netinet6/esp_input.c  |   798 ++++++++++++++++++++++++++++
 sys/netinet6/esp_output.c |   669 +++++++++++++++++++++++
 3 files changed, 2749 insertions(+), 0 deletions(-)

diffs (truncated from 2761 to 300 lines):

diff -r 4fce8abe4274 -r 24f9a6ab0996 sys/netinet6/esp_core.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/netinet6/esp_core.c   Wed Jun 14 19:39:42 2000 +0000
@@ -0,0 +1,1282 @@
+/*     $NetBSD: esp_core.c,v 1.1.1.1 2000/06/14 19:39:43 thorpej Exp $ */
+/*     $KAME: esp_core.c,v 1.15 2000/06/14 10:41:18 itojun Exp $       */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_inet.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/kernel.h>
+#include <sys/syslog.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#include <netinet/icmp6.h>
+#endif
+
+#include <netinet6/ipsec.h>
+#include <netinet6/ah.h>
+#include <netinet6/esp.h>
+#include <net/pfkeyv2.h>
+#include <netkey/keydb.h>
+#include <crypto/des/des.h>
+#include <crypto/blowfish/blowfish.h>
+#include <crypto/cast128/cast128.h>
+#ifdef SADB_EALG_RC5CBC
+#include <crypto/rc5/rc5.h>
+#endif
+
+#include <net/net_osdep.h>
+
+static int esp_null_mature __P((struct secasvar *));
+static int esp_null_ivlen __P((struct secasvar *));
+static int esp_null_decrypt __P((struct mbuf *, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_null_encrypt __P((struct mbuf *, size_t, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_descbc_mature __P((struct secasvar *));
+static int esp_descbc_ivlen __P((struct secasvar *));
+static int esp_descbc_decrypt __P((struct mbuf *, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_descbc_encrypt __P((struct mbuf *, size_t, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_cbc_mature __P((struct secasvar *));
+static int esp_blowfish_cbc_decrypt __P((struct mbuf *, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_blowfish_cbc_encrypt __P((struct mbuf *, size_t,
+       size_t, struct secasvar *, struct esp_algorithm *, int));
+static int esp_blowfish_cbc_ivlen __P((struct secasvar *));
+static int esp_cast128cbc_ivlen __P((struct secasvar *));
+static int esp_cast128cbc_decrypt __P((struct mbuf *, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_cast128cbc_encrypt __P((struct mbuf *, size_t, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_3descbc_ivlen __P((struct secasvar *));
+static int esp_3descbc_decrypt __P((struct mbuf *, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_3descbc_encrypt __P((struct mbuf *, size_t, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+#ifdef SADB_EALG_RC5CBC
+static int esp_rc5cbc_ivlen __P((struct secasvar *));
+static int esp_rc5cbc_decrypt __P((struct mbuf *, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+static int esp_rc5cbc_encrypt __P((struct mbuf *, size_t, size_t,
+       struct secasvar *, struct esp_algorithm *, int));
+#endif
+static void esp_increment_iv __P((struct secasvar *));
+static caddr_t mbuf_find_offset __P((struct mbuf *, size_t, size_t));
+
+/* NOTE: The order depends on SADB_EALG_x in netkey/keyv2.h */
+struct esp_algorithm esp_algorithms[] = {
+       { 0, 0, 0, 0, 0, 0, 0, },
+       { 8, esp_descbc_mature, 64, 64, "des-cbc",
+               esp_descbc_ivlen, esp_descbc_decrypt, esp_descbc_encrypt, },
+       { 8, esp_cbc_mature, 192, 192, "3des-cbc",
+               esp_3descbc_ivlen, esp_3descbc_decrypt, esp_3descbc_encrypt, },
+       { 1, esp_null_mature, 0, 2048, "null",
+               esp_null_ivlen, esp_null_decrypt, esp_null_encrypt, },
+       { 8, esp_cbc_mature, 40, 448, "blowfish-cbc",
+               esp_blowfish_cbc_ivlen, esp_blowfish_cbc_decrypt,
+               esp_blowfish_cbc_encrypt, },
+       { 8, esp_cbc_mature, 40, 128, "cast128-cbc",
+               esp_cast128cbc_ivlen, esp_cast128cbc_decrypt,
+               esp_cast128cbc_encrypt, },
+#ifdef SADB_EALG_RC5CBC
+       { 8, esp_cbc_mature, 40, 2040, "rc5-cbc",
+               esp_rc5cbc_ivlen, esp_rc5cbc_decrypt, esp_rc5cbc_encrypt, },
+#endif
+};
+
+/*
+ * mbuf assumption: foo_encrypt() assumes that IV part is placed in a single
+ * mbuf, not across multiple mbufs.
+ */
+
+static int
+esp_null_mature(sav)
+       struct secasvar *sav;
+{
+       /* anything is okay */
+       return 0;
+}
+
+static int
+esp_null_ivlen(sav)
+       struct secasvar *sav;
+{
+       return 0;
+}
+
+static int
+esp_null_decrypt(m, off, sav, algo, ivlen)
+       struct mbuf *m;
+       size_t off;             /* offset to ESP header */
+       struct secasvar *sav;
+       struct esp_algorithm *algo;
+       int ivlen;
+{
+       return 0; /* do nothing */
+}
+
+static int
+esp_null_encrypt(m, off, plen, sav, algo, ivlen)
+       struct mbuf *m;
+       size_t off;     /* offset to ESP header */
+       size_t plen;    /* payload length (to be encrypted) */
+       struct secasvar *sav;
+       struct esp_algorithm *algo;
+       int ivlen;
+{
+       return 0; /* do nothing */
+}
+
+static int
+esp_descbc_mature(sav)
+       struct secasvar *sav;
+{
+       struct esp_algorithm *algo;
+
+       if (!(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B)) {
+               ipseclog((LOG_ERR, "esp_cbc_mature: "
+                   "algorithm incompatible with 4 octets IV length\n"));
+               return 1;
+       }
+
+       if (!sav->key_enc) {
+               ipseclog((LOG_ERR, "esp_descbc_mature: no key is given.\n"));
+               return 1;
+       }
+       algo = &esp_algorithms[sav->alg_enc];
+       if (_KEYBITS(sav->key_enc) < algo->keymin
+        || algo->keymax < _KEYBITS(sav->key_enc)) {
+               ipseclog((LOG_ERR,
+                   "esp_descbc_mature: invalid key length %d.\n",
+                   _KEYBITS(sav->key_enc)));
+               return 1;
+       }
+
+       /* weak key check */
+       if (des_is_weak_key((C_Block *)_KEYBUF(sav->key_enc))) {
+               ipseclog((LOG_ERR,
+                   "esp_descbc_mature: weak key was passed.\n"));
+               return 1;
+       }
+
+       return 0;
+}
+
+static int
+esp_descbc_ivlen(sav)
+       struct secasvar *sav;
+{
+       if (sav && (sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_IV4B))
+               return 4;
+
+       if (sav && !(sav->flags & SADB_X_EXT_OLD) && (sav->flags & SADB_X_EXT_DERIV))
+               return 4;
+       else
+               return 8;
+}
+
+static int
+esp_descbc_decrypt(m, off, sav, algo, ivlen)
+       struct mbuf *m;
+       size_t off;             /* offset to ESP header */
+       struct secasvar *sav;
+       struct esp_algorithm *algo;
+       int ivlen;
+{
+       size_t ivoff = 0;
+       size_t bodyoff = 0;
+       u_int8_t *iv;
+       size_t plen;
+       u_int8_t tiv[8];
+       int derived;
+       int error;
+
+       derived = 0;
+       /* sanity check */
+       if (ivlen != sav->ivlen) {
+               ipseclog((LOG_ERR, "esp_descbc_decrypt: bad ivlen %d/%d\n",
+                   ivlen, sav->ivlen));
+               return EINVAL;
+       }
+       if (_KEYBITS(sav->key_enc) < algo->keymin
+        || algo->keymax < _KEYBITS(sav->key_enc)) {
+               ipseclog((LOG_ERR, "esp_descbc_decrypt: bad keylen %d\n",
+                   _KEYBITS(sav->key_enc)));
+               return EINVAL;
+       }
+
+       if (sav->flags & SADB_X_EXT_OLD) {
+               /* RFC 1827 */
+               ivoff = off + sizeof(struct esp);
+               bodyoff = off + sizeof(struct esp) + ivlen;
+               derived = 0;
+       } else {
+               /* RFC 2406 */
+               if (sav->flags & SADB_X_EXT_DERIV) {
+                       /*
+                        * draft-ietf-ipsec-ciph-des-derived-00.txt
+                        * uses sequence number field as IV field.
+                        * This draft has been deleted, but you can get from
+                        * ftp://ftp.kame.net/pub/internet-drafts/.
+                        */
+                       ivoff = off + sizeof(struct esp);
+                       bodyoff = off + sizeof(struct esp) + sizeof(u_int32_t);
+                       ivlen = sizeof(u_int32_t);
+                       derived = 1;
+               } else {
+                       ivoff = off + sizeof(struct newesp);
+                       bodyoff = off + sizeof(struct newesp) + ivlen;
+                       derived = 0;
+               }
+       }
+       if (ivlen == 4) {
+               iv = &tiv[0];
+               m_copydata(m, ivoff, 4, &tiv[0]);
+               m_copydata(m, ivoff, 4, &tiv[4]);
+               tiv[4] ^= 0xff;
+               tiv[5] ^= 0xff;
+               tiv[6] ^= 0xff;
+               tiv[7] ^= 0xff;
+       } else if (ivlen == 8) {
+               iv = &tiv[0];
+               m_copydata(m, ivoff, 8, &tiv[0]);
+       } else {
+               ipseclog((LOG_ERR, "esp_descbc_decrypt: unsupported ivlen %d\n",
+                   ivlen));
+               return EINVAL;
+       }
+
+       plen = m->m_pkthdr.len;
+       if (plen < bodyoff)
+               panic("esp_descbc_decrypt: too short packet: len=%lu",
+                   (u_long)plen);



Home | Main Index | Thread Index | Old Index