diff options
author | 1997-07-11 23:49:16 +0000 | |
---|---|---|
committer | 1997-07-11 23:49:16 +0000 | |
commit | 9e90fb05e161aa7df65248dc9b388325b411b00b (patch) | |
tree | 5419cb3401f09392e319e971edaa8429eddf49d7 | |
parent | argh. commited wrong file (diff) | |
download | wireguard-openbsd-9e90fb05e161aa7df65248dc9b388325b411b00b.tar.xz wireguard-openbsd-9e90fb05e161aa7df65248dc9b388325b411b00b.zip |
obsolete.
-rw-r--r-- | sys/netinet/ip_ahhmacmd5.c | 526 | ||||
-rw-r--r-- | sys/netinet/ip_ahhmacsha1.c | 531 | ||||
-rw-r--r-- | sys/netinet/ip_ahmd5.c | 417 | ||||
-rw-r--r-- | sys/netinet/ip_ahsha1.c | 415 | ||||
-rw-r--r-- | sys/netinet/ip_esp3des.c | 484 | ||||
-rw-r--r-- | sys/netinet/ip_esp3desmd5.c | 780 | ||||
-rw-r--r-- | sys/netinet/ip_espdes.c | 547 | ||||
-rw-r--r-- | sys/netinet/ip_espdesmd5.c | 845 |
8 files changed, 0 insertions, 4545 deletions
diff --git a/sys/netinet/ip_ahhmacmd5.c b/sys/netinet/ip_ahhmacmd5.c deleted file mode 100644 index 55284cd715e..00000000000 --- a/sys/netinet/ip_ahhmacmd5.c +++ /dev/null @@ -1,526 +0,0 @@ -/* $OpenBSD: ip_ahhmacmd5.c,v 1.13 1997/07/01 22:12:42 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Based on RFC 2085. - */ - -#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/socketvar.h> - -#include <machine/cpu.h> -#include <machine/endian.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> -#include <net/raw_cb.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#include <netinet/ip_icmp.h> - -#include <net/encap.h> - -#include <netinet/ip_ipsp.h> -#include <netinet/ip_ah.h> - -/* - * ahhmacmd5_attach() is called from the transformation initialization code. - * It just returns. - */ - -int -ahhmacmd5_attach() -{ - return 0; -} - -/* - * ahhmacmd5_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data. - */ - -int -ahhmacmd5_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct ahhmacmd5_xdata *xd; - struct ahhmacmd5_xencap txd; - struct encap_msghdr *em; - int len; - - tdbp->tdb_xform = xsp; - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct ahhmacmd5_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct ahhmacmd5_xdata)); - bzero(&txd, sizeof(struct ahhmacmd5_xencap)); - xd = (struct ahhmacmd5_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahhmacmd5_xencap)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, - (caddr_t)&txd); - - xd->amx_rpl = 1; - xd->amx_alen = txd.amx_alen; - xd->amx_bitmap = 0; - xd->amx_wnd = txd.amx_wnd; - - MD5Init(&(xd->amx_ictx)); - MD5Init(&(xd->amx_octx)); - - for (len = 0; len < AHHMACMD5_KMAX; len++) - txd.amx_key[len] ^= HMACMD5_IPAD_VAL; - - MD5Update(&(xd->amx_ictx), txd.amx_key, AHHMACMD5_KMAX); - - for (len = 0; len < AHHMACMD5_KMAX; len++) - txd.amx_key[len] ^= (HMACMD5_IPAD_VAL ^ HMACMD5_OPAD_VAL); - - MD5Update(&(xd->amx_octx), txd.amx_key, AHHMACMD5_KMAX); - bzero(&txd, sizeof(struct ahhmacmd5_xencap)); - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - - return 0; -} - -/* - * Free memory - */ - -int -ahhmacmd5_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - -/* - * ahhmacmd5_input() gets called to verify that an input packet - * passes authentication. - */ - -extern struct ifnet loif; - -struct mbuf * -ahhmacmd5_input(struct mbuf *m, struct tdb *tdb) -{ - struct ahhmacmd5_xdata *xd; - struct ip *ip, ipo; - struct ah *ah; - struct ahhmacmd5 aho, *ahp; - struct ifnet *rcvif; - int ohlen, len, count, off, ado, errc; - u_int64_t btsx; - struct mbuf *m0; - MD5_CTX ctx; - u_int8_t optval; - - xd = (struct ahhmacmd5_xdata *)tdb->tdb_xdata; - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; - if (xd->amx_wnd >= 0) - ohlen += HMACMD5_RPLENGTH; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahhmacmd5_input: receive interface is NULL!!!\n"); -#endif - rcvif = &loif; - } - - if (m->m_len < ohlen) - { - if ((m = m_pullup(m, ohlen)) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - } - - ip = mtod(m, struct ip *); - - if ((ip->ip_hl << 2) > sizeof(struct ip)) - { - if ((m = m_pullup(m, ohlen - sizeof (struct ip) + - (ip->ip_hl << 2))) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - - ip = mtod(m, struct ip *); - ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); - } - else - ah = (struct ah *)(ip + 1); - - ahp = (struct ahhmacmd5 *)ah; - - if (xd->amx_wnd >= 0) - ado = HMACMD5_RPLENGTH; - else - ado = 0; - - if (ah->ah_hl * sizeof(u_int32_t) != xd->amx_alen + ado) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahhmacmd5_input: bad authenticator length\n"); -#endif - ahstat.ahs_badauthl++; - m_freem(m); - return NULL; - } - - ipo = *ip; - ipo.ip_tos = 0; - ipo.ip_len += sizeof(struct ip); /* adjusted in ip_intr() */ - HTONS(ipo.ip_len); - HTONS(ipo.ip_id); - ipo.ip_off = htons(ipo.ip_off & IP_DF); /* XXX -- and the C bit? */ - ipo.ip_ttl = 0; - ipo.ip_sum = 0; - - ctx = xd->amx_ictx; - MD5Update(&ctx, (unsigned char *)&ipo, sizeof(struct ip)); - - /* Options */ - if ((ip->ip_hl << 2 > sizeof(struct ip))) - for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) - { - optval = ((u_int8_t *)ip)[off]; - switch (optval) - { - case IPOPT_EOL: - MD5Update(&ctx, ipseczeroes, 1); - off = ip->ip_hl << 2; - break; - - case IPOPT_NOP: - MD5Update(&ctx, ipseczeroes, 1); - off++; - break; - - case IPOPT_SECURITY: - case 133: - case 134: - optval = ((u_int8_t *)ip)[off + 1]; - MD5Update(&ctx, (u_int8_t *)ip + off, optval); - off += optval; - break; - - default: - optval = ((u_int8_t *)ip)[off + 1]; - MD5Update(&ctx, ipseczeroes, optval); - off += optval; - break; - } - } - - if (xd->amx_wnd >= 0) - MD5Update(&ctx, (unsigned char *)ahp, AH_FLENGTH + HMACMD5_RPLENGTH); - else - MD5Update(&ctx, (unsigned char *)ahp, AH_FLENGTH); - MD5Update(&ctx, ipseczeroes, xd->amx_alen); - - /* - * Code shamelessly stolen from m_copydata - */ - off = ohlen; - len = m->m_pkthdr.len - off; - m0 = m; - - while (off > 0) - { - if (m0 == 0) - panic("ahhmacmd5_input: m_copydata (off)"); - if (off < m0->m_len) - break; - off -= m0->m_len; - m0 = m0->m_next; - } - - while (len > 0) - { - if (m0 == 0) - panic("ahhmacmd5_input: m_copydata (copy)"); - count = min(m0->m_len - off, len); - MD5Update(&ctx, mtod(m0, unsigned char *) + off, count); - len -= count; - off = 0; - m0 = m0->m_next; - } - - MD5Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - ctx = xd->amx_octx; - MD5Update(&ctx, (unsigned char *)(&(aho.ah_data[0])), HMACMD5_HASHLEN); - MD5Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - - if (bcmp(aho.ah_data, ah->ah_data + ado, xd->amx_alen)) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahhmacmd5_input: bad auth\n"); /* XXX */ -#endif - ahstat.ahs_badauth++; - m_freem(m); - return NULL; - } - - if (xd->amx_wnd >= 0) - { - btsx = ntohq(ahp->ah_rpl); - if ((errc = checkreplaywindow64(btsx, &(xd->amx_rpl), - xd->amx_wnd, &(xd->amx_bitmap))) - != 0) - { - switch(errc) - { - case 1: -#ifdef ENCDEBUG - printf("ahhmacmd5_input: replay counter wrapped\n"); -#endif - ahstat.ahs_wrap++; - break; - case 2: -#ifdef ENCDEBUG - printf("ahhmacmd5_input: received old packet\n"); -#endif - ahstat.ahs_replay++; - break; - case 3: -#ifdef ENCDEBUG - printf("ahhmacmd5_input: packet already received\n"); -#endif - ahstat.ahs_replay++; - break; - } - m_freem(m); - return NULL; - } - } - - ipo = *ip; - ipo.ip_p = ah->ah_nh; - - m->m_len -= (ohlen - sizeof(struct ip)); - m->m_data += (ohlen - sizeof(struct ip)); - m->m_pkthdr.len -= (ohlen - sizeof(struct ip)); - m->m_pkthdr.rcvif = rcvif; /* this should not be necessary */ - - ip = mtod(m, struct ip *); - *ip = ipo; - ip->ip_len = htons(ip->ip_len - ohlen + 2 * sizeof (struct ip)); - HTONS(ip->ip_id); - HTONS(ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2); - - return m; -} - - -#define AHXPORT - -int -ahhmacmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct ahhmacmd5_xdata *xd; - struct ip *ip, ipo; - struct ah *ah; - struct ahhmacmd5 *ahp, aho; - register int len, off, count; - register struct mbuf *m0; - MD5_CTX ctx; - int ilen, ohlen; - - ahstat.ahs_output++; - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - xd = (struct ahhmacmd5_xdata *)tdb->tdb_xdata; - - ilen = ntohs(ip->ip_len); - -#ifdef AHXPORT - ohlen = AH_FLENGTH + xd->amx_alen; -#else - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; -#endif - if (xd->amx_wnd >= 0) - ohlen += HMACMD5_RPLENGTH; - - ipo.ip_v = IPVERSION; - ipo.ip_hl = 5; - ipo.ip_tos = 0; - ipo.ip_len = htons(ohlen + ilen); - ipo.ip_id = ip->ip_id; - ipo.ip_off = htons(ntohs(ip->ip_off) & IP_DF); - ipo.ip_ttl = 0; - ipo.ip_p = IPPROTO_AH; - ipo.ip_sum = 0; -#ifdef AHXPORT - ipo.ip_src = ip->ip_src; - ipo.ip_dst = ip->ip_dst; - aho.ah_nh = ip->ip_p; -#else - ipo.ip_src = gw->sen_ipsp_src; - ipo.ip_dst = gw->sen_ipsp_dst; - aho.ah_nh = IPPROTO_IP4; -#endif - aho.ah_hl = (xd->amx_alen >> 2); - if (xd->amx_wnd >= 0) - aho.ah_hl += (HMACMD5_RPLENGTH / sizeof(u_int32_t)); - aho.ah_rv = 0; - aho.ah_spi = tdb->tdb_spi; - - if (xd->amx_wnd >= 0) - { - if (xd->amx_rpl == 0) - { -#ifdef ENCDEBUG - printf("ahhmacmd5_output: key should have changed long ago\n"); -#endif - ahstat.ahs_wrap++; - return NULL; - } - } - - aho.ah_rpl = htonq(xd->amx_rpl++); - - ctx = xd->amx_ictx; - MD5Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); - if (xd->amx_wnd >= 0) - MD5Update(&ctx, (unsigned char *)&aho, AH_FLENGTH + HMACMD5_RPLENGTH); - else - MD5Update(&ctx, (unsigned char *)&aho, AH_FLENGTH); - MD5Update(&ctx, ipseczeroes, xd->amx_alen); - -#ifdef AHXPORT - off = sizeof (struct ip); -#else - off = 0; -#endif - - /* - * Code shamelessly stolen from m_copydata - */ - len = m->m_pkthdr.len - off; - - m0 = m; - - while (len > 0) - { - if (m0 == 0) - panic("ahhmacmd5_output: m_copydata"); - count = min(m0->m_len - off, len); - MD5Update(&ctx, mtod(m0, unsigned char *) + off, count); - - len -= count; - off = 0; - m0 = m0->m_next; - } - - MD5Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - ctx = xd->amx_octx; - MD5Update(&ctx, (unsigned char *)(&(aho.ah_data[0])), HMACMD5_HASHLEN); - MD5Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - - ipo.ip_tos = ip->ip_tos; - ipo.ip_id = ip->ip_id; - ipo.ip_off = ip->ip_off; - ipo.ip_ttl = ip->ip_ttl; -/* ipo.ip_len = ntohs(ipo.ip_len); */ - - M_PREPEND(m, ohlen, M_DONTWAIT); - if (m == NULL) - return ENOBUFS; - - m = m_pullup(m, ohlen + sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); - ahp = (struct ahhmacmd5 *)ah; - *ip = ipo; - ah->ah_nh = aho.ah_nh; - ah->ah_hl = aho.ah_hl; - ah->ah_rv = aho.ah_rv; - ah->ah_spi = aho.ah_spi; - if (xd->amx_wnd >= 0) - { - ahp->ah_rpl = aho.ah_rpl; - bcopy((unsigned char *)(&(aho.ah_data[0])), - ahp->ah_data, xd->amx_alen); - } - else - bcopy((unsigned char *)(&(aho.ah_data[0])), - ah->ah_data, xd->amx_alen); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - - xd->amx_alen; - if (xd->amx_wnd >= 0) - tdb->tdb_cur_bytes -= HMACMD5_RPLENGTH; - - return 0; -} diff --git a/sys/netinet/ip_ahhmacsha1.c b/sys/netinet/ip_ahhmacsha1.c deleted file mode 100644 index 9e3fa61bdb9..00000000000 --- a/sys/netinet/ip_ahhmacsha1.c +++ /dev/null @@ -1,531 +0,0 @@ -/* $OpenBSD: ip_ahhmacsha1.c,v 1.11 1997/07/01 22:12:43 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Based on draft-ietf-ipsec-ah-hmac-sha-04.txt. - */ - -#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/socketvar.h> - -#include <machine/cpu.h> -#include <machine/endian.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> -#include <net/raw_cb.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#include <netinet/ip_icmp.h> - -#include <net/encap.h> - -#include <netinet/ip_ipsp.h> -#include <netinet/ip_ah.h> - -/* - * ahhmacsha1_attach() is called from the transformation initialization code. - * It just returns. - */ - -int -ahhmacsha1_attach() -{ - return 0; -} - -/* - * ahhmacsha1_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data. - */ - -int -ahhmacsha1_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct ahhmacsha1_xdata *xd; - struct ahhmacsha1_xencap txd; - struct encap_msghdr *em; - int len; - - tdbp->tdb_xform = xsp; - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct ahhmacsha1_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct ahhmacsha1_xdata)); - bzero(&txd, sizeof(struct ahhmacsha1_xencap)); - xd = (struct ahhmacsha1_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahhmacsha1_xencap)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, - (caddr_t)&txd); - - xd->amx_rpl = 1; - xd->amx_alen = txd.amx_alen; - xd->amx_bitmap = 0; - xd->amx_wnd = txd.amx_wnd; - - SHA1Init(&(xd->amx_ictx)); - SHA1Init(&(xd->amx_octx)); - - for (len = 0; len < AHHMACSHA1_KMAX; len++) - txd.amx_key[len] ^= HMACSHA1_IPAD_VAL; - - SHA1Update(&(xd->amx_ictx), txd.amx_key, AHHMACSHA1_KMAX); - - for (len = 0; len < AHHMACSHA1_KMAX; len++) - txd.amx_key[len] ^= (HMACSHA1_IPAD_VAL ^ HMACSHA1_OPAD_VAL); - - SHA1Update(&(xd->amx_octx), txd.amx_key, AHHMACSHA1_KMAX); - bzero(&txd, sizeof(struct ahhmacsha1_xencap)); - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - - return 0; -} - -/* - * Free memory - */ - -int -ahhmacsha1_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - -/* - * ahhmacsha1_input() gets called to verify that an input packet - * passes authentication. - */ - -extern struct ifnet loif; - -struct mbuf * -ahhmacsha1_input(struct mbuf *m, struct tdb *tdb) -{ - struct ahhmacsha1_xdata *xd; - struct ip *ip, ipo; - struct ah *ah; - struct ahhmacsha1 aho, *ahp; - struct ifnet *rcvif; - int ohlen, len, count, off, ado, errc; - u_int64_t btsx; - struct mbuf *m0; - SHA1_CTX ctx; - u_int8_t optval; - - xd = (struct ahhmacsha1_xdata *)tdb->tdb_xdata; - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; - if (xd->amx_wnd >= 0) - ohlen += HMACSHA1_RPLENGTH; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahhmacsha1_input: receive interface is NULL!!!\n"); -#endif - rcvif = &loif; - } - - if (m->m_len < ohlen) - { - if ((m = m_pullup(m, ohlen)) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - } - - ip = mtod(m, struct ip *); - - ip = mtod(m, struct ip *); - - if ((ip->ip_hl << 2) > sizeof(struct ip)) - { - if ((m = m_pullup(m, ohlen - sizeof (struct ip) + - (ip->ip_hl << 2))) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - - ip = mtod(m, struct ip *); - ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); - } - else - ah = (struct ah *)(ip + 1); - ahp = (struct ahhmacsha1 *)ah; - - if (xd->amx_wnd >= 0) - ado = HMACSHA1_RPLENGTH; - else - ado = 0; - - if (ah->ah_hl * sizeof(u_int32_t) != xd->amx_alen + ado) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahhmacsha1_input: bad authenticator length\n"); -#endif - ahstat.ahs_badauthl++; - m_freem(m); - return NULL; - } - - ipo = *ip; - ipo.ip_tos = 0; - ipo.ip_len += sizeof(struct ip); /* adjusted in ip_intr() */ - HTONS(ipo.ip_len); - HTONS(ipo.ip_id); - ipo.ip_off = htons(ipo.ip_off & IP_DF); /* XXX -- and the C bit? */ - ipo.ip_ttl = 0; - ipo.ip_sum = 0; - - ctx = xd->amx_ictx; - SHA1Update(&ctx, (unsigned char *)&ipo, sizeof(struct ip)); - - /* Options */ - if ((ip->ip_hl << 2 > sizeof(struct ip))) - for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) - { - optval = ((u_int8_t *)ip)[off]; - switch (optval) - { - case IPOPT_EOL: - SHA1Update(&ctx, ipseczeroes, 1); - off = ip->ip_hl << 2; - break; - - case IPOPT_NOP: - SHA1Update(&ctx, ipseczeroes, 1); - off++; - break; - - case IPOPT_SECURITY: - case 133: - case 134: - optval = ((u_int8_t *)ip)[off + 1]; - SHA1Update(&ctx, (u_int8_t *)ip + off, optval); - off += optval; - break; - - default: - optval = ((u_int8_t *)ip)[off + 1]; - SHA1Update(&ctx, ipseczeroes, optval); - off += optval; - break; - } - } - - if (xd->amx_wnd >= 0) - SHA1Update(&ctx, (unsigned char *)ahp, - AH_FLENGTH + HMACSHA1_RPLENGTH); - else - SHA1Update(&ctx, (unsigned char *)ahp, AH_FLENGTH); - SHA1Update(&ctx, ipseczeroes, xd->amx_alen); - - /* - * Code shamelessly stolen from m_copydata - */ - off = ohlen; - len = m->m_pkthdr.len - off; - m0 = m; - - while (off > 0) - { - if (m0 == 0) - panic("ahhmacsha1_input: m_copydata (off)"); - if (off < m0->m_len) - break; - off -= m0->m_len; - m0 = m0->m_next; - } - - while (len > 0) - { - if (m0 == 0) - panic("ahhmacsha1_input: m_copydata (copy)"); - count = min(m0->m_len - off, len); - SHA1Update(&ctx, mtod(m0, unsigned char *) + off, count); - len -= count; - off = 0; - m0 = m0->m_next; - } - - SHA1Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - ctx = xd->amx_octx; - SHA1Update(&ctx, (unsigned char *)(&(aho.ah_data[0])), - HMACSHA1_HASHLEN); - SHA1Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - - if (bcmp(aho.ah_data, ah->ah_data + ado, xd->amx_alen)) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahhmacsha1_input: bad auth\n"); /* XXX */ -#endif - ahstat.ahs_badauth++; - m_freem(m); - return NULL; - } - - if (xd->amx_wnd >= 0) - { - btsx = ntohq(ahp->ah_rpl); - if ((errc = checkreplaywindow64(btsx, &(xd->amx_rpl), - xd->amx_wnd, &(xd->amx_bitmap))) - != 0) - { - switch(errc) - { - case 1: -#ifdef ENCDEBUG - printf("ahhmacsha1_input: replay counter wrapped\n"); -#endif - ahstat.ahs_wrap++; - break; - case 2: -#ifdef ENCDEBUG - printf("ahhmacsha1_input: received old packet\n"); -#endif - ahstat.ahs_replay++; - break; - case 3: -#ifdef ENCDEBUG - printf("ahhmacsha1_input: packet already received\n"); -#endif - ahstat.ahs_replay++; - break; - } - m_freem(m); - return NULL; - } - } - - ipo = *ip; - ipo.ip_p = ah->ah_nh; - - m->m_len -= (ohlen - sizeof(struct ip)); - m->m_data += (ohlen - sizeof(struct ip)); - m->m_pkthdr.len -= (ohlen - sizeof(struct ip)); - m->m_pkthdr.rcvif = rcvif; /* this should not be necessary */ - - ip = mtod(m, struct ip *); - *ip = ipo; - ip->ip_len = htons(ip->ip_len - ohlen + 2 * sizeof (struct ip)); - HTONS(ip->ip_id); - HTONS(ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2); - - return m; -} - - -#define AHXPORT - -int -ahhmacsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct ahhmacsha1_xdata *xd; - struct ip *ip, ipo; - struct ah *ah; - struct ahhmacsha1 *ahp, aho; - register int len, off, count; - register struct mbuf *m0; - SHA1_CTX ctx; - int ilen, ohlen; - - ahstat.ahs_output++; - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - xd = (struct ahhmacsha1_xdata *)tdb->tdb_xdata; - - ilen = ntohs(ip->ip_len); - -#ifdef AHXPORT - ohlen = AH_FLENGTH + xd->amx_alen; -#else - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; -#endif - if (xd->amx_wnd >= 0) - ohlen += HMACSHA1_RPLENGTH; - - ipo.ip_v = IPVERSION; - ipo.ip_hl = 5; - ipo.ip_tos = 0; - ipo.ip_len = htons(ohlen + ilen); - ipo.ip_id = ip->ip_id; - ipo.ip_off = htons(ntohs(ip->ip_off) & IP_DF); - ipo.ip_ttl = 0; - ipo.ip_p = IPPROTO_AH; - ipo.ip_sum = 0; -#ifdef AHXPORT - ipo.ip_src = ip->ip_src; - ipo.ip_dst = ip->ip_dst; - aho.ah_nh = ip->ip_p; -#else - ipo.ip_src = gw->sen_ipsp_src; - ipo.ip_dst = gw->sen_ipsp_dst; - aho.ah_nh = IPPROTO_IP4; -#endif - aho.ah_hl = (xd->amx_alen >> 2); - if (xd->amx_wnd >= 0) - aho.ah_hl += (HMACSHA1_RPLENGTH / sizeof(u_int32_t)); - aho.ah_rv = 0; - aho.ah_spi = tdb->tdb_spi; - - if (xd->amx_wnd >= 0) - { - if (xd->amx_rpl == 0) - { -#ifdef ENCDEBUG - printf("ahhmacsha1_output: key should have changed long ago\n"); -#endif - ahstat.ahs_wrap++; - return NULL; - } - } - - aho.ah_rpl = htonq(xd->amx_rpl++); - - ctx = xd->amx_ictx; - SHA1Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); - if (xd->amx_wnd >= 0) - SHA1Update(&ctx, (unsigned char *)&aho, - AH_FLENGTH + HMACSHA1_RPLENGTH); - else - SHA1Update(&ctx, (unsigned char *)&aho, AH_FLENGTH); - SHA1Update(&ctx, ipseczeroes, xd->amx_alen); - -#ifdef AHXPORT - off = sizeof (struct ip); -#else - off = 0; -#endif - - /* - * Code shamelessly stolen from m_copydata - */ - len = m->m_pkthdr.len - off; - - m0 = m; - - while (len > 0) - { - if (m0 == 0) - panic("ahhmacsha1_output: m_copydata"); - count = min(m0->m_len - off, len); - SHA1Update(&ctx, mtod(m0, unsigned char *) + off, count); - - len -= count; - off = 0; - m0 = m0->m_next; - } - - SHA1Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - ctx = xd->amx_octx; - SHA1Update(&ctx, (unsigned char *)(&(aho.ah_data[0])), - HMACSHA1_HASHLEN); - SHA1Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - - ipo.ip_tos = ip->ip_tos; - ipo.ip_id = ip->ip_id; - ipo.ip_off = ip->ip_off; - ipo.ip_ttl = ip->ip_ttl; -/* ipo.ip_len = ntohs(ipo.ip_len); */ - - M_PREPEND(m, ohlen, M_DONTWAIT); - if (m == NULL) - return ENOBUFS; - - m = m_pullup(m, ohlen + sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); - ahp = (struct ahhmacsha1 *)ah; - *ip = ipo; - ah->ah_nh = aho.ah_nh; - ah->ah_hl = aho.ah_hl; - ah->ah_rv = aho.ah_rv; - ah->ah_spi = aho.ah_spi; - if (xd->amx_wnd >= 0) - { - ahp->ah_rpl = aho.ah_rpl; - bcopy((unsigned char *)(&(aho.ah_data[0])), - ahp->ah_data, xd->amx_alen); - } - else - bcopy((unsigned char *)(&(aho.ah_data[0])), - ah->ah_data, xd->amx_alen); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - - xd->amx_alen; - if (xd->amx_wnd >= 0) - tdb->tdb_cur_bytes -= HMACSHA1_RPLENGTH; - - return 0; -} diff --git a/sys/netinet/ip_ahmd5.c b/sys/netinet/ip_ahmd5.c deleted file mode 100644 index f3d406dcd8f..00000000000 --- a/sys/netinet/ip_ahmd5.c +++ /dev/null @@ -1,417 +0,0 @@ -/* $OpenBSD: ip_ahmd5.c,v 1.10 1997/07/01 22:12:44 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Authentication Header Processing - * Per RFC1828 (Metzger & Simpson, 1995) - */ - -#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 <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#include <netinet/ip_icmp.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> -#include <net/encap.h> - -#include <netinet/ip_ipsp.h> -#include <netinet/ip_ah.h> - -/* - * ahmd5_attach() is called from the transformation initialization code. - * It just returns. - */ - -int -ahmd5_attach() -{ - return 0; -} - -/* - * ahmd5_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data. - */ - -int -ahmd5_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct ahmd5_xdata *xd; - struct encap_msghdr *em; - - tdbp->tdb_xform = xsp; - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct ahmd5_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct ahmd5_xdata)); - xd = (struct ahmd5_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahmd5_xdata)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, - (caddr_t)xd); - - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - return 0; -} - -/* - * Free memory - */ - -int -ahmd5_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - -/* - * ahmd5_input() gets called to verify that an input packet - * passes authentication. - */ - -extern struct ifnet loif; - -struct mbuf * -ahmd5_input(struct mbuf *m, struct tdb *tdb) -{ - struct ahmd5_xdata *xd; - struct ip *ip, ipo; - struct ah *ah; - struct ahmd5 aho; - struct ifnet *rcvif; - int ohlen, len, count, off; - struct mbuf *m0; - MD5_CTX ctx; - u_int8_t optval; - - xd = (struct ahmd5_xdata *)tdb->tdb_xdata; - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahmd5_input: receive interface is NULL!!!\n"); -#endif - rcvif = &loif; - } - - if (m->m_len < ohlen) - { - if ((m = m_pullup(m, ohlen)) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - } - - ip = mtod(m, struct ip *); - - if ((ip->ip_hl << 2) > sizeof(struct ip)) - { - if ((m = m_pullup(m, ohlen - sizeof (struct ip) + - (ip->ip_hl << 2))) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - - ip = mtod(m, struct ip *); - ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); - } - else - ah = (struct ah *)(ip + 1); - - ipo = *ip; - ipo.ip_tos = 0; - ipo.ip_len += sizeof (struct ip); /* adjusted in ip_intr() */ - HTONS(ipo.ip_len); - HTONS(ipo.ip_id); - ipo.ip_off = htons(ipo.ip_off & IP_DF); /* XXX -- and the C bit? */ - ipo.ip_ttl = 0; - ipo.ip_sum = 0; - - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - MD5Final(NULL, &ctx); /* non-std usage of MD5Final! */ - MD5Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); - - /* Options */ - if ((ip->ip_hl << 2 > sizeof(struct ip))) - for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) - { - optval = ((u_int8_t *)ip)[off]; - switch (optval) - { - case IPOPT_EOL: - MD5Update(&ctx, ipseczeroes, 1); - off = ip->ip_hl << 2; - break; - - case IPOPT_NOP: - MD5Update(&ctx, ipseczeroes, 1); - off++; - break; - - case IPOPT_SECURITY: - case 133: - case 134: - optval = ((u_int8_t *)ip)[off + 1]; - MD5Update(&ctx, (u_int8_t *)ip + off, optval); - off += optval; - break; - - default: - optval = ((u_int8_t *)ip)[off + 1]; - MD5Update(&ctx, ipseczeroes, optval); - off += optval; - break; - } - } - - - MD5Update(&ctx, (unsigned char *)ah, AH_FLENGTH); - MD5Update(&ctx, ipseczeroes, xd->amx_alen); - - /* - * Code shamelessly stolen from m_copydata - */ - off = ohlen; - len = m->m_pkthdr.len - off; - m0 = m; - - while (off > 0) - { - if (m0 == 0) - panic("ahmd5_input: m_copydata (off)"); - if (off < m0->m_len) - break; - off -= m0->m_len; - m0 = m0->m_next; - } - - while (len > 0) - { - if (m0 == 0) - panic("ahmd5_input: m_copydata (copy)"); - count = min(m0->m_len - off, len); - MD5Update(&ctx, mtod(m0, unsigned char *) + off, count); - len -= count; - off = 0; - m0 = m0->m_next; - } - - - MD5Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - MD5Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - - if (bcmp(aho.ah_data, ah->ah_data, xd->amx_alen)) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahmd5_input: bad auth\n"); /* XXX */ -#endif - ahstat.ahs_badauth++; - m_freem(m); - return NULL; - } - - ipo = *ip; - ipo.ip_p = ah->ah_nh; - - m->m_len -= (ohlen - sizeof(struct ip)); - m->m_data += (ohlen - sizeof(struct ip)); - m->m_pkthdr.len -= (ohlen - sizeof(struct ip)); - m->m_pkthdr.rcvif = rcvif; /* this should not be necessary */ - - ip = mtod(m, struct ip *); - *ip = ipo; - ip->ip_len = htons(ip->ip_len - ohlen + 2 * sizeof (struct ip)); - HTONS(ip->ip_id); - HTONS(ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2); - - return m; -} - - -#define AHXPORT - -int -ahmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct ahmd5_xdata *xd; - struct ip *ip, ipo; - struct ah *ah, aho; - register int len, off, count; - register struct mbuf *m0; - - MD5_CTX ctx; - - int ilen, ohlen; - - ahstat.ahs_output++; - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - xd = (struct ahmd5_xdata *)tdb->tdb_xdata; - - ilen = ntohs(ip->ip_len); - -#ifdef AHXPORT - ohlen = AH_FLENGTH + xd->amx_alen; -#else - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; -#endif - - ipo.ip_v = IPVERSION; - ipo.ip_hl = 5; - ipo.ip_tos = 0; - ipo.ip_len = htons(ohlen + ilen); - ipo.ip_id = ip->ip_id; - ipo.ip_off = htons(ntohs(ip->ip_off) & IP_DF); - ipo.ip_ttl = 0; - ipo.ip_p = IPPROTO_AH; - ipo.ip_sum = 0; -#ifdef AHXPORT - ipo.ip_src = ip->ip_src; - ipo.ip_dst = ip->ip_dst; - aho.ah_nh = ip->ip_p; -#else - ipo.ip_src = gw->sen_ipsp_src; - ipo.ip_dst = gw->sen_ipsp_dst; - aho.ah_nh = IPPROTO_IP4; -#endif - aho.ah_hl = xd->amx_alen >> 2; - aho.ah_rv = 0; - aho.ah_spi = tdb->tdb_spi; - - MD5Init(&ctx); - - MD5Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - MD5Final(NULL, &ctx); - MD5Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); - MD5Update(&ctx, (unsigned char *)&aho, AH_FLENGTH); - MD5Update(&ctx, ipseczeroes, xd->amx_alen); - -#ifdef AHXPORT - off = sizeof (struct ip); -#else - off = 0; -#endif - - /* - * Code shamelessly stolen from m_copydata - */ - len = m->m_pkthdr.len - off; - - m0 = m; - - while (len > 0) - { - if (m0 == 0) - panic("ahmd5_output: m_copydata"); - count = min(m0->m_len - off, len); - MD5Update(&ctx, mtod(m0, unsigned char *) + off, count); - len -= count; - off = 0; - m0 = m0->m_next; - } - - MD5Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - - ipo.ip_tos = ip->ip_tos; - ipo.ip_id = ip->ip_id; - ipo.ip_off = ip->ip_off; - ipo.ip_ttl = ip->ip_ttl; -/* ipo.ip_len = ntohs(ipo.ip_len); */ - - M_PREPEND(m, ohlen, M_DONTWAIT); - if (m == NULL) - return ENOBUFS; - - m = m_pullup(m, ohlen + sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); - *ip = ipo; - ah->ah_nh = aho.ah_nh; - ah->ah_hl = aho.ah_hl; - ah->ah_rv = aho.ah_rv; - ah->ah_spi = aho.ah_spi; - - - MD5Final(&(ah->ah_data[0]), &ctx); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - - xd->amx_alen; - - return 0; -} diff --git a/sys/netinet/ip_ahsha1.c b/sys/netinet/ip_ahsha1.c deleted file mode 100644 index 6aa40c07612..00000000000 --- a/sys/netinet/ip_ahsha1.c +++ /dev/null @@ -1,415 +0,0 @@ -/* $OpenBSD: ip_ahsha1.c,v 1.6 1997/07/01 22:12:45 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Authentication Header Processing - * Per RFC1852 (Metzger & Simpson, 1995) - */ - -#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 <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> -#include <netinet/ip_icmp.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> -#include <net/encap.h> - -#include <netinet/ip_ipsp.h> -#include <netinet/ip_ah.h> - -/* - * ahsha1_attach() is called from the transformation initialization code. - * It just returns. - */ - -int -ahsha1_attach() -{ - return 0; -} - -/* - * ahsha1_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data. - */ - -int -ahsha1_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct ahsha1_xdata *xd; - struct encap_msghdr *em; - - tdbp->tdb_xform = xsp; - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct ahsha1_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct ahsha1_xdata)); - xd = (struct ahsha1_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN > sizeof (struct ahsha1_xdata)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, - (caddr_t)xd); - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - return 0; -} - -/* - * Free memory - */ - -int -ahsha1_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - -/* - * ahsha1_input() gets called to verify that an input packet - * passes authentication. - */ - -extern struct ifnet loif; - -struct mbuf * -ahsha1_input(struct mbuf *m, struct tdb *tdb) -{ - struct ahsha1_xdata *xd; - struct ip *ip, ipo; - struct ah *ah; - struct ahsha1 aho; - struct ifnet *rcvif; - int ohlen, len, count, off; - struct mbuf *m0; - SHA1_CTX ctx; - u_int8_t optval; - - xd = (struct ahsha1_xdata *)tdb->tdb_xdata; - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahsha1_input: receive interface is NULL!!!\n"); -#endif - rcvif = &loif; - } - - if (m->m_len < ohlen) - { - if ((m = m_pullup(m, ohlen)) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - } - - ip = mtod(m, struct ip *); - - if ((ip->ip_hl << 2) > sizeof(struct ip)) - { - if ((m = m_pullup(m, ohlen - sizeof (struct ip) + - (ip->ip_hl << 2))) == NULL) - { - ahstat.ahs_hdrops++; - return NULL; - } - - ip = mtod(m, struct ip *); - ah = (struct ah *)((u_int8_t *)ip + (ip->ip_hl << 2)); - } - else - ah = (struct ah *)(ip + 1); - - ipo = *ip; - ipo.ip_tos = 0; - ipo.ip_len += sizeof (struct ip); /* adjusted in ip_intr() */ - HTONS(ipo.ip_len); - HTONS(ipo.ip_id); - ipo.ip_off = htons(ipo.ip_off & IP_DF); /* XXX -- and the C bit? */ - ipo.ip_ttl = 0; - ipo.ip_sum = 0; - - SHA1Init(&ctx); - SHA1Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - SHA1Final(NULL, &ctx); /* non-std usage of SHA1Final! */ - - /* Options */ - if ((ip->ip_hl << 2 > sizeof(struct ip))) - for (off = sizeof(struct ip); off < (ip->ip_hl << 2);) - { - optval = ((u_int8_t *)ip)[off]; - switch (IPOPT_NUMBER(optval)) - { - case IPOPT_EOL: - SHA1Update(&ctx, ipseczeroes, 1); - off = ip->ip_hl << 2; - break; - - case IPOPT_NOP: - SHA1Update(&ctx, ipseczeroes, 1); - off++; - break; - - case IPOPT_SECURITY: - case 133: - case 134: - optval = ((u_int8_t *)ip)[off + 1]; - SHA1Update(&ctx, (u_int8_t *)ip + off, optval); - off += optval; - break; - - default: - optval = ((u_int8_t *)ip)[off + 1]; - SHA1Update(&ctx, ipseczeroes, optval); - off += optval; - break; - } - } - - SHA1Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); - SHA1Update(&ctx, (unsigned char *)ah, AH_FLENGTH); - SHA1Update(&ctx, ipseczeroes, xd->amx_alen); - - /* - * Code shamelessly stolen from m_copydata - */ - off = ohlen; - len = m->m_pkthdr.len - off; - m0 = m; - - while (off > 0) - { - if (m0 == 0) - panic("ahsha1_input: m_copydata (off)"); - if (off < m0->m_len) - break; - off -= m0->m_len; - m0 = m0->m_next; - } - - while (len > 0) - { - if (m0 == 0) - panic("ahsha1_input: m_copydata (copy)"); - count = min(m0->m_len - off, len); - SHA1Update(&ctx, mtod(m0, unsigned char *) + off, count); - len -= count; - off = 0; - m0 = m0->m_next; - } - - - SHA1Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - SHA1Final((unsigned char *)(&(aho.ah_data[0])), &ctx); - - if (bcmp(aho.ah_data, ah->ah_data, xd->amx_alen)) - { -#ifdef ENCDEBUG - if (encdebug) - printf("ahsha1_input: bad auth\n"); /* XXX */ -#endif - ahstat.ahs_badauth++; - m_freem(m); - return NULL; - } - - ipo = *ip; - ipo.ip_p = ah->ah_nh; - - m->m_len -= (ohlen - sizeof(struct ip)); - m->m_data += (ohlen - sizeof(struct ip)); - m->m_pkthdr.len -= (ohlen - sizeof(struct ip)); - m->m_pkthdr.rcvif = rcvif; /* this should not be necessary */ - - ip = mtod(m, struct ip *); - *ip = ipo; - ip->ip_len = htons(ip->ip_len - ohlen + 2 * sizeof (struct ip)); - HTONS(ip->ip_id); - HTONS(ip->ip_off); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2); - - return m; -} - - -#define AHXPORT - -int -ahsha1_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct ahsha1_xdata *xd; - struct ip *ip, ipo; - struct ah *ah, aho; - register int len, off, count; - register struct mbuf *m0; - - SHA1_CTX ctx; - - int ilen, ohlen; - - ahstat.ahs_output++; - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - xd = (struct ahsha1_xdata *)tdb->tdb_xdata; - - ilen = ntohs(ip->ip_len); - -#ifdef AHXPORT - ohlen = AH_FLENGTH + xd->amx_alen; -#else - ohlen = sizeof (struct ip) + AH_FLENGTH + xd->amx_alen; -#endif - - ipo.ip_v = IPVERSION; - ipo.ip_hl = 5; - ipo.ip_tos = 0; - ipo.ip_len = htons(ohlen + ilen); - ipo.ip_id = ip->ip_id; - ipo.ip_off = htons(ntohs(ip->ip_off) & IP_DF); - ipo.ip_ttl = 0; - ipo.ip_p = IPPROTO_AH; - ipo.ip_sum = 0; -#ifdef AHXPORT - ipo.ip_src = ip->ip_src; - ipo.ip_dst = ip->ip_dst; - aho.ah_nh = ip->ip_p; -#else - ipo.ip_src = gw->sen_ipsp_src; - ipo.ip_dst = gw->sen_ipsp_dst; - aho.ah_nh = IPPROTO_IP4; -#endif - aho.ah_hl = xd->amx_alen >> 2; - aho.ah_rv = 0; - aho.ah_spi = tdb->tdb_spi; - - SHA1Init(&ctx); - - SHA1Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - SHA1Final(NULL, &ctx); - SHA1Update(&ctx, (unsigned char *)&ipo, sizeof (struct ip)); - SHA1Update(&ctx, (unsigned char *)&aho, AH_FLENGTH); - SHA1Update(&ctx, ipseczeroes, xd->amx_alen); - -#ifdef AHXPORT - off = sizeof (struct ip); -#else - off = 0; -#endif - - /* - * Code shamelessly stolen from m_copydata - */ - len = m->m_pkthdr.len - off; - - m0 = m; - - while (len > 0) - { - if (m0 == 0) - panic("ahsha1_output: m_copydata"); - count = min(m0->m_len - off, len); - SHA1Update(&ctx, mtod(m0, unsigned char *) + off, count); - len -= count; - off = 0; - m0 = m0->m_next; - } - - SHA1Update(&ctx, (unsigned char *)xd->amx_key, xd->amx_klen); - - ipo.ip_tos = ip->ip_tos; - ipo.ip_id = ip->ip_id; - ipo.ip_off = ip->ip_off; - ipo.ip_ttl = ip->ip_ttl; -/* ipo.ip_len = ntohs(ipo.ip_len); */ - - M_PREPEND(m, ohlen, M_DONTWAIT); - if (m == NULL) - return ENOBUFS; - - m = m_pullup(m, ohlen + sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - ah = (struct ah *)(ip + 1); - *ip = ipo; - ah->ah_nh = aho.ah_nh; - ah->ah_hl = aho.ah_hl; - ah->ah_rv = aho.ah_rv; - ah->ah_spi = aho.ah_spi; - - - SHA1Final(&(ah->ah_data[0]), &ctx); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ip->ip_len - (ip->ip_hl << 2) - AH_FLENGTH - - xd->amx_alen; - - return 0; -} diff --git a/sys/netinet/ip_esp3des.c b/sys/netinet/ip_esp3des.c deleted file mode 100644 index 9489f6c9f51..00000000000 --- a/sys/netinet/ip_esp3des.c +++ /dev/null @@ -1,484 +0,0 @@ -/* $OpenBSD: ip_esp3des.c,v 1.7 1997/07/01 22:12:46 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * 3DES-CBC - * Per RFC1851 (Metzger & Simpson, 1995) - */ - -#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 <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> -#include <net/encap.h> - -#include <netinet/ip_icmp.h> -#include <netinet/ip_ipsp.h> -#include <netinet/ip_esp.h> -#include <dev/rndvar.h> - -extern struct ifnet loif; - -extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int); -extern void des_set_key(caddr_t, caddr_t); - - -int -esp3des_attach() -{ - return 0; -} - -/* - * esp3des_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data, in - * this case, the encryption and decryption key schedules - */ - -int -esp3des_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct esp3des_xdata *xd; - struct encap_msghdr *em; - u_int32_t rk[2]; - - tdbp->tdb_xform = xsp; - - m = m_pullup(m, ESP_ULENGTH); - if (m == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3des_init: can't pull up %d bytes\n", - ESP_ULENGTH); -#endif ENCDEBUG - return ENOBUFS; - } - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct esp3des_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct esp3des_xdata)); - xd = (struct esp3des_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN != ESP_ULENGTH) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - m_copydata(m, EMT_SETSPI_FLEN, ESP_ULENGTH, (caddr_t)xd); - - rk[0] = xd->edx_eks[0][0][0]; /* some overloading doesn't hurt */ - rk[1] = xd->edx_eks[0][0][1]; /* XXX -- raw-major order */ - des_set_key((caddr_t)rk, (caddr_t)(xd->edx_eks[0])); - - rk[0] = xd->edx_eks[1][0][0]; - rk[1] = xd->edx_eks[1][0][1]; - des_set_key((caddr_t)rk, (caddr_t)(xd->edx_eks[1])); - - rk[0] = xd->edx_eks[2][0][0]; - rk[1] = xd->edx_eks[2][0][1]; - des_set_key((caddr_t)rk, (caddr_t)(xd->edx_eks[2])); - - rk[0] = rk[1] = 0; /* zeroize! */ - - return 0; -} - -int -esp3des_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - - -struct mbuf * -esp3des_input(struct mbuf *m, struct tdb *tdb) -{ - struct esp3des_xdata *xd; - struct ip *ip, ipo; - u_char iv[8], niv[8], blk[8]; - u_char *idat, *odat; - struct esp *esp; - struct ifnet *rcvif; - int ohlen, plen, ilen, olen, i; - struct mbuf *mi, *mo; - - xd = (struct esp3des_xdata *)tdb->tdb_xdata; - ohlen = sizeof (struct ip) + ESP_FLENGTH; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3des_input: receive interface is NULL!!!\n"); -#endif ENCDEBUG - rcvif = &loif; - } - - ip = mtod(m, struct ip *); - ipo = *ip; - esp = (struct esp *)(ip + 1); - - plen = m->m_pkthdr.len - sizeof (struct ip) - sizeof (u_int32_t) - - xd->edx_ivlen; - if (plen & 07) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3des_input: payload not a multiple of 8 octets\n"); -#endif ENCDEBUG - espstat.esps_badilen++; - m_freem(m); - return NULL; - } - - ilen = m->m_len - sizeof (struct ip) - 8; - idat = mtod(m, unsigned char *) + sizeof (struct ip) + 8; - - iv[0] = esp->esp_iv[0]; - iv[1] = esp->esp_iv[1]; - iv[2] = esp->esp_iv[2]; - iv[3] = esp->esp_iv[3]; - if (xd->edx_ivlen == 4) - { - iv[4] = ~esp->esp_iv[0]; - iv[5] = ~esp->esp_iv[1]; - iv[6] = ~esp->esp_iv[2]; - iv[7] = ~esp->esp_iv[3]; - } - else - { - iv[4] = esp->esp_iv[4]; - iv[5] = esp->esp_iv[5]; - iv[6] = esp->esp_iv[6]; - iv[7] = esp->esp_iv[7]; - - ilen -= 4; - idat += 4; - } - - olen = ilen; - odat = idat; - mi = mo = m; - i = 0; - - /* - * At this point: - * plen is # of encapsulated payload octets - * ilen is # of octets left in this mbuf - * idat is first encapsulated payload octed in this mbuf - * same for olen and odat - * iv contains the IV. - * mi and mo point to the first mbuf - * - * From now on until the end of the mbuf chain: - * . move the next eight octets of the chain into blk[] - * (ilen, idat, and mi are adjusted accordingly) - * and save it back into iv[] - * . decrypt blk[], xor with iv[], put back into chain - * (olen, odat, amd mo are adjusted accordingly) - * . repeat - */ - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("esp3des_input: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = niv[i] = *idat++; - i++; - ilen--; - - if (i == 8) - { - des_ecb3_encrypt(blk, blk, (caddr_t)(xd->edx_eks[2]), - (caddr_t)(xd->edx_eks[1]), - (caddr_t)(xd->edx_eks[0]), 0); - for (i=0; i<8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("esp3des_input: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat = blk[i] ^ iv[i]; - iv[i] = niv[i]; - blk[i] = *odat++; /* needed elsewhere */ - olen--; - } - i = 0; - } - - plen--; - } - - /* - * Now, the entire chain has been decrypted. As a side effect, - * blk[7] contains the next protocol, and blk[6] contains the - * amount of padding the original chain had. Chop off the - * appropriate parts of the chain, and return. - */ - - m_adj(m, -blk[6] - 2); - m_adj(m, 4 + xd->edx_ivlen); - if (m->m_len < sizeof (struct ip)) - { - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - { - return NULL; - } - } - - ip = mtod(m, struct ip *); - ipo.ip_p = blk[7]; - ipo.ip_id = htons(ipo.ip_id); - ipo.ip_off = 0; - ipo.ip_len += sizeof (struct ip) - 4 - xd->edx_ivlen - blk[6] - 2; - ipo.ip_len = htons(ipo.ip_len); - ipo.ip_sum = 0; - *ip = ipo; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) + blk[6] + 2; - - return m; -} - -int -esp3des_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct esp3des_xdata *xd; - struct ip *ip, ipo; - int i, ilen, olen, ohlen, nh, rlen, plen, padding; - u_int32_t spi; - struct mbuf *mi, *mo; - u_char *pad, *idat, *odat; - u_char iv[8], blk[8], opts[40]; - int iphlen; - - espstat.esps_output++; - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - spi = tdb->tdb_spi; - iphlen = ip->ip_hl << 2; - - /* - * If options are present, pullup the IP header, the options - * and one DES block (8 bytes) of data. - */ - if (iphlen != sizeof(struct ip)) - { - m = m_pullup(m, iphlen + 8); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - /* Keep the options */ - bcopy(mtod(m, u_char *) + sizeof(struct ip), opts, - iphlen - sizeof(struct ip)); - } - - xd = (struct esp3des_xdata *)tdb->tdb_xdata; - ilen = ntohs(ip->ip_len); - ohlen = sizeof (u_int32_t) + xd->edx_ivlen; - - ipo = *ip; - nh = ipo.ip_p; - - rlen = ilen - iphlen; /* raw payload length */ - padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; - - pad = (u_char *)m_pad(m, padding); - if (pad == NULL) - return ENOBUFS; - - pad[padding-2] = padding - 2; - pad[padding-1] = nh; - - plen = rlen + padding; - mi = mo = m; - ilen = olen = m->m_len - iphlen; - idat = odat = mtod(m, u_char *) + iphlen; - i = 0; - - /* - * We are now ready to encrypt the payload. - */ - - xd->edx_ivl++; - - iv[0] = xd->edx_iv[0]; - iv[1] = xd->edx_iv[1]; - iv[2] = xd->edx_iv[2]; - iv[3] = xd->edx_iv[3]; - if (xd->edx_ivlen == 4) - { - iv[4] = ~xd->edx_iv[0]; - iv[5] = ~xd->edx_iv[1]; - iv[6] = ~xd->edx_iv[2]; - iv[7] = ~xd->edx_iv[3]; - } - else - { - iv[4] = xd->edx_iv[4]; - iv[5] = xd->edx_iv[5]; - iv[6] = xd->edx_iv[6]; - iv[7] = xd->edx_iv[7]; - } - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("esp3des_output: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = *idat++ ^ iv[i]; - - i++; - ilen--; - - if (i == 8) - { - des_ecb3_encrypt(blk, blk, (caddr_t)(xd->edx_eks[0]), - (caddr_t)(xd->edx_eks[1]), - (caddr_t)(xd->edx_eks[2]), 1); - for (i = 0; i < 8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("esp3des_output: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat++ = blk[i]; - iv[i] = blk[i]; - olen--; - } - i = 0; - } - - plen--; - } - - /* - * Done with encryption. Let's wedge in the ESP header - * and send it out. - */ - - M_PREPEND(m, ohlen, M_DONTWAIT); - if (m == NULL) - return ENOBUFS; - - m = m_pullup(m, iphlen + ohlen); - if (m == NULL) - return ENOBUFS; - - ipo.ip_len = htons(iphlen + ohlen + rlen + padding); - ipo.ip_p = IPPROTO_ESP; - - iv[0] = xd->edx_iv[0]; - iv[1] = xd->edx_iv[1]; - iv[2] = xd->edx_iv[2]; - iv[3] = xd->edx_iv[3]; - if (xd->edx_ivlen == 8) - { - iv[4] = xd->edx_iv[4]; - iv[5] = xd->edx_iv[5]; - iv[6] = xd->edx_iv[6]; - iv[7] = xd->edx_iv[7]; - } - - bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof (struct ip)); - - /* Copy options, if existing */ - if (iphlen != sizeof(struct ip)) - bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip), - iphlen - sizeof(struct ip)); - - bcopy((caddr_t)&spi, mtod(m, caddr_t) + sizeof(struct ip), - sizeof (u_int32_t)); - bcopy((caddr_t)iv, mtod(m, caddr_t) + sizeof(struct ip) + - sizeof (u_int32_t), xd->edx_ivlen); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += rlen + padding; - - return 0; -} diff --git a/sys/netinet/ip_esp3desmd5.c b/sys/netinet/ip_esp3desmd5.c deleted file mode 100644 index 3bfe161f2f2..00000000000 --- a/sys/netinet/ip_esp3desmd5.c +++ /dev/null @@ -1,780 +0,0 @@ -/* $OpenBSD: ip_esp3desmd5.c,v 1.11 1997/07/01 22:12:47 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Based on draft-ietf-ipsec-esp-3des-md5-00.txt. - */ - -#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 <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> -#include <net/encap.h> - -#include <netinet/ip_icmp.h> -#include <netinet/ip_ipsp.h> -#include <netinet/ip_esp.h> - -extern struct ifnet loif; - -extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int); -extern void des_set_key(caddr_t, caddr_t); - -int -esp3desmd5_attach() -{ - return 0; -} - -/* - * esp3desmd5_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data, in - * this case, the encryption and decryption key schedules - */ - -int -esp3desmd5_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct esp3desmd5_xdata *xd; - struct encap_msghdr *em; - struct esp3desmd5_xencap txd; - u_char buf[ESP3DESMD5_KEYSZ]; - int len; - MD5_CTX ctx; - - tdbp->tdb_xform = xsp; - - m = m_pullup(m, ESP3DESMD5_ULENGTH); - if (m == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_init: can't pull up %d bytes\n", ESP_ULENGTH); -#endif ENCDEBUG - return ENOBUFS; - } - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct esp3desmd5_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct esp3desmd5_xdata)); - xd = (struct esp3desmd5_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN != ESP3DESMD5_ULENGTH) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, (caddr_t)&txd); - - if ((txd.edx_ivlen != 0) && (txd.edx_ivlen != 8)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - - xd->edx_ivlen = txd.edx_ivlen; - xd->edx_bitmap = 0; - xd->edx_wnd = txd.edx_wnd; - - /* Fix the IV */ - -#ifdef ENCDEBUG - if (encdebug) - { - if (txd.edx_initiator) - printf("INITIATOR\n"); - printf("IV length: %d\n", txd.edx_ivlen); - } -#endif - if (txd.edx_ivlen) - bcopy(txd.edx_ivv, xd->edx_iv, ESP3DESMD5_IVS); - else - { - for (len = 0; len < ESP3DESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESP3DESMD5_IPADI : - ESP3DESMD5_IPADR; - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - bcopy(buf, xd->edx_iv, ESP3DESMD5_IVS); -#ifdef ENCDEBUG - printf("IV "); - if (encdebug) - for (len = 0; len < ESP3DESMD5_IVS; len++) - printf(" %02x", xd->edx_iv[len]); - printf("\n"); -#endif - } - - /* DES key */ - - for (len = 1; len < ESP3DESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESP3DESMD5_DPADI : ESP3DESMD5_DPADR; - - buf[0] = 0; - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - des_set_key((caddr_t)buf, (caddr_t)(xd->edx_eks[0])); - - buf[0] = 1; - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - des_set_key((caddr_t)buf, (caddr_t)(xd->edx_eks[1])); - - buf[0] = 2; - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - des_set_key((caddr_t)buf, (caddr_t)(xd->edx_eks[2])); - - /* HMAC contexts */ - - MD5Init(&ctx); - for (len = 0; len < ESP3DESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESP3DESMD5_HPADI : ESP3DESMD5_HPADR; - - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - - bzero(buf + ESP3DESMD5_ALEN, ESP3DESMD5_KEYSZ - ESP3DESMD5_ALEN); - - for (len = 0; len < ESP3DESMD5_KEYSZ; len++) - buf[len] ^= ESP3DESMD5_IPAD_VAL; - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - xd->edx_ictx = ctx; - - for (len = 0; len < ESP3DESMD5_KEYSZ; len++) - buf[len] ^= (ESP3DESMD5_IPAD_VAL ^ ESP3DESMD5_OPAD_VAL); - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - xd->edx_octx = ctx; - - /* Replay counter */ - - for (len = 0; len < ESP3DESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESP3DESMD5_RPADI : - ESP3DESMD5_RPADR; - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESP3DESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - bcopy(buf, (unsigned char *)&(xd->edx_rpl), ESP3DESMD5_RPLENGTH); - xd->edx_initial = xd->edx_rpl - 1; - -#ifdef ENCDEBUG - if (encdebug) - printf("Initial replay counter: %x (%x)\n", xd->edx_rpl, - xd->edx_initial); -#endif - - bzero(&txd, sizeof(struct esp3desmd5_xencap)); - bzero(buf, ESP3DESMD5_KEYSZ); - bzero(&ctx, sizeof(MD5_CTX)); - - return 0; -} - -int -esp3desmd5_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - - -struct mbuf * -esp3desmd5_input(struct mbuf *m, struct tdb *tdb) -{ - struct esp3desmd5_xdata *xd; - struct ip *ip, ipo; - u_char iv[8], niv[8], blk[8], auth[ESP3DESMD5_ALEN]; - u_char iauth[ESP3DESMD5_ALEN]; - u_char *idat, *odat; - struct esp *esp; - struct ifnet *rcvif; - int plen, ilen, olen, i, authp, oplen, errc; - u_int32_t rplc, tbitmap, trpl; - u_char padsize, nextproto; - struct mbuf *mi, *mo; - MD5_CTX ctx; - - xd = (struct esp3desmd5_xdata *)tdb->tdb_xdata; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_input: receive interface is NULL!!!\n"); -#endif ENCDEBUG - rcvif = &loif; - } - - ip = mtod(m, struct ip *); - ipo = *ip; - esp = (struct esp *)(ip + 1); - - plen = m->m_pkthdr.len - sizeof (struct ip) - sizeof (u_int32_t) - - xd->edx_ivlen; - if (plen & 07) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_input: payload not a multiple of 8 octets\n"); -#endif ENCDEBUG - espstat.esps_badilen++; - m_freem(m); - return NULL; - } - - oplen = plen; - ilen = m->m_len - sizeof (struct ip) - ESP3DESMD5_IVS - sizeof(u_int32_t); - idat = mtod(m, unsigned char *) + sizeof (struct ip) + sizeof(u_int32_t) + - ESP3DESMD5_IVS; - - if (xd->edx_ivlen == 0) /* KeyIV in use */ - { - bcopy(xd->edx_iv, iv, ESP3DESMD5_IVS); - ilen += ESP3DESMD5_IVS; - idat -= ESP3DESMD5_IVS; - } - else - bcopy(idat - ESP3DESMD5_IVS, iv, ESP3DESMD5_IVS); - - olen = ilen; - odat = idat; - mi = mo = m; - i = 0; - authp = 0; - - ctx = xd->edx_ictx; - - MD5Update(&ctx, (unsigned char *)&(tdb->tdb_spi), sizeof(u_int32_t)); - MD5Update(&ctx, iv, ESP3DESMD5_IVS); - -#ifdef ENCDEBUG - printf("IV "); - for (i = 0; i < ESP3DESMD5_IVS; i++) - printf(" %02x", iv[i]); - printf("\n"); - i = 0; -#endif - - /* - * At this point: - * plen is # of encapsulated payload octets - * ilen is # of octets left in this mbuf - * idat is first encapsulated payload octed in this mbuf - * same for olen and odat - * iv contains the IV. - * mi and mo point to the first mbuf - * - * From now on until the end of the mbuf chain: - * . move the next eight octets of the chain into blk[] - * (ilen, idat, and mi are adjusted accordingly) - * and save it back into iv[] - * . decrypt blk[], xor with iv[], put back into chain - * (olen, odat, amd mo are adjusted accordingly) - * . repeat - */ - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("esp3desmd5_input: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = niv[i] = *idat++; - i++; - ilen--; - - if (i == 8) - { - des_ecb3_encrypt(blk, blk, (caddr_t)(xd->edx_eks[2]), - (caddr_t)(xd->edx_eks[1]), - (caddr_t)(xd->edx_eks[0]), 0); - for (i=0; i<8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("esp3desmd5_input: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat = blk[i] ^ iv[i]; - iv[i] = niv[i]; - blk[i] = *odat++; /* needed elsewhere */ - olen--; - } - i = 0; - - if (plen < ESP3DESMD5_ALEN) - { - bcopy(blk, auth + authp, ESP3DESMD5_DESBLK); - authp += ESP3DESMD5_DESBLK; -#ifdef ENCDEBUG - if (encdebug) - printf("Copying authenticator from %d\n", - plen); -#endif - } - else - { - if (plen == ESP3DESMD5_ALEN + 1) - { - nextproto = blk[7]; - padsize = blk[6]; -#ifdef ENCDEBUG - if (encdebug) - printf("Next protocol: %d\nPadsize: %d\n", nextproto, - padsize); -#endif - } - else - if (plen + 7 == oplen) - { -#ifdef ENCDEBUG - if (encdebug) - printf("SEQ %02x %02x %02x %02x\n", - blk[0], blk[1], blk[2], - blk[3]); -#endif - tbitmap = xd->edx_bitmap; /* Save it */ - trpl = xd->edx_rpl; - rplc = ntohl(*((u_int32_t *)blk)); - if ((errc = checkreplaywindow32(rplc, xd->edx_initial, &(xd->edx_rpl), xd->edx_wnd, &(xd->edx_bitmap))) != 0) - { - switch (errc) - { - case 1: -#ifdef ENCDEBUG - printf("esp3desmd5_input: replay counter wrapped\n"); -#endif - espstat.esps_wrap++; - break; - case 2: -#ifdef ENCDEBUG - printf("esp3desmd5_input: received old packet, seq = %08x\n", rplc); -#endif - espstat.esps_replay++; - break; - case 3: -#ifdef ENCDEBUG - printf("esp3desmd5_input: packet already received\n"); -#endif - espstat.esps_replay++; - break; - } - m_freem(m); - return NULL; - } - } - - MD5Update(&ctx, blk, ESP3DESMD5_DESBLK); - } - } - - plen--; - } - - /* - * Now, the entire chain has been decrypted. - */ - - MD5Final(iauth, &ctx); - ctx = xd->edx_octx; - MD5Update(&ctx, iauth, ESP3DESMD5_ALEN); - MD5Final(iauth, &ctx); - -#ifdef ENCDEBUG - printf("RECEIVED "); - for (rplc = 0; rplc < ESP3DESMD5_ALEN; rplc++) - printf(" %02x", auth[rplc]); - printf("\nSHOULD HAVE "); - for (rplc = 0; rplc < ESP3DESMD5_ALEN; rplc++) - printf(" %02x", iauth[rplc]); - printf("\n"); -#endif - - if (bcmp(auth, iauth, ESP3DESMD5_ALEN)) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_input: bad auth\n"); -#endif - xd->edx_rpl = trpl; - xd->edx_bitmap = tbitmap; /* Restore */ - espstat.esps_badauth++; - m_freem(m); - return NULL; - } - - m_adj(m, - padsize - 2 - ESP3DESMD5_ALEN); - m_adj(m, 4 + xd->edx_ivlen + ESP3DESMD5_RPLENGTH); - - if (m->m_len < sizeof (struct ip)) - { - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - { - xd->edx_rpl = trpl; - xd->edx_bitmap = tbitmap; - return NULL; - } - } - - ip = mtod(m, struct ip *); - ipo.ip_p = nextproto; - ipo.ip_id = htons(ipo.ip_id); - ipo.ip_off = 0; - ipo.ip_len += sizeof (struct ip) - ESP3DESMD5_RPLENGTH - 4 - - xd->edx_ivlen - padsize - 2 - ESP3DESMD5_ALEN; -#ifdef ENCDEBUG - if (encdebug) - printf("IP packet size %d\n", ipo.ip_len); -#endif - ipo.ip_len = htons(ipo.ip_len); - ipo.ip_sum = 0; - *ip = ipo; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) + padsize + - 2 + ESP3DESMD5_ALEN; - - return m; -} - -int -esp3desmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct esp3desmd5_xdata *xd; - struct ip *ip, ipo; - int i, ilen, olen, ohlen, nh, rlen, plen, padding; - u_int32_t rplc; - u_int32_t spi; - struct mbuf *mi, *mo, *ms; - u_char *pad, *idat, *odat; - u_char iv[ESP3DESMD5_IVS], blk[8], auth[ESP3DESMD5_ALEN], opts[40]; - MD5_CTX ctx; - int iphlen; - - espstat.esps_output++; - m = m_pullup(m, sizeof (struct ip)); /* Get IP header in one mbuf */ - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - spi = tdb->tdb_spi; - iphlen = ip->ip_hl << 2; - - /* - * If options are present, pullup the IP header, the options - * and one DES block (8 bytes) of data. - */ - if (iphlen != sizeof(struct ip)) - { - m = m_pullup(m, iphlen + 8); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - /* Keep the options */ - bcopy(mtod(m, u_char *) + sizeof(struct ip), opts, - iphlen - sizeof(struct ip)); - } - - xd = (struct esp3desmd5_xdata *)tdb->tdb_xdata; - ilen = ntohs(ip->ip_len); /* Size of the packet */ - ohlen = sizeof (u_int32_t) + xd->edx_ivlen; /* size of plaintext ESP */ - - if (xd->edx_rpl == xd->edx_initial) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: replay counter wrapped\n"); -#endif - espstat.esps_wrap++; - return EHOSTDOWN; /* XXX */ - } - - ipo = *ip; - nh = ipo.ip_p; - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: next protocol is %d\n", nh); -#endif - - /* Raw payload length */ - rlen = ESP3DESMD5_RPLENGTH + ilen - iphlen; - - padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; - - pad = (u_char *)m_pad(m, padding); - if (pad == NULL) - return ENOBUFS; - - pad[padding-2] = padding - 2; - pad[padding-1] = nh; - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: padding %d bytes\n", padding); -#endif - - plen = rlen + padding + ESP3DESMD5_ALEN; - - ctx = xd->edx_ictx; /* Get inner padding cached */ - - bcopy(xd->edx_iv, iv, ESP3DESMD5_IVS); - - MD5Update(&ctx, (u_char *)&spi, sizeof(u_int32_t)); - MD5Update(&ctx, iv, ESP3DESMD5_IVS); - rplc = htonl(xd->edx_rpl); - MD5Update(&ctx, (unsigned char *)&rplc, ESP3DESMD5_RPLENGTH); - xd->edx_rpl++; - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: using replay counter %x\n", - xd->edx_rpl - 1); -#endif - mi = m; - - /* MD5 the data */ - while (mi != NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: MD5'ing %d bytes\n", mi->m_len); -#endif - if (mi == m) - MD5Update(&ctx, (u_char *)mi->m_data + iphlen, mi->m_len - iphlen); - else - MD5Update(&ctx, (u_char *)mi->m_data, mi->m_len); - mi = mi->m_next; - } - - MD5Final(auth, &ctx); - ctx = xd->edx_octx; - MD5Update(&ctx, auth, ESP3DESMD5_ALEN); - MD5Final(auth, &ctx); /* That's the authenticator */ - - /* - * This routine is different from espdes_output() in that - * here we construct the whole packet before starting encrypting. - */ - - m = m_pullup(m, iphlen + ESP3DESMD5_RPLENGTH + - sizeof(u_int32_t) + xd->edx_ivlen); - if (m == NULL) - return ENOBUFS; - - /* Copy data if necessary */ - if (m->m_len - iphlen) - { -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: pushing data\n"); -#endif - ms = m_copym(m, iphlen, m->m_len - iphlen, M_DONTWAIT); - if (ms == NULL) - return ENOBUFS; - - ms->m_next = m->m_next; - m->m_next = ms; - m->m_len = iphlen; - } - - /* Copy SPI, IV (or not) and replay counter */ - bcopy((caddr_t)&spi, mtod(m, caddr_t) + iphlen, sizeof (u_int32_t)); - bcopy((caddr_t)iv, mtod(m, caddr_t) + iphlen + sizeof (u_int32_t), - xd->edx_ivlen); - bcopy((caddr_t)&rplc, mtod(m, caddr_t) + iphlen + sizeof(u_int32_t) + - xd->edx_ivlen, ESP3DESMD5_RPLENGTH); - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: replay counter (wire value) %x\n", rplc); -#endif - - /* Adjust the length accordingly */ - m->m_len += sizeof(u_int32_t) + ESP3DESMD5_RPLENGTH + xd->edx_ivlen; - m->m_pkthdr.len += sizeof(u_int32_t) + ESP3DESMD5_RPLENGTH + - xd->edx_ivlen; - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: mbuf chain length %d\n", m->m_pkthdr.len); -#endif - - /* Let's append the authenticator too */ - MGET(ms, M_DONTWAIT, MT_DATA); - if (ms == NULL) - return ENOBUFS; - - bcopy(auth, mtod(ms, u_char *), ESP3DESMD5_ALEN); - ms->m_len = ESP3DESMD5_ALEN; - - m_cat(m, ms); - m->m_pkthdr.len += ESP3DESMD5_ALEN; /* Adjust length */ - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: final mbuf chain length %d\n", - m->m_pkthdr.len); -#endif - - ilen = olen = m->m_len - iphlen - sizeof(u_int32_t) - xd->edx_ivlen; - idat = odat = mtod(m, u_char *) + iphlen + sizeof(u_int32_t) - + xd->edx_ivlen; - i = 0; - mi = mo = m; - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: starting encryption with ilen=%d, plen=%d\n", - ilen, plen); -#endif - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("esp3desmd5_output: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = *idat++ ^ iv[i]; - - i++; - ilen--; - - if (i == 8) /* We have full block */ - { - des_ecb3_encrypt(blk, blk, (caddr_t)(xd->edx_eks[0]), - (caddr_t)(xd->edx_eks[1]), - (caddr_t)(xd->edx_eks[2]), 1); - for (i = 0; i < 8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("esp3desmd5_output: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat++ = blk[i]; - iv[i] = blk[i]; - olen--; - } - i = 0; - } - - plen--; - } - -#ifdef ENCDEBUG - if (encdebug) - printf("esp3desmd5_output: almost done now\n"); -#endif - - if (xd->edx_ivlen != 0) - bcopy(iv, xd->edx_iv, ESP3DESMD5_IVS); /* New IV */ - - /* Fix the length and the next protocol, copy back and off we go */ - ipo.ip_len = htons(iphlen + ohlen + rlen + padding + ESP3DESMD5_ALEN); - ipo.ip_p = IPPROTO_ESP; - bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof(struct ip)); - - /* Copy back the options, if existing */ - if (iphlen != sizeof(struct ip)) - bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip), - iphlen - sizeof(struct ip)); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += rlen + padding; - - return 0; -} diff --git a/sys/netinet/ip_espdes.c b/sys/netinet/ip_espdes.c deleted file mode 100644 index cfbd603b514..00000000000 --- a/sys/netinet/ip_espdes.c +++ /dev/null @@ -1,547 +0,0 @@ -/* $OpenBSD: ip_espdes.c,v 1.9 1997/07/01 22:12:48 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * DES-CBC - * Per RFC1829 (Metzger & Simpson, 1995) - */ - -#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 <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> -#include <net/encap.h> - -#include <netinet/ip_icmp.h> -#include <netinet/ip_ipsp.h> -#include <netinet/ip_esp.h> -#include <dev/rndvar.h> - -extern struct ifnet loif; - -extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int); -extern void des_set_key(caddr_t, caddr_t); - -int -espdes_attach() -{ - return 0; -} - -/* - * espdes_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data, in - * this case, the encryption and decryption key schedules - */ - -int -espdes_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct espdes_xdata *xd; - struct encap_msghdr *em; - u_int32_t rk[2]; - - tdbp->tdb_xform = xsp; - - m = m_pullup(m, ESP_ULENGTH); - if (m == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdes_init: can't pull up %d bytes\n", ESP_ULENGTH); -#endif ENCDEBUG - return ENOBUFS; - } - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct espdes_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct espdes_xdata)); - xd = (struct espdes_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN != ESP_ULENGTH) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - m_copydata(m, EMT_SETSPI_FLEN, ESP_ULENGTH, (caddr_t)xd); - - rk[0] = xd->edx_eks[0][0]; /* some overloading doesn't hurt */ - rk[1] = xd->edx_eks[0][1]; /* XXX -- raw-major order */ - - des_set_key((caddr_t)rk, (caddr_t)(xd->edx_eks)); - rk[0] = rk[1] = 0; /* zeroize! */ - - return 0; -} - -int -espdes_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - - -struct mbuf * -espdes_input(struct mbuf *m, struct tdb *tdb) -{ - struct espdes_xdata *xd; - struct ip *ip, ipo; - u_char iv[8], niv[8], blk[8]; - u_char *idat, *odat; - struct esp *esp; - struct ifnet *rcvif; - int ohlen, plen, ilen, olen, i; - struct mbuf *mi, *mo; - - xd = (struct espdes_xdata *)tdb->tdb_xdata; - ohlen = sizeof (struct ip) + ESP_FLENGTH; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdes_input: receive interface is NULL!!!\n"); -#endif ENCDEBUG - rcvif = &loif; - } - - ip = mtod(m, struct ip *); - ipo = *ip; - esp = (struct esp *)(ip + 1); - - plen = m->m_pkthdr.len - sizeof (struct ip) - sizeof (u_int32_t) - xd->edx_ivlen; - if (plen & 07) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdes_input: payload not a multiple of 8 octets\n"); -#endif ENCDEBUG - espstat.esps_badilen++; - m_freem(m); - return NULL; - } - - ilen = m->m_len - sizeof (struct ip) - 8; - idat = mtod(m, unsigned char *) + sizeof (struct ip) + 8; - - iv[0] = esp->esp_iv[0]; - iv[1] = esp->esp_iv[1]; - iv[2] = esp->esp_iv[2]; - iv[3] = esp->esp_iv[3]; - if (xd->edx_ivlen == 4) - { - iv[4] = ~esp->esp_iv[0]; - iv[5] = ~esp->esp_iv[1]; - iv[6] = ~esp->esp_iv[2]; - iv[7] = ~esp->esp_iv[3]; - } - else - { - iv[4] = esp->esp_iv[4]; - iv[5] = esp->esp_iv[5]; - iv[6] = esp->esp_iv[6]; - iv[7] = esp->esp_iv[7]; - - ilen -= 4; - idat += 4; - } - - olen = ilen; - odat = idat; - mi = mo = m; - i = 0; - - /* - * At this point: - * plen is # of encapsulated payload octets - * ilen is # of octets left in this mbuf - * idat is first encapsulated payload octed in this mbuf - * same for olen and odat - * iv contains the IV. - * mi and mo point to the first mbuf - * - * From now on until the end of the mbuf chain: - * . move the next eight octets of the chain into blk[] - * (ilen, idat, and mi are adjusted accordingly) - * and save it back into iv[] - * . decrypt blk[], xor with iv[], put back into chain - * (olen, odat, amd mo are adjusted accordingly) - * . repeat - */ - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("espdes_input: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = niv[i] = *idat++; - i++; - ilen--; - - if (i == 8) - { - des_ecb_encrypt(blk, blk, (caddr_t)(xd->edx_eks), 0); - for (i=0; i<8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("espdes_input: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat = blk[i] ^ iv[i]; - iv[i] = niv[i]; - blk[i] = *odat++; /* needed elsewhere */ - olen--; - } - i = 0; - } - - plen--; - } - - /* - * Now, the entire chain has been decrypted. As a side effect, - * blk[7] contains the next protocol, and blk[6] contains the - * amount of padding the original chain had. Chop off the - * appropriate parts of the chain, and return. - */ - - m_adj(m, -blk[6] - 2); - m_adj(m, 4 + xd->edx_ivlen); - if (m->m_len < sizeof (struct ip)) - { - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - { - return NULL; - } - } - - ip = mtod(m, struct ip *); - ipo.ip_p = blk[7]; - ipo.ip_id = htons(ipo.ip_id); - ipo.ip_off = 0; - ipo.ip_len += sizeof (struct ip) - 4 - xd->edx_ivlen - blk[6] - 2; - ipo.ip_len = htons(ipo.ip_len); - ipo.ip_sum = 0; - *ip = ipo; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) + blk[6] + 2; - - return m; -} - -int -espdes_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct espdes_xdata *xd; - struct ip *ip, ipo; - int i, ilen, olen, ohlen, nh, rlen, plen, padding; - u_int32_t spi; - struct mbuf *mi, *mo; - u_char *pad, *idat, *odat; - u_char iv[8], blk[8], opts[40]; - int iphlen; - - espstat.esps_output++; - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - spi = tdb->tdb_spi; - iphlen = ip->ip_hl << 2; - - /* - * If options are present, pullup the IP header, the options - * and one DES block (8 bytes) of data. - */ - if (iphlen != sizeof(struct ip)) - { - m = m_pullup(m, iphlen + 8); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - /* Keep the options */ - bcopy(mtod(m, u_char *) + sizeof(struct ip), opts, - iphlen - sizeof(struct ip)); - } - - xd = (struct espdes_xdata *)tdb->tdb_xdata; - ilen = ntohs(ip->ip_len); - ohlen = sizeof (u_int32_t) + xd->edx_ivlen; - - ipo = *ip; - nh = ipo.ip_p; - - rlen = ilen - iphlen; /* raw payload length */ - padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; - - pad = (u_char *)m_pad(m, padding); - if (pad == NULL) - return ENOBUFS; - - pad[padding-2] = padding - 2; - pad[padding-1] = nh; - - plen = rlen + padding; - mi = mo = m; - ilen = olen = m->m_len - iphlen; - idat = odat = mtod(m, u_char *) + iphlen; - i = 0; - - /* - * We are now ready to encrypt the payload. - */ - - xd->edx_ivl++; - - iv[0] = xd->edx_iv[0]; - iv[1] = xd->edx_iv[1]; - iv[2] = xd->edx_iv[2]; - iv[3] = xd->edx_iv[3]; - if (xd->edx_ivlen == 4) - { - iv[4] = ~xd->edx_iv[0]; - iv[5] = ~xd->edx_iv[1]; - iv[6] = ~xd->edx_iv[2]; - iv[7] = ~xd->edx_iv[3]; - } - else - { - iv[4] = xd->edx_iv[4]; - iv[5] = xd->edx_iv[5]; - iv[6] = xd->edx_iv[6]; - iv[7] = xd->edx_iv[7]; - } - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("espdes_output: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = *idat++ ^ iv[i]; - - i++; - ilen--; - - if (i == 8) - { - des_ecb_encrypt(blk, blk, (caddr_t)(xd->edx_eks), 1); - for (i = 0; i < 8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("espdes_output: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat++ = blk[i]; - iv[i] = blk[i]; - olen--; - } - i = 0; - } - - plen--; - } - - /* - * Done with encryption. Let's wedge in the ESP header - * and send it out. - */ - - M_PREPEND(m, ohlen, M_DONTWAIT); - if (m == NULL) - return ENOBUFS; - - m = m_pullup(m, iphlen + ohlen); - if (m == NULL) - return ENOBUFS; - - ipo.ip_len = htons(iphlen + ohlen + rlen + padding); - ipo.ip_p = IPPROTO_ESP; - - iv[0] = xd->edx_iv[0]; - iv[1] = xd->edx_iv[1]; - iv[2] = xd->edx_iv[2]; - iv[3] = xd->edx_iv[3]; - if (xd->edx_ivlen == 8) - { - iv[4] = xd->edx_iv[4]; - iv[5] = xd->edx_iv[5]; - iv[6] = xd->edx_iv[6]; - iv[7] = xd->edx_iv[7]; - } - - bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof(struct ip)); - - /* Copy options, if existing */ - if (iphlen != sizeof(struct ip)) - bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip), - iphlen - sizeof(struct ip)); - - bcopy((caddr_t)&spi, mtod(m, caddr_t) + iphlen, sizeof(u_int32_t)); - bcopy((caddr_t)iv, mtod(m, caddr_t) + iphlen + - sizeof (u_int32_t), xd->edx_ivlen); - - *mp = m; - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += rlen + padding; - - return 0; -} - - - -/* - * - * - * m_pad(m, n) pads <m> with <n> bytes at the end. The packet header - * length is updated, and a pointer to the first byte of the padding - * (which is guaranteed to be all in one mbuf) is returned. - * - */ - -caddr_t -m_pad(struct mbuf *m, int n) -{ - register int len, pad; - register struct mbuf *m0, *m1; - caddr_t retval; - u_char dat; - - if (n <= 0) /* no stupid arguments */ - return NULL; - - len = m->m_pkthdr.len; - pad = n; - - m0 = m; - - while (m0->m_len < len) - { - len -= m0->m_len; - m0 = m0->m_next; - } - - if (m0->m_len != len) - { -#ifdef ENCDEBUG - if (encdebug) - printf("m_pad: length mismatch (should be %d instead of %d\n", - m->m_pkthdr.len, m->m_pkthdr.len + m0->m_len - len); -#endif ENCDEBUG - m_freem(m); - return NULL; - } - - if ((m0->m_flags & M_EXT) || - (m0->m_data + m0->m_len + pad >= &(m0->m_dat[MLEN]))) - { - /* - * Add an mbuf to the chain - */ - - MGET(m1, M_DONTWAIT, MT_DATA); - if (m1 == 0) - { - m_freem(m0); -#ifdef ENCDEBUG - if (encdebug) - printf("m_pad: cannot append\n"); -#endif ENCDEBUG - return NULL; - } - m0->m_next = m1; - m0 = m1; - m0->m_len = 0; - } - - retval = m0->m_data + m0->m_len; - m0->m_len += pad; - m->m_pkthdr.len += pad; - - for (len = 0; len < n; len++) - { - get_random_bytes((void *)&dat, sizeof(dat)); - retval[len] = len + dat; - } - - return retval; -} diff --git a/sys/netinet/ip_espdesmd5.c b/sys/netinet/ip_espdesmd5.c deleted file mode 100644 index 4e50b1d6501..00000000000 --- a/sys/netinet/ip_espdesmd5.c +++ /dev/null @@ -1,845 +0,0 @@ -/* $OpenBSD: ip_espdesmd5.c,v 1.11 1997/07/01 22:12:49 provos Exp $ */ - -/* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). - * - * This code was written for BSD/OS in Athens, Greece, in November 1995. - * - * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. - * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis and Angelos D. Keromytis. - * - * Permission to use, copy, and modify this software 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. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE - * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR - * PURPOSE. - */ - -/* - * Based on draft-ietf-ipsec-esp-des-md5-03.txt. - */ - -#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 <machine/cpu.h> - -#include <net/if.h> -#include <net/route.h> -#include <net/netisr.h> - -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/in_var.h> -#include <netinet/ip_var.h> - -#include <sys/socketvar.h> -#include <net/raw_cb.h> -#include <net/encap.h> - -#include <netinet/ip_icmp.h> -#include <netinet/ip_ipsp.h> -#include <netinet/ip_esp.h> - -extern struct ifnet loif; - -extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int); -extern void des_set_key(caddr_t, caddr_t); - -int -espdesmd5_attach() -{ - return 0; -} - -/* - * espdesmd5_init() is called when an SPI is being set up. It interprets the - * encap_msghdr present in m, and sets up the transformation data, in - * this case, the encryption and decryption key schedules - */ - -int -espdesmd5_init(struct tdb *tdbp, struct xformsw *xsp, struct mbuf *m) -{ - struct espdesmd5_xdata *xd; - struct encap_msghdr *em; - struct espdesmd5_xencap txd; - u_char buf[ESPDESMD5_KEYSZ]; - int len; - MD5_CTX ctx; - - tdbp->tdb_xform = xsp; - - m = m_pullup(m, ESPDESMD5_ULENGTH); - if (m == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_init: can't pull up %d bytes\n", ESP_ULENGTH); -#endif ENCDEBUG - return ENOBUFS; - } - - MALLOC(tdbp->tdb_xdata, caddr_t, sizeof (struct espdesmd5_xdata), - M_XDATA, M_WAITOK); - if (tdbp->tdb_xdata == NULL) - return ENOBUFS; - bzero(tdbp->tdb_xdata, sizeof (struct espdesmd5_xdata)); - xd = (struct espdesmd5_xdata *)tdbp->tdb_xdata; - - em = mtod(m, struct encap_msghdr *); - if (em->em_msglen - EMT_SETSPI_FLEN != ESPDESMD5_ULENGTH) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - m_copydata(m, EMT_SETSPI_FLEN, em->em_msglen - EMT_SETSPI_FLEN, - (caddr_t)&txd); - - if ((txd.edx_ivlen != 0) && (txd.edx_ivlen != 8)) - { - free((caddr_t)tdbp->tdb_xdata, M_XDATA); - tdbp->tdb_xdata = NULL; - return EINVAL; - } - - bzero(ipseczeroes, IPSEC_ZEROES_SIZE); /* paranoid */ - - xd->edx_ivlen = txd.edx_ivlen; - xd->edx_bitmap = 0; - xd->edx_wnd = txd.edx_wnd; - - /* Fix the IV */ - -#ifdef ENCDEBUG - if (encdebug) - { - if (txd.edx_initiator) - printf("INITIATOR\n"); - printf("IV length: %d\n", txd.edx_ivlen); - } -#endif - if (txd.edx_ivlen) - bcopy(txd.edx_ivv, xd->edx_iv, ESPDESMD5_IVS); - else - { - for (len = 0; len < ESPDESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESPDESMD5_IPADI : - ESPDESMD5_IPADR; - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESPDESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - bcopy(buf, xd->edx_iv, ESPDESMD5_IVS); -#ifdef ENCDEBUG - printf("IV "); - if (encdebug) - for (len = 0; len < ESPDESMD5_IVS; len++) - printf(" %02x", xd->edx_iv[len]); - printf("\n"); -#endif - } - - /* DES key */ - - MD5Init(&ctx); - for (len = 0; len < ESPDESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESPDESMD5_DPADI : ESPDESMD5_DPADR; - - MD5Update(&ctx, buf, ESPDESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - des_set_key((caddr_t)buf, (caddr_t)(xd->edx_eks)); - - /* HMAC contexts */ - - MD5Init(&ctx); - for (len = 0; len < ESPDESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESPDESMD5_HPADI : ESPDESMD5_HPADR; - - MD5Update(&ctx, buf, ESPDESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - - bzero(buf + ESPDESMD5_ALEN, ESPDESMD5_KEYSZ - ESPDESMD5_ALEN); - - for (len = 0; len < ESPDESMD5_KEYSZ; len++) - buf[len] ^= ESPDESMD5_IPAD_VAL; - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESPDESMD5_KEYSZ); - xd->edx_ictx = ctx; - - for (len = 0; len < ESPDESMD5_KEYSZ; len++) - buf[len] ^= (ESPDESMD5_IPAD_VAL ^ ESPDESMD5_OPAD_VAL); - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESPDESMD5_KEYSZ); - xd->edx_octx = ctx; - - /* Replay counter */ - - for (len = 0; len < ESPDESMD5_KEYSZ; len++) - buf[len] = txd.edx_initiator ? ESPDESMD5_RPADI : - ESPDESMD5_RPADR; - - MD5Init(&ctx); - MD5Update(&ctx, buf, ESPDESMD5_KEYSZ); - MD5Update(&ctx, txd.edx_key, txd.edx_keylen); - MD5Final(buf, &ctx); - bcopy(buf, (unsigned char *)&(xd->edx_rpl), ESPDESMD5_RPLENGTH); - xd->edx_initial = xd->edx_rpl - 1; - -#ifdef ENCDEBUG - if (encdebug) - printf("Initial replay counter: %x (%x)\n", xd->edx_rpl, - xd->edx_initial); -#endif - - bzero(&txd, sizeof(struct espdesmd5_xencap)); - bzero(buf, ESPDESMD5_KEYSZ); - bzero(&ctx, sizeof(MD5_CTX)); - - return 0; -} - -int -espdesmd5_zeroize(struct tdb *tdbp) -{ - FREE(tdbp->tdb_xdata, M_XDATA); - return 0; -} - - -struct mbuf * -espdesmd5_input(struct mbuf *m, struct tdb *tdb) -{ - struct espdesmd5_xdata *xd; - struct ip *ip, ipo; - u_char iv[8], niv[8], blk[8], auth[ESPDESMD5_ALEN]; - u_char iauth[ESPDESMD5_ALEN]; - u_char *idat, *odat; - struct esp *esp; - struct ifnet *rcvif; - int plen, ilen, olen, i, authp, oplen, errc; - u_int32_t rplc, tbitmap, trpl; - u_char padsize, nextproto; - struct mbuf *mi, *mo; - MD5_CTX ctx; - - xd = (struct espdesmd5_xdata *)tdb->tdb_xdata; - - rcvif = m->m_pkthdr.rcvif; - if (rcvif == NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_input: receive interface is NULL!!!\n"); -#endif ENCDEBUG - rcvif = &loif; - } - - ip = mtod(m, struct ip *); - ipo = *ip; - esp = (struct esp *)(ip + 1); - - plen = m->m_pkthdr.len - sizeof (struct ip) - sizeof (u_int32_t) - - xd->edx_ivlen; - if (plen & 07) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_input: payload not a multiple of 8 octets\n"); -#endif ENCDEBUG - espstat.esps_badilen++; - m_freem(m); - return NULL; - } - - oplen = plen; - ilen = m->m_len - sizeof (struct ip) - ESPDESMD5_IVS - sizeof(u_int32_t); - idat = mtod(m, unsigned char *) + sizeof (struct ip) + sizeof(u_int32_t) + - ESPDESMD5_IVS; - - if (xd->edx_ivlen == 0) /* KeyIV in use */ - { - bcopy(xd->edx_iv, iv, ESPDESMD5_IVS); - ilen += ESPDESMD5_IVS; - idat -= ESPDESMD5_IVS; - } - else - bcopy(idat - ESPDESMD5_IVS, iv, ESPDESMD5_IVS); - - olen = ilen; - odat = idat; - mi = mo = m; - i = 0; - authp = 0; - - ctx = xd->edx_ictx; - - MD5Update(&ctx, (unsigned char *)&(tdb->tdb_spi), sizeof(u_int32_t)); - MD5Update(&ctx, iv, ESPDESMD5_IVS); - -#ifdef ENCDEBUG - printf("IV "); - for (i = 0; i < ESPDESMD5_IVS; i++) - printf(" %02x", iv[i]); - printf("\n"); - i = 0; -#endif - - /* - * At this point: - * plen is # of encapsulated payload octets - * ilen is # of octets left in this mbuf - * idat is first encapsulated payload octed in this mbuf - * same for olen and odat - * iv contains the IV. - * mi and mo point to the first mbuf - * - * From now on until the end of the mbuf chain: - * . move the next eight octets of the chain into blk[] - * (ilen, idat, and mi are adjusted accordingly) - * and save it back into iv[] - * . decrypt blk[], xor with iv[], put back into chain - * (olen, odat, amd mo are adjusted accordingly) - * . repeat - */ - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("espdesmd5_input: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = niv[i] = *idat++; - i++; - ilen--; - - if (i == 8) - { - des_ecb_encrypt(blk, blk, (caddr_t)(xd->edx_eks), 0); - for (i=0; i<8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("espdesmd5_input: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat = blk[i] ^ iv[i]; - iv[i] = niv[i]; - blk[i] = *odat++; /* needed elsewhere */ - olen--; - } - i = 0; - - if (plen < ESPDESMD5_ALEN) - { - bcopy(blk, auth + authp, ESPDESMD5_DESBLK); - authp += ESPDESMD5_DESBLK; -#ifdef ENCDEBUG - if (encdebug) - printf("Copying authenticator from %d\n", - plen); -#endif - } - else - { - if (plen == ESPDESMD5_ALEN + 1) - { - nextproto = blk[7]; - padsize = blk[6]; -#ifdef ENCDEBUG - if (encdebug) - printf("Next protocol: %d\nPadsize: %d\n", nextproto, - padsize); -#endif - } - else - if (plen + 7 == oplen) - { -#ifdef ENCDEBUG - if (encdebug) - printf("SEQ %02x %02x %02x %02x\n", - blk[0], blk[1], blk[2], - blk[3]); -#endif - tbitmap = xd->edx_bitmap; /* Save it */ - trpl = xd->edx_rpl; - rplc = ntohl(*((u_int32_t *)blk)); - if ((errc = checkreplaywindow32(rplc, xd->edx_initial, &(xd->edx_rpl), xd->edx_wnd, &(xd->edx_bitmap))) != 0) - { - switch (errc) - { - case 1: -#ifdef ENCDEBUG - printf("espdesmd5_input: replay counter wrapped\n"); -#endif - espstat.esps_wrap++; - break; - case 2: -#ifdef ENCDEBUG - printf("espdesmd5_input: received old packet, seq = %08x\n", rplc); -#endif - espstat.esps_replay++; - break; - case 3: -#ifdef ENCDEBUG - printf("espdesmd5_input: packet already received\n"); -#endif - espstat.esps_replay++; - break; - } - m_freem(m); - return NULL; - } - } - - MD5Update(&ctx, blk, ESPDESMD5_DESBLK); - } - } - - plen--; - } - - /* - * Now, the entire chain has been decrypted. - */ - - MD5Final(iauth, &ctx); - ctx = xd->edx_octx; - MD5Update(&ctx, iauth, ESPDESMD5_ALEN); - MD5Final(iauth, &ctx); - -#ifdef ENCDEBUG - printf("RECEIVED "); - for (rplc = 0; rplc < ESPDESMD5_ALEN; rplc++) - printf(" %02x", auth[rplc]); - printf("\nSHOULD HAVE "); - for (rplc = 0; rplc < ESPDESMD5_ALEN; rplc++) - printf(" %02x", iauth[rplc]); - printf("\n"); -#endif - - if (bcmp(auth, iauth, ESPDESMD5_ALEN)) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_input: bad auth\n"); -#endif - xd->edx_rpl = trpl; - xd->edx_bitmap = tbitmap; /* Restore */ - espstat.esps_badauth++; - m_freem(m); - return NULL; - } - - m_adj(m, - padsize - 2 - ESPDESMD5_ALEN); - m_adj(m, 4 + xd->edx_ivlen + ESPDESMD5_RPLENGTH); - - if (m->m_len < sizeof (struct ip)) - { - m = m_pullup(m, sizeof (struct ip)); - if (m == NULL) - { - xd->edx_rpl = trpl; - xd->edx_bitmap = tbitmap; - return NULL; - } - } - - ip = mtod(m, struct ip *); - ipo.ip_p = nextproto; - ipo.ip_id = htons(ipo.ip_id); - ipo.ip_off = 0; - ipo.ip_len += sizeof (struct ip) - ESPDESMD5_RPLENGTH - 4 - xd->edx_ivlen - - padsize - 2 - ESPDESMD5_ALEN; -#ifdef ENCDEBUG - if (encdebug) - printf("IP packet size %d\n", ipo.ip_len); -#endif - ipo.ip_len = htons(ipo.ip_len); - ipo.ip_sum = 0; - *ip = ipo; - ip->ip_sum = in_cksum(m, sizeof (struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += ntohs(ip->ip_len) - (ip->ip_hl << 2) + padsize + - 2 + ESPDESMD5_ALEN; - - return m; -} - -int -espdesmd5_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, - struct mbuf **mp) -{ - struct espdesmd5_xdata *xd; - struct ip *ip, ipo; - int i, ilen, olen, ohlen, nh, rlen, plen, padding; - u_int32_t rplc; - u_int32_t spi; - struct mbuf *mi, *mo, *ms; - u_char *pad, *idat, *odat; - u_char iv[ESPDESMD5_IVS], blk[8], auth[ESPDESMD5_ALEN], opts[40]; - MD5_CTX ctx; - int iphlen; - - espstat.esps_output++; - m = m_pullup(m, sizeof (struct ip)); /* Get IP header in one mbuf */ - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - spi = tdb->tdb_spi; - iphlen = ip->ip_hl << 2; - - /* - * If options are present, pullup the IP header, the options - * and one DES block (8 bytes) of data. - */ - if (iphlen != sizeof(struct ip)) - { - m = m_pullup(m, iphlen + 8); - if (m == NULL) - return ENOBUFS; - - ip = mtod(m, struct ip *); - - /* Keep the options */ - bcopy(mtod(m, u_char *) + sizeof(struct ip), opts, - iphlen - sizeof(struct ip)); - } - - xd = (struct espdesmd5_xdata *)tdb->tdb_xdata; - ilen = ntohs(ip->ip_len); /* Size of the packet */ - ohlen = sizeof (u_int32_t) + xd->edx_ivlen; /* size of plaintext ESP */ - - if (xd->edx_rpl == xd->edx_initial) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: replay counter wrapped\n"); -#endif - espstat.esps_wrap++; - return EHOSTDOWN; /* XXX */ - } - - ipo = *ip; - nh = ipo.ip_p; - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: next protocol is %d\n", nh); -#endif - - /* Raw payload length */ - rlen = ESPDESMD5_RPLENGTH + ilen - iphlen; - - padding = ((8 - ((rlen + 2) % 8)) % 8) + 2; - - pad = (u_char *)m_pad(m, padding); - if (pad == NULL) - return ENOBUFS; - - pad[padding-2] = padding - 2; - pad[padding-1] = nh; - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: padding %d bytes\n", padding); -#endif - - plen = rlen + padding + ESPDESMD5_ALEN; - - ctx = xd->edx_ictx; /* Get inner padding cached */ - - bcopy(xd->edx_iv, iv, ESPDESMD5_IVS); - - MD5Update(&ctx, (u_char *)&spi, sizeof(u_int32_t)); - MD5Update(&ctx, iv, ESPDESMD5_IVS); - rplc = htonl(xd->edx_rpl); - MD5Update(&ctx, (unsigned char *)&rplc, ESPDESMD5_RPLENGTH); - xd->edx_rpl++; - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: using replay counter %x\n", - xd->edx_rpl - 1); -#endif - mi = m; - - /* MD5 the data */ - while (mi != NULL) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: MD5'ing %d bytes\n", mi->m_len); -#endif - if (mi == m) - MD5Update(&ctx, (u_char *)mi->m_data + iphlen, - mi->m_len - iphlen); - else - MD5Update(&ctx, (u_char *)mi->m_data, mi->m_len); - mi = mi->m_next; - } - - MD5Final(auth, &ctx); - ctx = xd->edx_octx; - MD5Update(&ctx, auth, ESPDESMD5_ALEN); - MD5Final(auth, &ctx); /* That's the authenticator */ - - /* - * This routine is different from espdes_output() in that - * here we construct the whole packet before starting encrypting. - */ - - m = m_pullup(m, iphlen + ESPDESMD5_RPLENGTH + - sizeof(u_int32_t) + xd->edx_ivlen); - if (m == NULL) - return ENOBUFS; - - /* Copy data if necessary */ - if (m->m_len - iphlen) - { -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: pushing data\n"); -#endif - ms = m_copym(m, iphlen, m->m_len - iphlen, M_DONTWAIT); - if (ms == NULL) - return ENOBUFS; - - ms->m_next = m->m_next; - m->m_next = ms; - m->m_len = iphlen; - } - - /* Copy SPI, IV (or not) and replay counter */ - bcopy((caddr_t)&spi, mtod(m, caddr_t) + iphlen, sizeof (u_int32_t)); - bcopy((caddr_t)iv, mtod(m, caddr_t) + iphlen + sizeof (u_int32_t), - xd->edx_ivlen); - bcopy((caddr_t)&rplc, mtod(m, caddr_t) + iphlen + sizeof(u_int32_t) + - xd->edx_ivlen, ESPDESMD5_RPLENGTH); - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: replay counter (wire value) %x\n", rplc); -#endif - - /* Adjust the length accordingly */ - m->m_len += sizeof(u_int32_t) + ESPDESMD5_RPLENGTH + xd->edx_ivlen; - m->m_pkthdr.len += sizeof(u_int32_t) + ESPDESMD5_RPLENGTH + - xd->edx_ivlen; - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: mbuf chain length %d\n", m->m_pkthdr.len); -#endif - - /* Let's append the authenticator too */ - MGET(ms, M_DONTWAIT, MT_DATA); - if (ms == NULL) - return ENOBUFS; - - bcopy(auth, mtod(ms, u_char *), ESPDESMD5_ALEN); - ms->m_len = ESPDESMD5_ALEN; - - m_cat(m, ms); - m->m_pkthdr.len += ESPDESMD5_ALEN; /* Adjust length */ - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: final mbuf chain length %d\n", - m->m_pkthdr.len); -#endif - - ilen = olen = m->m_len - iphlen - sizeof(u_int32_t) - xd->edx_ivlen; - idat = odat = mtod(m, u_char *) + iphlen + sizeof(u_int32_t) - + xd->edx_ivlen; - i = 0; - mi = mo = m; - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: starting encryption with ilen=%d, plen=%d\n", - ilen, plen); -#endif - - while (plen > 0) /* while not done */ - { - while (ilen == 0) /* we exhausted previous mbuf */ - { - mi = mi->m_next; - if (mi == NULL) - panic("espdesmd5_output: bad chain (i)\n"); - ilen = mi->m_len; - idat = (u_char *)mi->m_data; - } - - blk[i] = *idat++ ^ iv[i]; - - i++; - ilen--; - - if (i == 8) /* We have full block */ - { - des_ecb_encrypt(blk, blk, (caddr_t)(xd->edx_eks), 1); - for (i = 0; i < 8; i++) - { - while (olen == 0) - { - mo = mo->m_next; - if (mo == NULL) - panic("espdesmd5_output: bad chain (o)\n"); - olen = mo->m_len; - odat = (u_char *)mo->m_data; - } - *odat++ = blk[i]; - iv[i] = blk[i]; - olen--; - } - i = 0; - } - - plen--; - } - -#ifdef ENCDEBUG - if (encdebug) - printf("espdesmd5_output: almost done now\n"); -#endif - - if (xd->edx_ivlen != 0) - bcopy(iv, xd->edx_iv, ESPDESMD5_IVS); /* New IV */ - - /* Fix the length and the next protocol, copy back and off we go */ - ipo.ip_len = htons(iphlen + ohlen + rlen + padding + - ESPDESMD5_ALEN); - ipo.ip_p = IPPROTO_ESP; - bcopy((caddr_t)&ipo, mtod(m, caddr_t), sizeof(struct ip)); - - /* Copy back the options, if existing */ - if (iphlen != sizeof(struct ip)) - bcopy(opts, mtod(m, caddr_t) + sizeof(struct ip), - iphlen - sizeof(struct ip)); - - /* Update the counters */ - tdb->tdb_cur_packets++; - tdb->tdb_cur_bytes += rlen + padding; - - *mp = m; - return 0; -} - - -/* - * both versions of the checkreplaywindow for 32 and 64 bit counters - * return 0 on success - * return 1 for counter == 0 - * return 2 for very old packet - * return 3 for packet within current window but already received - */ - -int -checkreplaywindow64(u_int64_t seq, u_int64_t *lastseq, u_int64_t window, u_int64_t *bitmap) -{ - u_int64_t diff; - - if (seq == 0) - return 1; - - if (seq > *lastseq) - { - diff = seq - *lastseq; - if (diff < window) - *bitmap = ((*bitmap) << diff) | 1; - else - *bitmap = 1; - *lastseq = seq; - return 0; - } - diff = *lastseq - seq; - if (diff >= window) - { - espstat.esps_wrap++; - return 2; - } - if ((*bitmap) & (((u_int64_t) 1) << diff)) - { - espstat.esps_replay++; - return 3; - } - *bitmap |= (((u_int64_t) 1) << diff); - return 0; -} - -int -checkreplaywindow32(u_int32_t seq, u_int32_t initial, u_int32_t *lastseq, u_int32_t window, u_int32_t *bitmap) -{ - u_int32_t diff; - -#ifdef ENCDEBUG - if (encdebug) - printf("checkreplaywindow32: seq=%x lastseq=%x\n", seq, *lastseq); -#endif - - seq -= initial; - - if (seq == 0) - return 1; - - if (seq > *lastseq - initial) - { - diff = seq - (*lastseq - initial); - if (diff < window) - *bitmap = ((*bitmap) << diff) | 1; - else - *bitmap = 1; - *lastseq = seq + initial; - return 0; - } - diff = *lastseq - initial - seq; - if (diff >= window) - { - espstat.esps_wrap++; - return 2; - } - if ((*bitmap) & (((u_int32_t) 1) << diff)) - { - espstat.esps_replay++; - return 3; - } - *bitmap |= (((u_int32_t) 1) << diff); - return 0; -} |