IPSEC support in the kernel.

pr_input() routines prototype is also changed to support IPSEC and IPV6
chained protocol headers.

Reviewed by: freebsd-arch, cvs-committers
Obtained from: KAME project
This commit is contained in:
Yoshinobu Inoue 1999-12-22 19:13:38 +00:00
parent 2e636eed15
commit 6a800098cc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55009
101 changed files with 22639 additions and 4038 deletions

View File

@ -367,6 +367,10 @@ options ROOTDEVNAME=\"da0s2e\"
#
options INET #Internet communications protocols
options INET6 #IPv6 communications protocols
options IPSEC #IP security
options IPSEC_ESP #IP security (crypto; define w/ IPSEC)
options IPSEC_IPV6FWD #IP security tunnel for IPv6
options IPSEC_DEBUG #debug for IP security
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)

View File

@ -63,6 +63,19 @@ cam/scsi/scsi_pass.c optional pass
cam/scsi/scsi_scan.c optional scan
cam/scsi/scsi_target.c optional targ
cam/scsi/scsi_targ_bh.c optional targbh
crypto/sha1.c optional ipsec
crypto/des/des_cbc.c optional ipsec
crypto/des/des_ecb.c optional ipsec
crypto/des/des_setkey.c optional ipsec
crypto/des/des_3cbc.c optional ipsec
crypto/blowfish/bf_cbc.c optional ipsec
crypto/blowfish/bf_cbc_m.c optional ipsec
crypto/blowfish/bf_enc.c optional ipsec
crypto/blowfish/bf_skey.c optional ipsec
crypto/cast128/cast128.c optional ipsec
crypto/cast128/cast128_cbc.c optional ipsec
crypto/rc5/rc5.c optional ipsec
crypto/rc5/rc5_cbc.c optional ipsec
ddb/db_access.c optional ddb
ddb/db_kld.c optional ddb
ddb/db_aout.c optional ddb
@ -607,6 +620,8 @@ netinet/in.c optional inet
netinet/in_pcb.c optional inet
netinet/in_proto.c optional inet
netinet/in_rmx.c optional inet
netinet/ip_ecn.c optional inet
netinet/ip_ecn.c optional inet6
netinet/ip_divert.c optional ipdivert
netinet/ip_dummynet.c optional dummynet
netinet/ip_flow.c optional inet
@ -632,6 +647,13 @@ netinet/ip_auth.c optional ipfilter inet
netinet/ip_proxy.c optional ipfilter inet
netinet/ip_log.c optional ipfilter inet
netinet/mlfk_ipl.c optional ipfilter inet
netinet6/ah_core.c optional ipsec
netinet6/ah_input.c optional ipsec
netinet6/ah_output.c optional ipsec
netinet6/esp_core.c optional ipsec
netinet6/esp_input.c optional ipsec
netinet6/esp_output.c optional ipsec
netinet6/ipsec.c optional ipsec
netinet6/dest6.c optional inet6
netinet6/frag6.c optional inet6
netinet6/icmp6.c optional inet6
@ -664,8 +686,9 @@ netipx/ipx_tun.c optional ipx
netipx/ipx_usrreq.c optional ipx
netipx/spx_debug.c optional ipx
netipx/spx_usrreq.c optional ipx
netkey/key.c optional key
netkey/key_debug.c optional key_debug
netkey/key.c optional ipsec
netkey/key_debug.c optional ipsec
netkey/keysock.c optional ipsec
netnatm/natm.c optional natm
netnatm/natm_pcb.c optional natm
netnatm/natm_proto.c optional natm

View File

@ -231,6 +231,10 @@ BRIDGE opt_bdg.h
MROUTING opt_mrouting.h
INET opt_inet.h
INET6 opt_inet6.h
IPSEC opt_ipsec.h
IPSEC_ESP opt_ipsec.h
IPSEC_DEBUG opt_ipsec.h
IPSEC_IPV6FWD opt_ipsec.h
IPDIVERT
DUMMYNET opt_ipdn.h
IPFILTER opt_ipfilter.h

View File

@ -0,0 +1,150 @@
/* crypto/bf/bf_cbc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
void BF_cbc_encrypt(in, out, length, ks, iv, encrypt)
unsigned char *in;
unsigned char *out;
long length;
BF_KEY *ks;
unsigned char *iv;
int encrypt;
{
register BF_LONG tin0,tin1;
register BF_LONG tout0,tout1,xor0,xor1;
register long l=length;
BF_LONG tin[2];
if (encrypt)
{
n2l(iv,tout0);
n2l(iv,tout1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_ENCRYPT);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
if (l != -8)
{
n2ln(in,tin0,tin1,l+8);
tin0^=tout0;
tin1^=tout1;
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_ENCRYPT);
tout0=tin[0];
tout1=tin[1];
l2n(tout0,out);
l2n(tout1,out);
}
l2n(tout0,iv);
l2n(tout1,iv);
}
else
{
n2l(iv,xor0);
n2l(iv,xor1);
iv-=8;
for (l-=8; l>=0; l-=8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_DECRYPT);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2n(tout0,out);
l2n(tout1,out);
xor0=tin0;
xor1=tin1;
}
if (l != -8)
{
n2l(in,tin0);
n2l(in,tin1);
tin[0]=tin0;
tin[1]=tin1;
BF_encrypt(tin,ks,BF_DECRYPT);
tout0=tin[0]^xor0;
tout1=tin[1]^xor1;
l2nn(tout0,tout1,out,l+8);
xor0=tin0;
xor1=tin1;
}
l2n(xor0,iv);
l2n(xor1,iv);
}
tin0=tin1=tout0=tout1=xor0=xor1=0;
tin[0]=tin[1]=0;
}

View File

@ -0,0 +1,341 @@
/*
* heavily modified to accept mbuf, by Jun-ichiro itojun Itoh
* <itojun@itojun.org>, 1997.
*/
/* crypto/bf/bf_cbc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
#define panic(x) {printf(x); return;}
void BF_cbc_encrypt_m(m0, skip, length, key, iv, mode)
struct mbuf *m0;
int skip;
int length;
BF_KEY *key;
unsigned char *iv;
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
register BF_LONG tin0, tin1;
register BF_LONG tout0, tout1;
BF_LONG tin[2];
/* sanity checks */
if (m0->m_pkthdr.len < skip) {
printf("mbuf length < skip\n");
return;
}
if (m0->m_pkthdr.len < length) {
printf("mbuf length < encrypt length\n");
return;
}
if (m0->m_pkthdr.len < skip + length) {
printf("mbuf length < skip + encrypt length\n");
return;
}
if (length % 8) {
printf("length is not multiple of 8\n");
return;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* initialize */
tin0 = tin1 = tout0 = tout1 = 0;
tin[0] = tin[1] = 0;
if (mode == BF_ENCRYPT) {
u_int8_t *in, *out;
n2l(iv, tout0);
n2l(iv, tout1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
n2l(in, tin0);
n2l(in, tin1);
tin0 ^= tout0; tin[0] = tin0;
tin1 ^= tout1; tin[1] = tin1;
BF_encrypt(tin, key, BF_ENCRYPT);
tout0 = tin[0]; l2n(tout0, out);
tout1 = tin[1]; l2n(tout1, out);
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
} else if (mode == BF_DECRYPT) {
register BF_LONG xor0, xor1;
u_int8_t *in, *out;
xor0 = xor1 = 0;
n2l(iv, xor0);
n2l(iv, xor1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
n2l(in, tin0); tin[0] = tin0;
n2l(in, tin1); tin[1] = tin1;
BF_encrypt(tin, key, BF_DECRYPT);
tout0 = tin[0] ^ xor0;
tout1 = tin[1] ^ xor1;
l2n(tout0, out);
l2n(tout1, out);
xor0 = tin0;
xor1 = tin1;
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}
}

View File

@ -0,0 +1,142 @@
/* crypto/bf/bf_enc.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
* (From LECTURE NOTES IN COIMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
* CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
*/
#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
If you set BF_ROUNDS to some value other than 16 or 20, you will have
to modify the code.
#endif
void BF_encrypt(data,key,encrypt)
BF_LONG *data;
BF_KEY *key;
int encrypt;
{
register BF_LONG l,r,*p,*s;
p=key->P;
s= &(key->S[0]);
l=data[0];
r=data[1];
if (encrypt)
{
l^=p[0];
BF_ENC(r,l,s,p[ 1]);
BF_ENC(l,r,s,p[ 2]);
BF_ENC(r,l,s,p[ 3]);
BF_ENC(l,r,s,p[ 4]);
BF_ENC(r,l,s,p[ 5]);
BF_ENC(l,r,s,p[ 6]);
BF_ENC(r,l,s,p[ 7]);
BF_ENC(l,r,s,p[ 8]);
BF_ENC(r,l,s,p[ 9]);
BF_ENC(l,r,s,p[10]);
BF_ENC(r,l,s,p[11]);
BF_ENC(l,r,s,p[12]);
BF_ENC(r,l,s,p[13]);
BF_ENC(l,r,s,p[14]);
BF_ENC(r,l,s,p[15]);
BF_ENC(l,r,s,p[16]);
#if BF_ROUNDS == 20
BF_ENC(r,l,s,p[17]);
BF_ENC(l,r,s,p[18]);
BF_ENC(r,l,s,p[19]);
BF_ENC(l,r,s,p[20]);
#endif
r^=p[BF_ROUNDS+1];
}
else
{
l^=p[BF_ROUNDS+1];
#if BF_ROUNDS == 20
BF_ENC(r,l,s,p[20]);
BF_ENC(l,r,s,p[19]);
BF_ENC(r,l,s,p[18]);
BF_ENC(l,r,s,p[17]);
#endif
BF_ENC(r,l,s,p[16]);
BF_ENC(l,r,s,p[15]);
BF_ENC(r,l,s,p[14]);
BF_ENC(l,r,s,p[13]);
BF_ENC(r,l,s,p[12]);
BF_ENC(l,r,s,p[11]);
BF_ENC(r,l,s,p[10]);
BF_ENC(l,r,s,p[ 9]);
BF_ENC(r,l,s,p[ 8]);
BF_ENC(l,r,s,p[ 7]);
BF_ENC(r,l,s,p[ 6]);
BF_ENC(l,r,s,p[ 5]);
BF_ENC(r,l,s,p[ 4]);
BF_ENC(l,r,s,p[ 3]);
BF_ENC(r,l,s,p[ 2]);
BF_ENC(l,r,s,p[ 1]);
r^=p[0];
}
data[1]=l&0xffffffff;
data[0]=r&0xffffffff;
}

View File

@ -0,0 +1,217 @@
/* crypto/bf/bf_local.h */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify bf_locl.org since bf_locl.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
#undef c2l
#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
l|=((unsigned long)(*((c)++)))<< 8L, \
l|=((unsigned long)(*((c)++)))<<16L, \
l|=((unsigned long)(*((c)++)))<<24L)
/* NOTE - c is not incremented as per c2l */
#undef c2ln
#define c2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
case 5: l2|=((unsigned long)(*(--(c)))); \
case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
case 1: l1|=((unsigned long)(*(--(c)))); \
} \
}
#undef l2c
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>>24L)&0xff))
/* NOTE - c is not incremented as per l2c */
#undef l2cn
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
/* NOTE - c is not incremented as per n2l */
#define n2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((unsigned long)(*(--(c)))) ; \
case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
case 6: l2|=((unsigned long)(*(--(c))))<<16; \
case 5: l2|=((unsigned long)(*(--(c))))<<24; \
case 4: l1 =((unsigned long)(*(--(c)))) ; \
case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
case 2: l1|=((unsigned long)(*(--(c))))<<16; \
case 1: l1|=((unsigned long)(*(--(c))))<<24; \
} \
}
/* NOTE - c is not incremented as per l2n */
#define l2nn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
} \
}
#undef n2l
#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \
l|=((unsigned long)(*((c)++)))<<16L, \
l|=((unsigned long)(*((c)++)))<< 8L, \
l|=((unsigned long)(*((c)++))))
#undef l2n
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* This is actually a big endian algorithm, the most significate byte
* is used to lookup array 0 */
/* use BF_PTR2 for intel boxes,
* BF_PTR for sparc and MIPS/SGI
* use nothing for Alpha and HP.
*/
#if !defined(BF_PTR) && !defined(BF_PTR2)
#undef BF_PTR
#endif
#define BF_M 0x3fc
#define BF_0 22L
#define BF_1 14L
#define BF_2 6L
#define BF_3 2L /* left shift */
#if defined(BF_PTR2)
/* This is basically a special pentium verson */
#define BF_ENC(LL,R,S,P) \
{ \
BF_LONG t,u,v; \
u=R>>BF_0; \
v=R>>BF_1; \
u&=BF_M; \
v&=BF_M; \
t= *(BF_LONG *)((unsigned char *)&(S[ 0])+u); \
u=R>>BF_2; \
t+= *(BF_LONG *)((unsigned char *)&(S[256])+v); \
v=R<<BF_3; \
u&=BF_M; \
v&=BF_M; \
t^= *(BF_LONG *)((unsigned char *)&(S[512])+u); \
LL^=P; \
t+= *(BF_LONG *)((unsigned char *)&(S[768])+v); \
LL^=t; \
}
#elif defined(BF_PTR)
/* This is normally very good */
#define BF_ENC(LL,R,S,P) \
LL^=P; \
LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \
*(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
*(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M)));
#else
/* This will always work, even on 64 bit machines and strangly enough,
* on the Alpha it is faster than the pointer versions (both 32 and 64
* versions of BF_LONG) */
#define BF_ENC(LL,R,S,P) \
LL^=P; \
LL^=((( S[ (R>>24L) ] + \
S[0x0100+((R>>16L)&0xff)])^ \
S[0x0200+((R>> 8L)&0xff)])+ \
S[0x0300+((R )&0xff)])&0xffffffff;
#endif

327
sys/crypto/blowfish/bf_pi.h Normal file
View File

@ -0,0 +1,327 @@
/* crypto/bf/bf_pi.h */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
static BF_KEY bf_init= {
{
0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
0x9216d5d9L, 0x8979fb1b
},{
0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L,
0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L,
0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L,
0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL,
0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL,
0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L,
0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL,
0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL,
0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L,
0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L,
0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL,
0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL,
0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL,
0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L,
0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L,
0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L,
0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L,
0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L,
0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL,
0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L,
0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L,
0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L,
0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L,
0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL,
0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L,
0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL,
0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL,
0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L,
0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL,
0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L,
0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL,
0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L,
0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L,
0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL,
0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L,
0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L,
0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL,
0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L,
0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL,
0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L,
0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L,
0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL,
0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L,
0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L,
0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L,
0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L,
0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L,
0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL,
0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL,
0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L,
0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L,
0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L,
0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L,
0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL,
0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L,
0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL,
0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL,
0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L,
0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L,
0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L,
0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L,
0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L,
0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L,
0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL,
0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L,
0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L,
0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L,
0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL,
0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L,
0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L,
0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL,
0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L,
0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L,
0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L,
0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL,
0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL,
0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L,
0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L,
0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L,
0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L,
0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL,
0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL,
0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL,
0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L,
0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL,
0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L,
0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L,
0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL,
0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL,
0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L,
0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL,
0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L,
0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL,
0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL,
0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L,
0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L,
0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L,
0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L,
0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L,
0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L,
0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L,
0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL,
0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L,
0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL,
0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L,
0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L,
0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L,
0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L,
0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L,
0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L,
0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L,
0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L,
0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L,
0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L,
0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L,
0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L,
0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L,
0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L,
0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L,
0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L,
0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL,
0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL,
0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L,
0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL,
0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L,
0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L,
0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L,
0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L,
0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L,
0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L,
0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL,
0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L,
0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L,
0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L,
0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL,
0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL,
0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL,
0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L,
0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L,
0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL,
0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L,
0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL,
0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L,
0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL,
0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L,
0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL,
0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L,
0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL,
0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L,
0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L,
0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL,
0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L,
0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L,
0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L,
0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L,
0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL,
0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L,
0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL,
0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L,
0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL,
0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L,
0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL,
0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL,
0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL,
0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L,
0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L,
0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL,
0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL,
0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL,
0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL,
0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL,
0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L,
0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L,
0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L,
0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L,
0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL,
0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL,
0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L,
0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L,
0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L,
0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L,
0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L,
0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L,
0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L,
0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L,
0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L,
0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L,
0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL,
0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L,
0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL,
0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L,
0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L,
0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL,
0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL,
0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL,
0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L,
0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L,
0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L,
0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L,
0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L,
0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L,
0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L,
0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L,
0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L,
0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L,
0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L,
0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L,
0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL,
0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL,
0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L,
0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL,
0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL,
0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL,
0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L,
0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL,
0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL,
0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L,
0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L,
0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L,
0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L,
0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL,
0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL,
0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L,
0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L,
0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L,
0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL,
0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L,
0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L,
0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L,
0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL,
0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L,
0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L,
0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L,
0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL,
0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL,
0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L,
0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L,
0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L,
0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L,
0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL,
0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L,
0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL,
0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL,
0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L,
0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L,
0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL,
0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L,
0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL,
0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L,
0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL,
0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L,
0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L,
0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL,
0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L,
0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL,
0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L,
}
};

View File

@ -0,0 +1,122 @@
/* crypto/bf/bf_skey.c */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <crypto/blowfish/blowfish.h>
#include <crypto/blowfish/bf_locl.h>
#include <crypto/blowfish/bf_pi.h>
void BF_set_key(key,len,data)
BF_KEY *key;
int len;
unsigned char *data;
{
int i;
BF_LONG *p,ri,in[2];
unsigned char *d,*end;
memcpy((char *)key,(char *)&bf_init,sizeof(BF_KEY));
p=key->P;
if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
d=data;
end= &(data[len]);
for (i=0; i<(BF_ROUNDS+2); i++)
{
ri= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
ri<<=8;
ri|= *(d++);
if (d >= end) d=data;
p[i]^=ri;
}
in[0]=0L;
in[1]=0L;
for (i=0; i<(BF_ROUNDS+2); i+=2)
{
BF_encrypt(in,key,BF_ENCRYPT);
p[i ]=in[0];
p[i+1]=in[1];
}
p=key->S;
for (i=0; i<4*256; i+=2)
{
BF_encrypt(in,key,BF_ENCRYPT);
p[i ]=in[0];
p[i+1]=in[1];
}
}

View File

@ -0,0 +1,124 @@
/* crypto/bf/blowfish.h */
/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@mincom.oz.au).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@mincom.oz.au)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#ifndef HEADER_BLOWFISH_H
#define HEADER_BLOWFISH_H
#ifdef __cplusplus
extern "C" {
#endif
#define BF_ENCRYPT 1
#define BF_DECRYPT 0
/* If you make this 'unsigned int' the pointer variants will work on
* the Alpha, otherwise they will not. Strangly using the '8 byte'
* BF_LONG and the default 'non-pointer' inner loop is the best configuration
* for the Alpha */
#define BF_LONG unsigned long
#define BF_ROUNDS 16
#define BF_BLOCK 8
typedef struct bf_key_st
{
BF_LONG P[BF_ROUNDS+2];
BF_LONG S[4*256];
} BF_KEY;
#ifndef NOPROTO
void BF_set_key(BF_KEY *key, int len, unsigned char *data);
void BF_ecb_encrypt(unsigned char *in,unsigned char *out,BF_KEY *key,
int encrypt);
void BF_encrypt(BF_LONG *data,BF_KEY *key,int encrypt);
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *ks, unsigned char *iv, int encrypt);
void BF_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *schedule, unsigned char *ivec, int *num, int encrypt);
void BF_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
BF_KEY *schedule, unsigned char *ivec, int *num);
char *BF_options(void);
/* added by itojun */
struct mbuf;
void BF_cbc_encrypt_m(struct mbuf *, int, int, BF_KEY *,
unsigned char *, int);
#else
void BF_set_key();
void BF_ecb_encrypt();
void BF_encrypt();
void BF_cbc_encrypt();
void BF_cfb64_encrypt();
void BF_ofb64_encrypt();
char *BF_options();
/* added by itojun */
void BF_cbc_encrypt_m();
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,873 @@
/*
* heavily modified by Tomomi Suzuki <suzuki@grelot.elec.ryukoku.ac.jp>
*/
/*
* The CAST-128 Encryption Algorithm (RFC 2144)
*
* original implementation <Hideo "Sir MaNMOS" Morisita>
* 1997/08/21
*/
/*
* Copyright (C) 1997 Hideo "Sir MANMOS" Morishita
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Hideo "Sir MaNMOS" Morishita ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Hideo "Sir MaNMOS" Morishita BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <crypto/cast128/cast128.h>
#include <crypto/cast128/cast128_subkey.h>
static u_int32_t S1[];
static u_int32_t S2[];
static u_int32_t S3[];
static u_int32_t S4[];
static u_int32_t S5[];
static u_int32_t S6[];
static u_int32_t S7[];
static u_int32_t S8[];
/*
* Step 1
*/
void set_cast128_subkey(u_int32_t *subkey, u_int8_t *key)
{
u_int32_t buf[8]; /* for x0x1x2x3, x4x5x6x7 ..., z0z1z2z3, ... */
buf[0] = (key[ 0] << 24) | (key[ 1] << 16) | (key[ 2] << 8)
| key[ 3];
buf[1] = (key[ 4] << 24) | (key[ 5] << 16) | (key[ 6] << 8)
| key[ 7];
buf[2] = (key[ 8] << 24) | (key[ 9] << 16) | (key[10] << 8)
| key[11];
buf[3] = (key[12] << 24) | (key[13] << 16) | (key[14] << 8)
| key[15];
/* masking subkey */
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
subkey[0] = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2];
subkey[1] = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6];
subkey[2] = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9];
subkey[3] = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC];
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
subkey[4] = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8];
subkey[5] = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD];
subkey[6] = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3];
subkey[7] = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7];
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
subkey[8] = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9];
subkey[9] = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC];
subkey[10] = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2];
subkey[11] = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6];
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
subkey[12] = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3];
subkey[13] = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7];
subkey[14] = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8];
subkey[15] = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD];
/* rotate subkey (least significast 5 bits) */
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
subkey[16] = (S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]) & 0x1f;
subkey[17] = (S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]) & 0x1f;
subkey[18] = (S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]) & 0x1f;
subkey[19] = (S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]) & 0x1f;
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
subkey[20] = (S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]) & 0x1f;
subkey[21] = (S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]) & 0x1f;
subkey[22] = (S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]) & 0x1f;
subkey[23] = (S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]) & 0x1f;
z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];
z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];
z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];
zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];
subkey[24] = (S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]) & 0x1f;
subkey[25] = (S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]) & 0x1f;
subkey[26] = (S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]) & 0x1f;
subkey[27] = (S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]) & 0x1f;
x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];
x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];
x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];
xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];
subkey[28] = (S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]) & 0x1f;
subkey[29] = (S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]) & 0x1f;
subkey[30] = (S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]) & 0x1f;
subkey[31] = (S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]) & 0x1f;
}
#define CAST128_TYPE1(rc, d, km, kr) { \
u_int32_t x = circular_leftshift(((km)+(d)), (kr)); \
(rc) = ((S1[byte0(x)] ^ S2[byte1(x)]) - S3[byte2(x)]) + S4[byte3(x)]; \
}
#define CAST128_TYPE2(rc, d, km, kr) { \
u_int32_t x = circular_leftshift(((km)^(d)), (kr)); \
(rc) = ((S1[byte0(x)] - S2[byte1(x)]) + S3[byte2(x)]) ^ S4[byte3(x)]; \
}
#define CAST128_TYPE3(rc, d, km, kr) { \
u_int32_t x = circular_leftshift(((km)-(d)), (kr)); \
(rc) = ((S1[byte0(x)] + S2[byte1(x)]) ^ S3[byte2(x)]) - S4[byte3(x)]; \
}
void cast128_encrypt_round16(u_int8_t *c, const u_int8_t *m,
u_int32_t *subkey)
{
u_int32_t l; /* left 32bit */
u_int32_t r; /* right 32bit */
u_int32_t br; /* backup right 32bit */
u_int32_t rc; /* result code of CAST128_TYPE?() */
u_int32_t *km, *kr;
/* Step 2 */
l = (m[0] << 24) | (m[1] << 16) | (m[2] << 8) | m[3];
r = (m[4] << 24) | (m[5] << 16) | (m[6] << 8) | m[7];
/* Step 3 */
km = subkey;
kr = subkey + 16;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br;
/* Step 4 */
c[0] = (r >> 24) & 0xff;
c[1] = (r >> 16) & 0xff;
c[2] = (r >> 8) & 0xff;
c[3] = r & 0xff;
c[4] = (l >> 24) & 0xff;
c[5] = (l >> 16) & 0xff;
c[6] = (l >> 8) & 0xff;
c[7] = l & 0xff;
}
void cast128_decrypt_round16(u_int8_t *m, const u_int8_t *c,
u_int32_t *subkey)
{
u_int32_t l; /* left 32bit */
u_int32_t r; /* right 32bit */
u_int32_t bl; /* backup left 32bit */
u_int32_t rc; /* result code of CAST128_TYPE?() */
u_int32_t *km, *kr;
/* Step 2 */
r = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
l = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | c[7];
/* Step 3 */
km = subkey + 15;
kr = subkey + 31;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl;
/* Step 4 */
m[0] = (l >> 24) & 0xff;
m[1] = (l >> 16) & 0xff;
m[2] = (l >> 8) & 0xff;
m[3] = l & 0xff;
m[4] = (r >> 24) & 0xff;
m[5] = (r >> 16) & 0xff;
m[6] = (r >> 8) & 0xff;
m[7] = r & 0xff;
}
void cast128_encrypt_round12(u_int8_t *c, const u_int8_t *m,
u_int32_t *subkey)
{
u_int32_t l; /* left 32bit */
u_int32_t r; /* right 32bit */
u_int32_t br; /* backup right 32bit */
u_int32_t rc; /* result code of CAST128_TYPE?() */
u_int32_t *km, *kr;
/* Step 2 */
l = (m[0] << 24) | (m[1] << 16) | (m[2] << 8) | m[3];
r = (m[4] << 24) | (m[5] << 16) | (m[6] << 8) | m[7];
/* Step 3 */
km = subkey;
kr = subkey + 16;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE1(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE2(rc, r, *km, *kr); r = l ^ rc; l = br; km++; kr++;
br = r; CAST128_TYPE3(rc, r, *km, *kr); r = l ^ rc; l = br;
/* Step 4 */
c[0] = (r >> 24) & 0xff;
c[1] = (r >> 16) & 0xff;
c[2] = (r >> 8) & 0xff;
c[3] = r & 0xff;
c[4] = (l >> 24) & 0xff;
c[5] = (l >> 16) & 0xff;
c[6] = (l >> 8) & 0xff;
c[7] = l & 0xff;
}
void cast128_decrypt_round12(u_int8_t *m, const u_int8_t *c,
u_int32_t *subkey)
{
u_int32_t l; /* left 32bit */
u_int32_t r; /* right 32bit */
u_int32_t bl; /* backup left 32bit */
u_int32_t rc; /* result code of CAST128_TYPE?() */
u_int32_t *km, *kr;
/* Step 2 */
r = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
l = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | c[7];
/* Step 3 */
km = subkey + 11;
kr = subkey + 27;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE3(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE2(rc, l, *km, *kr); l = r ^ rc; r = bl; km--; kr--;
bl = l; CAST128_TYPE1(rc, l, *km, *kr); l = r ^ rc; r = bl;
/* Step 4 */
m[0] = (l >> 24) & 0xff;
m[1] = (l >> 16) & 0xff;
m[2] = (l >> 8) & 0xff;
m[3] = l & 0xff;
m[4] = (r >> 24) & 0xff;
m[5] = (r >> 16) & 0xff;
m[6] = (r >> 8) & 0xff;
m[7] = r & 0xff;
}
static u_int32_t S1[] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a,
0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2,
0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f,
0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f,
0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d,
0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272,
0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d,
0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f,
0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9,
0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9,
0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e,
0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82,
0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac,
0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491,
0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de,
0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79,
0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779,
0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb,
0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0,
0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298,
0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571,
0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
};
static u_int32_t S2[] = {
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380,
0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909,
0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b,
0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f,
0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21,
0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f,
0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d,
0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801,
0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755,
0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b,
0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c,
0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3,
0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9,
0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4,
0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43,
0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171,
0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89,
0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb,
0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e,
0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea,
0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd,
0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
};
static u_int32_t S3[] = {
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907,
0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e,
0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc,
0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f,
0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99,
0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380,
0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8,
0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6,
0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e,
0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1,
0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c,
0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4,
0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b,
0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231,
0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889,
0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49,
0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d,
0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e,
0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767,
0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24,
0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0,
0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
};
static u_int32_t S4[] = {
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298,
0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220,
0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe,
0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b,
0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93,
0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9,
0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb,
0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7,
0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340,
0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec,
0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205,
0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5,
0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c,
0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9,
0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff,
0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2,
0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff,
0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df,
0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf,
0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c,
0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43,
0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
};
static u_int32_t S5[] = {
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911,
0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180,
0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2,
0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b,
0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571,
0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea,
0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263,
0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b,
0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284,
0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7,
0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce,
0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4,
0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561,
0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406,
0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472,
0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288,
0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2,
0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76,
0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0,
0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2,
0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be,
0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
};
static u_int32_t S6[] = {
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c,
0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e,
0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866,
0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd,
0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53,
0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf,
0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807,
0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563,
0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0,
0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0,
0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2,
0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa,
0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9,
0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358,
0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397,
0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4,
0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f,
0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2,
0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab,
0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b,
0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855,
0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
};
static u_int32_t S7[] = {
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693,
0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd,
0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f,
0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e,
0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83,
0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a,
0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f,
0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78,
0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d,
0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9,
0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302,
0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a,
0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4,
0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9,
0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c,
0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939,
0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e,
0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd,
0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567,
0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf,
0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2,
0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
};
static u_int32_t S8[] = {
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095,
0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940,
0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42,
0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4,
0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0,
0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491,
0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b,
0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006,
0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564,
0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc,
0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8,
0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f,
0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504,
0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6,
0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd,
0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc,
0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba,
0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603,
0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37,
0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d,
0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347,
0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
};

View File

@ -0,0 +1,62 @@
/*
* heavily modified by Tomomi Suzuki <suzuki@grelot.elec.ryukoku.ac.jp>
*/
/*
* The CAST-128 Encryption Algorithm (RFC 2144)
*
* original implementation <Hideo "Sir MaNMOS" Morisita>
* 1997/08/21
*/
/*
* Copyright (C) 1997 Hideo "Sir MANMOS" Morishita
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Hideo "Sir MaNMOS" Morishita ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Hideo "Sir MaNMOS" Morishita BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef RFC2144_CAST_128_H
#define RFC2144_CAST_128_H
#include <sys/param.h>
#include <sys/mbuf.h>
#define CAST128_ENCRYPT 1
#define CAST128_DECRYPT 0
extern void set_cast128_subkey __P((u_int32_t *, u_int8_t *));
extern void cast128_encrypt_round16 __P((u_int8_t *, const u_int8_t *,
u_int32_t *));
extern void cast128_decrypt_round16 __P((u_int8_t *, const u_int8_t *,
u_int32_t *));
extern void cast128_encrypt_round12 __P((u_int8_t *, const u_int8_t *,
u_int32_t *));
extern void cast128_decrypt_round12 __P((u_int8_t *, const u_int8_t *,
u_int32_t *));
extern void cast128_cbc_process __P((struct mbuf *, size_t, size_t,
u_int32_t *, u_int8_t *, size_t, int));
#endif

View File

@ -0,0 +1,219 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <crypto/cast128/cast128.h>
void
cast128_cbc_process(m0, skip, length, subkey, iv, keylen, mode)
struct mbuf *m0;
size_t skip;
size_t length;
u_int32_t *subkey;
u_int8_t *iv;
size_t keylen;
int mode;
{
struct mbuf *m;
u_int8_t inbuf[8], outbuf[8];
size_t off;
/* sanity check */
if (m0->m_pkthdr.len < skip) {
printf("cast128_cbc_process: mbuf length < skip\n");
return;
}
if (m0->m_pkthdr.len < length) {
printf("cast128_cbc_process: mbuf length < encrypt length\n");
return;
}
if (m0->m_pkthdr.len < skip + length) {
printf("cast128_cbc_process: "
"mbuf length < skip + encrypt length\n");
return;
}
if (length % 8) {
printf("cast128_cbc_process: length is not multiple of 8\n");
return;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("cast128_cbc_process: mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* copy iv into outbuf for XOR (encrypt) */
bcopy(iv, outbuf, 8);
/*
* encrypt/decrypt packet
*/
while (length > 0) {
int i;
if (!m)
panic("cast128_cbc_process: mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them
* later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *)+off, inbuf, 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p, *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = inbuf;
while (in - inbuf < 8) {
if (!p) {
panic("cast128_cbc_process: "
"mbuf chain?\n");
}
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *);
else
p = NULL;
}
}
/* encrypt/decrypt */
switch (mode) {
case CAST128_ENCRYPT:
/* XOR */
for (i = 0; i < 8; i++)
inbuf[i] ^= outbuf[i];
/* encrypt */
if (keylen <= 80/8)
cast128_encrypt_round12(outbuf, inbuf, subkey);
else
cast128_encrypt_round16(outbuf, inbuf, subkey);
break;
case CAST128_DECRYPT:
/* decrypt */
if (keylen <= 80/8)
cast128_decrypt_round12(outbuf, inbuf, subkey);
else
cast128_decrypt_round16(outbuf, inbuf, subkey);
/* XOR */
for (i = 0; i < 8; i++)
outbuf[i] ^= iv[i];
/* copy inbuf into iv for next XOR */
bcopy(inbuf, iv, 8);
break;
}
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(outbuf, mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(outbuf, mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && !m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p, *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = outbuf;
while (out - outbuf < 8) {
if (!p) {
panic("cast128_cbc_process: "
"mbuf chain?\n");
}
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *);
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}

View File

@ -0,0 +1,91 @@
/*
* heavily modified by Tomomi Suzuki <suzuki@grelot.elec.ryukoku.ac.jp>
*/
/*
* The CAST-128 Encryption Algorithm (RFC 2144)
*
* original implementation <Hideo "Sir MaNMOS" Morisita>
* 1997/08/21
*/
/*
* Copyright (C) 1997 Hideo "Sir MANMOS" Morishita
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Hideo "Sir MaNMOS" Morishita ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Hideo "Sir MaNMOS" Morishita BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef RFC2144_CAST_128_SUBKEY_H
#define RFC2144_CAST_128_SUBKEY_H
#define x0x1x2x3 buf[0]
#define x4x5x6x7 buf[1]
#define x8x9xAxB buf[2]
#define xCxDxExF buf[3]
#define z0z1z2z3 buf[4]
#define z4z5z6z7 buf[5]
#define z8z9zAzB buf[6]
#define zCzDzEzF buf[7]
#define byte0(x) (((x) >> 24))
#define byte1(x) (((x) >> 16) & 0xff)
#define byte2(x) (((x) >> 8) & 0xff)
#define byte3(x) (((x)) & 0xff)
#define x0 byte0(buf[0])
#define x1 byte1(buf[0])
#define x2 byte2(buf[0])
#define x3 byte3(buf[0])
#define x4 byte0(buf[1])
#define x5 byte1(buf[1])
#define x6 byte2(buf[1])
#define x7 byte3(buf[1])
#define x8 byte0(buf[2])
#define x9 byte1(buf[2])
#define xA byte2(buf[2])
#define xB byte3(buf[2])
#define xC byte0(buf[3])
#define xD byte1(buf[3])
#define xE byte2(buf[3])
#define xF byte3(buf[3])
#define z0 byte0(buf[4])
#define z1 byte1(buf[4])
#define z2 byte2(buf[4])
#define z3 byte3(buf[4])
#define z4 byte0(buf[5])
#define z5 byte1(buf[5])
#define z6 byte2(buf[5])
#define z7 byte3(buf[5])
#define z8 byte0(buf[6])
#define z9 byte1(buf[6])
#define zA byte2(buf[6])
#define zB byte3(buf[6])
#define zC byte0(buf[7])
#define zD byte1(buf[7])
#define zE byte2(buf[7])
#define zF byte3(buf[7])
#define circular_leftshift(x, y) ( ((x) << (y)) | ((x) >> (32-(y))) )
#endif

280
sys/crypto/des/des.h Normal file
View File

@ -0,0 +1,280 @@
/* lib/des/des.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#ifndef HEADER_DES_H
#define HEADER_DES_H
#ifdef __cplusplus
extern "C" {
#endif
/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
* %20 speed up (longs are 8 bytes, int's are 4). */
#ifndef DES_LONG
#define DES_LONG unsigned long
#endif
typedef unsigned char des_cblock[8];
typedef struct des_ks_struct
{
union {
des_cblock _;
/* make sure things are correct size on machines with
* 8 byte longs */
DES_LONG pad[2];
} ks;
#undef _
#define _ ks._
} des_key_schedule[16];
#define DES_KEY_SZ (sizeof(des_cblock))
#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
#define DES_CBC_MODE 0
#define DES_PCBC_MODE 1
#define des_ecb2_encrypt(i,o,k1,k2,e) \
des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
#define C_Block des_cblock
#define Key_schedule des_key_schedule
#ifdef KERBEROS
#define ENCRYPT DES_ENCRYPT
#define DECRYPT DES_DECRYPT
#endif
#define KEY_SZ DES_KEY_SZ
#define string_to_key des_string_to_key
#define read_pw_string des_read_pw_string
#define random_key des_random_key
#define pcbc_encrypt des_pcbc_encrypt
#define set_key des_set_key
#define key_sched des_key_sched
#define ecb_encrypt des_ecb_encrypt
#define cbc_encrypt des_cbc_encrypt
#define ncbc_encrypt des_ncbc_encrypt
#define xcbc_encrypt des_xcbc_encrypt
#define cbc_cksum des_cbc_cksum
#define quad_cksum des_quad_cksum
/* For compatibility with the MIT lib - eay 20/05/92 */
typedef des_key_schedule bit_64;
#define des_fixup_key_parity des_set_odd_parity
#define des_check_key_parity check_parity
extern int des_check_key; /* defaults to false */
extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
/* The next line is used to disable full ANSI prototypes, if your
* compiler has problems with the prototypes, make sure this line always
* evaluates to true :-) */
#if defined(MSDOS) || defined(__STDC__)
#undef NOPROTO
#endif
#ifndef NOPROTO
char *des_options(void);
void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
des_key_schedule ks1,des_key_schedule ks2,
des_key_schedule ks3, int enc);
DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
long length,des_key_schedule schedule,des_cblock *ivec);
/*
void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
*/
void des_cbc_encrypt(struct mbuf *, size_t, size_t,
des_key_schedule schedule,des_cblock *ivec, int enc);
void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,
des_cblock *inw,des_cblock *outw,int enc);
void des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule sk1,des_key_schedule sk2,
des_cblock *ivec1,des_cblock *ivec2,int enc);
extern void des_3cbc_process(struct mbuf *, size_t, size_t,
des_key_schedule *schedule, des_cblock *ivec, int mode);
void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
long length,des_key_schedule schedule,des_cblock *ivec,int enc);
void des_ecb_encrypt(des_cblock *input,des_cblock *output,
des_key_schedule ks,int enc);
void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int enc);
void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int *num, int encrypt);
void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
long length, des_key_schedule ks1, des_key_schedule ks2,
des_key_schedule ks3, des_cblock *ivec, int *num);
int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
#ifdef PERL5
char *des_crypt(const char *buf,const char *salt);
#else
/* some stupid compilers complain because I have declared char instead
* of const char */
#if 1
char *crypt(const char *buf,const char *salt);
#else
char *crypt();
#endif
#endif
void des_ofb_encrypt(unsigned char *in,unsigned char *out,
int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
des_key_schedule schedule,des_cblock *ivec,int enc);
DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
long length,int out_count,des_cblock *seed);
void des_random_seed(des_cblock key);
void des_random_key(des_cblock ret);
int des_read_password(des_cblock *key,char *prompt,int verify);
int des_read_2passwords(des_cblock *key1,des_cblock *key2,
char *prompt,int verify);
int des_read_pw_string(char *buf,int length,char *prompt,int verify);
void des_set_odd_parity(des_cblock *key);
int des_is_weak_key(des_cblock *key);
int des_set_key(des_cblock *key,des_key_schedule schedule);
int des_key_sched(des_cblock *key,des_key_schedule schedule);
void des_string_to_key(char *str,des_cblock *key);
void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
des_key_schedule schedule, des_cblock *ivec, int *num);
/* Extra functions from Mark Murray <mark@grondar.za> */
/*
void des_cblock_print_file(des_cblock *cb, FILE *fp);
*/
/* The following functions are not in the normal unix build or the
* SSLeay build. When using the SSLeay build, use RAND_seed()
* and RAND_bytes() instead. */
int des_new_random_key(des_cblock *key);
void des_init_random_number_generator(des_cblock *key);
void des_set_random_generator_seed(des_cblock *key);
void des_set_sequence_number(des_cblock new_sequence_number);
void des_generate_random_block(des_cblock *block);
#else
char *des_options();
void des_ecb3_encrypt();
DES_LONG des_cbc_cksum();
void des_cbc_encrypt();
void des_ncbc_encrypt();
void des_xcbc_encrypt();
void des_3cbc_encrypt();
void des_cfb_encrypt();
void des_ede3_cfb64_encrypt();
void des_ede3_ofb64_encrypt();
void des_ecb_encrypt();
void des_encrypt();
void des_encrypt2();
void des_ede3_cbc_encrypt();
int des_enc_read();
int des_enc_write();
#ifdef PERL5
char *des_crypt();
#else
char *crypt();
#endif
void des_ofb_encrypt();
void des_pcbc_encrypt();
DES_LONG des_quad_cksum();
void des_random_seed();
void des_random_key();
int des_read_password();
int des_read_2passwords();
int des_read_pw_string();
void des_set_odd_parity();
int des_is_weak_key();
int des_set_key();
int des_key_sched();
void des_string_to_key();
void des_string_to_2keys();
void des_cfb64_encrypt();
void des_ofb64_encrypt();
/* Extra functions from Mark Murray <mark@grondar.za> */
void des_cblock_print_file();
/* The following functions are not in the normal unix build or the
* SSLeay build. When using the SSLeay build, use RAND_seed()
* and RAND_bytes() instead. */
#ifdef FreeBSD
int des_new_random_key();
void des_init_random_number_generator();
void des_set_random_generator_seed();
void des_set_sequence_number();
void des_generate_random_block();
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

246
sys/crypto/des/des_3cbc.c Normal file
View File

@ -0,0 +1,246 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
*/
#include <crypto/des/des_locl.h>
void des_3cbc_process(m0, skip, length, schedule, ivec, mode)
struct mbuf *m0;
size_t skip;
size_t length;
des_key_schedule *schedule;
des_cblock (*ivec);
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
DES_LONG tin0, tin1;
DES_LONG tout0, tout1;
DES_LONG tin[2];
DES_LONG xor0 = 0, xor1 = 0;
u_int8_t *iv;
u_int8_t *in, *out;
/* sanity check */
if (m0->m_pkthdr.len < skip) {
printf("des_3cbc_process: mbuf length < skip\n");
return;
}
if (m0->m_pkthdr.len < length) {
printf("des_3cbc_process: mbuf length < encrypt length\n");
return;
}
if (m0->m_pkthdr.len < skip + length) {
printf("des_3cbc_process: mbuf length < "
"skip + encrypt length\n");
return;
}
if (length % 8) {
printf("des_3cbc_process: length(%lu) is not multiple of 8\n",
(u_long)length);
return;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("des_3cbc_process: mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* initialize */
tin0 = tin1 = tout0 = tout1 = 0;
tin[0] = tin[1] = 0;
switch (mode) {
case DES_ENCRYPT:
iv = (u_int8_t *)ivec;
c2l(iv, tout0);
c2l(iv, tout1);
break;
case DES_DECRYPT:
xor0 = xor1 = 0;
iv = (u_int8_t *)ivec;
c2l(iv, xor0);
c2l(iv, xor1);
break;
}
/*
* encrypt/decrypt packet
*/
while (length > 0) {
if (!m)
panic("des_3cbc_process: mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them
* later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p) {
panic("des_3cbc_process: "
"mbuf chain?\n");
}
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
/* encrypt/decrypt */
switch (mode) {
case DES_ENCRYPT:
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0);
c2l(in, tin1);
/* XOR */
tin0 ^= tout0; tin[0] = tin0;
tin1 ^= tout1; tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule[0], DES_ENCRYPT);
des_encrypt((DES_LONG *)tin, schedule[1], DES_DECRYPT);
des_encrypt((DES_LONG *)tin, schedule[2], DES_ENCRYPT);
tout0 = tin[0]; l2c(tout0, out);
tout1 = tin[1]; l2c(tout1, out);
break;
case DES_DECRYPT:
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0); tin[0] = tin0;
c2l(in, tin1); tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule[2], DES_DECRYPT);
des_encrypt((DES_LONG *)tin, schedule[1], DES_ENCRYPT);
des_encrypt((DES_LONG *)tin, schedule[0], DES_DECRYPT);
/* XOR */
tout0 = tin[0] ^ xor0;
tout1 = tin[1] ^ xor1;
l2c(tout0, out);
l2c(tout1, out);
/* for next iv */
xor0 = tin0;
xor1 = tin1;
break;
}
/*
* copy the output buffer int the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && !m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p) {
panic("des_3cbc_process: "
"mbuf chain?\n");
}
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}

328
sys/crypto/des/des_cbc.c Normal file
View File

@ -0,0 +1,328 @@
/*
* heavily modified by Yoshifumi Nishida <nishida@sfc.wide.ad.jp>.
* then, completely rewrote by Jun-ichiro itojun Itoh <itojun@itojun.org>,
* 1997.
*/
/* crypto/des/cbc_enc.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#include <crypto/des/des_locl.h>
#define panic(x) {printf(x); return;}
void des_cbc_encrypt(m0, skip, length, schedule, ivec, mode)
struct mbuf *m0;
size_t skip;
size_t length;
des_key_schedule schedule;
des_cblock (*ivec);
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
register DES_LONG tin0, tin1;
register DES_LONG tout0, tout1;
DES_LONG tin[2];
u_int8_t *iv;
/* sanity checks */
if (m0->m_pkthdr.len < skip) {
printf("mbuf length < skip\n");
return;
}
if (m0->m_pkthdr.len < length) {
printf("mbuf length < encrypt length\n");
return;
}
if (m0->m_pkthdr.len < skip + length) {
printf("mbuf length < skip + encrypt length\n");
return;
}
if (length % 8) {
printf("length is not multiple of 8\n");
return;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* initialize */
tin0 = tin1 = tout0 = tout1 = 0;
tin[0] = tin[1] = 0;
if (mode == DES_ENCRYPT) {
u_int8_t *in, *out;
iv = (u_int8_t *)ivec;
c2l(iv, tout0);
c2l(iv, tout1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0);
c2l(in, tin1);
tin0 ^= tout0; tin[0] = tin0;
tin1 ^= tout1; tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule, DES_ENCRYPT);
tout0 = tin[0]; l2c(tout0, out);
tout1 = tin[1]; l2c(tout1, out);
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
} else if (mode == DES_DECRYPT) {
register DES_LONG xor0, xor1;
u_int8_t *in, *out;
xor0 = xor1 = 0;
iv = (u_int8_t *)ivec;
c2l(iv, xor0);
c2l(iv, xor1);
while (0 < length) {
if (!m)
panic("mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them * later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
in = &inbuf[0];
out = &outbuf[0];
c2l(in, tin0); tin[0] = tin0;
c2l(in, tin1); tin[1] = tin1;
des_encrypt((DES_LONG *)tin, schedule, DES_DECRYPT);
tout0 = tin[0] ^ xor0;
tout1 = tin[1] ^ xor1;
l2c(tout0, out);
l2c(tout1, out);
xor0 = tin0;
xor1 = tin1;
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && ! m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p)
panic("mbuf chain?\n");
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && ! n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}
}

231
sys/crypto/des/des_ecb.c Normal file
View File

@ -0,0 +1,231 @@
/* crypto/des/ecb_enc.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
#include <crypto/des/des_locl.h>
#include <crypto/des/spr.h>
char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
char *DES_version="DES part of SSLeay 0.6.4 30-Aug-1996";
char *des_options()
{
#ifdef DES_PTR
if (sizeof(DES_LONG) != sizeof(long))
return("des(ptr,int)");
else
return("des(ptr,long)");
#else
if (sizeof(DES_LONG) != sizeof(long))
return("des(idx,int)");
else
return("des(idx,long)");
#endif
}
void des_ecb_encrypt(input, output, ks, encrypt)
des_cblock (*input);
des_cblock (*output);
des_key_schedule ks;
int encrypt;
{
register DES_LONG l;
register unsigned char *in,*out;
DES_LONG ll[2];
in=(unsigned char *)input;
out=(unsigned char *)output;
c2l(in,l); ll[0]=l;
c2l(in,l); ll[1]=l;
des_encrypt(ll,ks,encrypt);
l=ll[0]; l2c(l,out);
l=ll[1]; l2c(l,out);
l=ll[0]=ll[1]=0;
}
void des_encrypt(data, ks, encrypt)
DES_LONG *data;
des_key_schedule ks;
int encrypt;
{
register DES_LONG l,r,t,u;
#ifdef DES_PTR
register unsigned char *des_SP=(unsigned char *)des_SPtrans;
#endif
#ifdef undef
union fudge {
DES_LONG l;
unsigned short s[2];
unsigned char c[4];
} U,T;
#endif
register int i;
register DES_LONG *s;
u=data[0];
r=data[1];
IP(u,r);
/* Things have been modified so that the initial rotate is
* done outside the loop. This required the
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
* One perl script later and things have a 5% speed up on a sparc2.
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
* for pointing this out. */
l=(r<<1)|(r>>31);
r=(u<<1)|(u>>31);
/* clear the top bits on machines with 8byte longs */
l&=0xffffffffL;
r&=0xffffffffL;
s=(DES_LONG *)ks;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop
*/
if (encrypt)
{
for (i=0; i<32; i+=8)
{
D_ENCRYPT(l,r,i+0); /* 1 */
D_ENCRYPT(r,l,i+2); /* 2 */
D_ENCRYPT(l,r,i+4); /* 3 */
D_ENCRYPT(r,l,i+6); /* 4 */
}
}
else
{
for (i=30; i>0; i-=8)
{
D_ENCRYPT(l,r,i-0); /* 16 */
D_ENCRYPT(r,l,i-2); /* 15 */
D_ENCRYPT(l,r,i-4); /* 14 */
D_ENCRYPT(r,l,i-6); /* 13 */
}
}
l=(l>>1)|(l<<31);
r=(r>>1)|(r<<31);
/* clear the top bits on machines with 8byte longs */
l&=0xffffffffL;
r&=0xffffffffL;
FP(r,l);
data[0]=l;
data[1]=r;
l=r=t=u=0;
}
void des_encrypt2(data, ks, encrypt)
DES_LONG *data;
des_key_schedule ks;
int encrypt;
{
register DES_LONG l,r,t,u;
#ifdef DES_PTR
register unsigned char *des_SP=(unsigned char *)des_SPtrans;
#endif
#ifdef undef
union fudge {
DES_LONG l;
unsigned short s[2];
unsigned char c[4];
} U,T;
#endif
register int i;
register DES_LONG *s;
u=data[0];
r=data[1];
/* Things have been modified so that the initial rotate is
* done outside the loop. This required the
* des_SPtrans values in sp.h to be rotated 1 bit to the right.
* One perl script later and things have a 5% speed up on a sparc2.
* Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
* for pointing this out. */
l=(r<<1)|(r>>31);
r=(u<<1)|(u>>31);
/* clear the top bits on machines with 8byte longs */
l&=0xffffffffL;
r&=0xffffffffL;
s=(DES_LONG *)ks;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (encrypt)
{
for (i=0; i<32; i+=8)
{
D_ENCRYPT(l,r,i+0); /* 1 */
D_ENCRYPT(r,l,i+2); /* 2 */
D_ENCRYPT(l,r,i+4); /* 3 */
D_ENCRYPT(r,l,i+6); /* 4 */
}
}
else
{
for (i=30; i>0; i-=8)
{
D_ENCRYPT(l,r,i-0); /* 16 */
D_ENCRYPT(r,l,i-2); /* 15 */
D_ENCRYPT(l,r,i-4); /* 14 */
D_ENCRYPT(r,l,i-6); /* 13 */
}
}
l=(l>>1)|(l<<31);
r=(r>>1)|(r<<31);
/* clear the top bits on machines with 8byte longs */
l&=0xffffffffL;
r&=0xffffffffL;
data[0]=l;
data[1]=r;
l=r=t=u=0;
}

347
sys/crypto/des/des_locl.h Normal file
View File

@ -0,0 +1,347 @@
/* lib/des/des_locl.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Always modify des_locl.org since des_locl.h is automatically generated from
* it during SSLeay configuration.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#ifndef HEADER_DES_LOCL_H
#define HEADER_DES_LOCL_H
#if defined(WIN32) || defined(WIN16)
#ifndef MSDOS
#define MSDOS
#endif
#endif
/*
#include <stdio.h>
#include <stdlib.h>
#ifndef MSDOS
#include <unistd.h>
#endif
*/
#include <crypto/des/des.h>
/* the following is tweaked from a config script, that is why it is a
* protected undef/define */
#ifndef DES_PTR
#undef DES_PTR
#endif
#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <io.h>
#ifndef RAND
#define RAND
#endif
#undef NOPROTO
#endif
#if !defined(KERNEL) && (defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS))
#ifndef __NetBSD__
#include <string.h>
#endif
#endif
#ifdef __NetBSD__
#include <sys/systm.h>
#endif
#ifndef RAND
#define RAND
#endif
#ifdef linux
#undef RAND
#endif
#ifdef MSDOS
#define getpid() 2
#define RAND
#undef NOPROTO
#endif
#if defined(NOCONST)
#define const
#endif
#ifdef __STDC__
#undef NOPROTO
#endif
#ifdef RAND
#define srandom(s) srand(s)
#define random rand
#endif
#define ITERATIONS 16
#define HALF_ITERATIONS 8
/* used in des_read and des_write */
#define MAXWRITE (1024*16)
#define BSIZE (MAXWRITE+4)
#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
l|=((DES_LONG)(*((c)++)))<< 8L, \
l|=((DES_LONG)(*((c)++)))<<16L, \
l|=((DES_LONG)(*((c)++)))<<24L)
/* NOTE - c is not incremented as per c2l */
#define c2ln(c,l1,l2,n) { \
c+=n; \
l1=l2=0; \
switch (n) { \
case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
case 5: l2|=((DES_LONG)(*(--(c)))); \
case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
case 1: l1|=((DES_LONG)(*(--(c)))); \
} \
}
#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>>24L)&0xff))
/* replacements for htonl and ntohl since I have no idea what to do
* when faced with machines with 8 byte longs. */
#define HDRSIZE 4
#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
l|=((DES_LONG)(*((c)++)))<<16L, \
l|=((DES_LONG)(*((c)++)))<< 8L, \
l|=((DES_LONG)(*((c)++))))
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
*((c)++)=(unsigned char)(((l)>>16L)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* NOTE - c is not incremented as per l2c */
#define l2cn(l1,l2,c,n) { \
c+=n; \
switch (n) { \
case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
} \
}
#if defined(WIN32)
#define ROTATE(a,n) (_lrotr(a,n))
#else
#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
#endif
/* The changes to this macro may help or hinder, depending on the
* compiler and the achitecture. gcc2 always seems to do well :-).
* Inspired by Dana How <how@isl.stanford.edu>
* DO NOT use the alternative version on machines with 8 byte longs.
* It does not seem to work on the Alpha, even when DES_LONG is 4
* bytes, probably an issue of accessing non-word aligned objects :-( */
#ifdef DES_PTR
#define D_ENCRYPT(L,R,S) { \
u=((R^s[S ])<<2); \
t= R^s[S+1]; \
t=ROTATE(t,2); \
L^= (\
*(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8)&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16)&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24)&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8)&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16)&0xfc))+ \
*(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24)&0xfc))); }
#else /* original version */
#ifdef undef
#define D_ENCRYPT(L,R,S) \
U.l=R^s[S+1]; \
T.s[0]=((U.s[0]>>4)|(U.s[1]<<12))&0x3f3f; \
T.s[1]=((U.s[1]>>4)|(U.s[0]<<12))&0x3f3f; \
U.l=(R^s[S ])&0x3f3f3f3fL; \
L^= des_SPtrans[1][(T.c[0])]| \
des_SPtrans[3][(T.c[1])]| \
des_SPtrans[5][(T.c[2])]| \
des_SPtrans[7][(T.c[3])]| \
des_SPtrans[0][(U.c[0])]| \
des_SPtrans[2][(U.c[1])]| \
des_SPtrans[4][(U.c[2])]| \
des_SPtrans[6][(U.c[3])];
#else
#define D_ENCRYPT(Q,R,S) {\
u=(R^s[S ]); \
t=R^s[S+1]; \
t=ROTATE(t,4); \
Q^= des_SPtrans[1][(t )&0x3f]| \
des_SPtrans[3][(t>> 8L)&0x3f]| \
des_SPtrans[5][(t>>16L)&0x3f]| \
des_SPtrans[7][(t>>24L)&0x3f]| \
des_SPtrans[0][(u )&0x3f]| \
des_SPtrans[2][(u>> 8L)&0x3f]| \
des_SPtrans[4][(u>>16L)&0x3f]| \
des_SPtrans[6][(u>>24L)&0x3f]; }
#endif
#endif
/* IP and FP
* The problem is more of a geometric problem that random bit fiddling.
0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
The output has been subject to swaps of the form
0 1 -> 3 1 but the odd and even bits have been put into
2 3 2 0
different words. The main trick is to remember that
t=((l>>size)^r)&(mask);
r^=t;
l^=(t<<size);
can be used to swap and move bits between words.
So l = 0 1 2 3 r = 16 17 18 19
4 5 6 7 20 21 22 23
8 9 10 11 24 25 26 27
12 13 14 15 28 29 30 31
becomes (for size == 2 and mask == 0x3333)
t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
6^20 7^21 -- -- 4 5 20 21 6 7 22 23
10^24 11^25 -- -- 8 9 24 25 10 11 24 25
14^28 15^29 -- -- 12 13 28 29 14 15 28 29
Thanks for hints from Richard Outerbridge - he told me IP&FP
could be done in 15 xor, 10 shifts and 5 ands.
When I finally started to think of the problem in 2D
I first got ~42 operations without xors. When I remembered
how to use xors :-) I got it to its final state.
*/
#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
(b)^=(t),\
(a)^=((t)<<(n)))
#define IP(l,r) \
{ \
register DES_LONG tt; \
PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
PERM_OP(l,r,tt,16,0x0000ffffL); \
PERM_OP(r,l,tt, 2,0x33333333L); \
PERM_OP(l,r,tt, 8,0x00ff00ffL); \
PERM_OP(r,l,tt, 1,0x55555555L); \
}
#define FP(l,r) \
{ \
register DES_LONG tt; \
PERM_OP(l,r,tt, 1,0x55555555L); \
PERM_OP(r,l,tt, 8,0x00ff00ffL); \
PERM_OP(l,r,tt, 2,0x33333333L); \
PERM_OP(r,l,tt,16,0x0000ffffL); \
PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
}
#endif
/*
#define mbuf2char(i_mbuf, i_index, in) \
{ \
register int i; \
struct mbuf *m; \
char *buf; \
m = i_mbuf; \
for (i = 0; i < 8; i ++){ \
if (i_index + i == m->m_len){ \
m = m->m_next; \
} \
buf = mtod(m, char *); \
in[i] = *(buf + i); \
}
#define char2mbuf(o_mbuf, o_index, out) \
{ \
register int i; \
struct mbuf *m; \
char *buf; \
m = o_mbuf; \
for (i = 0; i < 8; i ++){ \
if (i_index + i == m->m_len){ \
m = m->m_next; \
} \
buf = mtod(m, char *); \
*(buf + i) = out[i]; \
}
*/

238
sys/crypto/des/des_setkey.c Normal file
View File

@ -0,0 +1,238 @@
/* crypto/des/set_key.c */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
/* set_key.c v 1.4 eay 24/9/91
* 1.4 Speed up by 400% :-)
* 1.3 added register declarations.
* 1.2 unrolled make_key_sched a bit more
* 1.1 added norm_expand_bits
* 1.0 First working version
*/
#include <crypto/des/des_locl.h>
#include <crypto/des/podd.h>
#include <crypto/des/sk.h>
#ifndef NOPROTO
static int check_parity(des_cblock (*key));
#else
static int check_parity();
#endif
int des_check_key=0;
void des_set_odd_parity(key)
des_cblock (*key);
{
int i;
for (i=0; i<DES_KEY_SZ; i++)
(*key)[i]=odd_parity[(*key)[i]];
}
static int check_parity(key)
des_cblock (*key);
{
int i;
for (i=0; i<DES_KEY_SZ; i++)
{
if ((*key)[i] != odd_parity[(*key)[i]])
return(0);
}
return(1);
}
/* Weak and semi week keys as take from
* %A D.W. Davies
* %A W.L. Price
* %T Security for Computer Networks
* %I John Wiley & Sons
* %D 1984
* Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
* (and actual cblock values).
*/
#define NUM_WEAK_KEY 16
static des_cblock weak_keys[NUM_WEAK_KEY]={
/* weak keys */
{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
{0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
{0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
{0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
/* semi-weak keys */
{0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
{0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
{0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
{0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
{0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
int des_is_weak_key(key)
des_cblock (*key);
{
int i;
for (i=0; i<NUM_WEAK_KEY; i++)
/* Added == 0 to comparision, I obviously don't run
* this section very often :-(, thanks to
* engineering@MorningStar.Com for the fix
* eay 93/06/29 */
/*
if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
*/
if (bcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
return(0);
}
/* NOW DEFINED IN des_local.h
* See ecb_encrypt.c for a pseudo description of these macros.
* #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
* (b)^=(t),\
* (a)=((a)^((t)<<(n))))
*/
#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
(a)=(a)^(t)^(t>>(16-(n))))
/* return 0 if key parity is odd (correct),
* return -1 if key parity error,
* return -2 if illegal weak key.
*/
int des_set_key(key, schedule)
des_cblock (*key);
des_key_schedule schedule;
{
static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
register DES_LONG c,d,t,s;
register unsigned char *in;
register DES_LONG *k;
register int i;
if (des_check_key)
{
if (!check_parity(key))
return(-1);
if (des_is_weak_key(key))
return(-2);
}
k=(DES_LONG *)schedule;
in=(unsigned char *)key;
c2l(in,c);
c2l(in,d);
/* do PC1 in 60 simple operations */
/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
HPERM_OP(c,t,-2, 0xcccc0000L);
HPERM_OP(c,t,-1, 0xaaaa0000L);
HPERM_OP(c,t, 8, 0x00ff0000L);
HPERM_OP(c,t,-1, 0xaaaa0000L);
HPERM_OP(d,t,-8, 0xff000000L);
HPERM_OP(d,t, 8, 0x00ff0000L);
HPERM_OP(d,t, 2, 0x33330000L);
d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
d=(d>>8)|((c&0xf0000000L)>>4);
c&=0x0fffffffL; */
/* I now do it in 47 simple operations :-)
* Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
* for the inspiration. :-) */
PERM_OP (d,c,t,4,0x0f0f0f0fL);
HPERM_OP(c,t,-2,0xcccc0000L);
HPERM_OP(d,t,-2,0xcccc0000L);
PERM_OP (d,c,t,1,0x55555555L);
PERM_OP (c,d,t,8,0x00ff00ffL);
PERM_OP (d,c,t,1,0x55555555L);
d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
c&=0x0fffffffL;
for (i=0; i<ITERATIONS; i++)
{
if (shifts2[i])
{ c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
else
{ c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
c&=0x0fffffffL;
d&=0x0fffffffL;
/* could be a few less shifts but I am to lazy at this
* point in time to investigate */
s= des_skb[0][ (c )&0x3f ]|
des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
((c>>22L)&0x38)];
t= des_skb[4][ (d )&0x3f ]|
des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
des_skb[6][ (d>>15L)&0x3f ]|
des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
/* table contained 0213 4657 */
*(k++)=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
s= ((s>>16L)|(t&0xffff0000L));
s=(s<<4L)|(s>>28L);
*(k++)=s&0xffffffffL;
}
return(0);
}
int des_key_sched(key, schedule)
des_cblock (*key);
des_key_schedule schedule;
{
return(des_set_key(key,schedule));
}

66
sys/crypto/des/podd.h Normal file
View File

@ -0,0 +1,66 @@
/* crypto/des/podd.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
static const unsigned char odd_parity[256]={
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};

195
sys/crypto/des/sk.h Normal file
View File

@ -0,0 +1,195 @@
/* crypto/des/sk.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
static const DES_LONG des_skb[8][64]={
{
/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
0x00000000L,0x00000010L,0x20000000L,0x20000010L,
0x00010000L,0x00010010L,0x20010000L,0x20010010L,
0x00000800L,0x00000810L,0x20000800L,0x20000810L,
0x00010800L,0x00010810L,0x20010800L,0x20010810L,
0x00000020L,0x00000030L,0x20000020L,0x20000030L,
0x00010020L,0x00010030L,0x20010020L,0x20010030L,
0x00000820L,0x00000830L,0x20000820L,0x20000830L,
0x00010820L,0x00010830L,0x20010820L,0x20010830L,
0x00080000L,0x00080010L,0x20080000L,0x20080010L,
0x00090000L,0x00090010L,0x20090000L,0x20090010L,
0x00080800L,0x00080810L,0x20080800L,0x20080810L,
0x00090800L,0x00090810L,0x20090800L,0x20090810L,
0x00080020L,0x00080030L,0x20080020L,0x20080030L,
0x00090020L,0x00090030L,0x20090020L,0x20090030L,
0x00080820L,0x00080830L,0x20080820L,0x20080830L,
0x00090820L,0x00090830L,0x20090820L,0x20090830L,
},{
/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
0x00000000L,0x02000000L,0x00002000L,0x02002000L,
0x00200000L,0x02200000L,0x00202000L,0x02202000L,
0x00000004L,0x02000004L,0x00002004L,0x02002004L,
0x00200004L,0x02200004L,0x00202004L,0x02202004L,
0x00000400L,0x02000400L,0x00002400L,0x02002400L,
0x00200400L,0x02200400L,0x00202400L,0x02202400L,
0x00000404L,0x02000404L,0x00002404L,0x02002404L,
0x00200404L,0x02200404L,0x00202404L,0x02202404L,
0x10000000L,0x12000000L,0x10002000L,0x12002000L,
0x10200000L,0x12200000L,0x10202000L,0x12202000L,
0x10000004L,0x12000004L,0x10002004L,0x12002004L,
0x10200004L,0x12200004L,0x10202004L,0x12202004L,
0x10000400L,0x12000400L,0x10002400L,0x12002400L,
0x10200400L,0x12200400L,0x10202400L,0x12202400L,
0x10000404L,0x12000404L,0x10002404L,0x12002404L,
0x10200404L,0x12200404L,0x10202404L,0x12202404L,
},{
/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
0x00000000L,0x00000001L,0x00040000L,0x00040001L,
0x01000000L,0x01000001L,0x01040000L,0x01040001L,
0x00000002L,0x00000003L,0x00040002L,0x00040003L,
0x01000002L,0x01000003L,0x01040002L,0x01040003L,
0x00000200L,0x00000201L,0x00040200L,0x00040201L,
0x01000200L,0x01000201L,0x01040200L,0x01040201L,
0x00000202L,0x00000203L,0x00040202L,0x00040203L,
0x01000202L,0x01000203L,0x01040202L,0x01040203L,
0x08000000L,0x08000001L,0x08040000L,0x08040001L,
0x09000000L,0x09000001L,0x09040000L,0x09040001L,
0x08000002L,0x08000003L,0x08040002L,0x08040003L,
0x09000002L,0x09000003L,0x09040002L,0x09040003L,
0x08000200L,0x08000201L,0x08040200L,0x08040201L,
0x09000200L,0x09000201L,0x09040200L,0x09040201L,
0x08000202L,0x08000203L,0x08040202L,0x08040203L,
0x09000202L,0x09000203L,0x09040202L,0x09040203L,
},{
/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
0x00000000L,0x00100000L,0x00000100L,0x00100100L,
0x00000008L,0x00100008L,0x00000108L,0x00100108L,
0x00001000L,0x00101000L,0x00001100L,0x00101100L,
0x00001008L,0x00101008L,0x00001108L,0x00101108L,
0x04000000L,0x04100000L,0x04000100L,0x04100100L,
0x04000008L,0x04100008L,0x04000108L,0x04100108L,
0x04001000L,0x04101000L,0x04001100L,0x04101100L,
0x04001008L,0x04101008L,0x04001108L,0x04101108L,
0x00020000L,0x00120000L,0x00020100L,0x00120100L,
0x00020008L,0x00120008L,0x00020108L,0x00120108L,
0x00021000L,0x00121000L,0x00021100L,0x00121100L,
0x00021008L,0x00121008L,0x00021108L,0x00121108L,
0x04020000L,0x04120000L,0x04020100L,0x04120100L,
0x04020008L,0x04120008L,0x04020108L,0x04120108L,
0x04021000L,0x04121000L,0x04021100L,0x04121100L,
0x04021008L,0x04121008L,0x04021108L,0x04121108L,
},{
/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
0x00000000L,0x10000000L,0x00010000L,0x10010000L,
0x00000004L,0x10000004L,0x00010004L,0x10010004L,
0x20000000L,0x30000000L,0x20010000L,0x30010000L,
0x20000004L,0x30000004L,0x20010004L,0x30010004L,
0x00100000L,0x10100000L,0x00110000L,0x10110000L,
0x00100004L,0x10100004L,0x00110004L,0x10110004L,
0x20100000L,0x30100000L,0x20110000L,0x30110000L,
0x20100004L,0x30100004L,0x20110004L,0x30110004L,
0x00001000L,0x10001000L,0x00011000L,0x10011000L,
0x00001004L,0x10001004L,0x00011004L,0x10011004L,
0x20001000L,0x30001000L,0x20011000L,0x30011000L,
0x20001004L,0x30001004L,0x20011004L,0x30011004L,
0x00101000L,0x10101000L,0x00111000L,0x10111000L,
0x00101004L,0x10101004L,0x00111004L,0x10111004L,
0x20101000L,0x30101000L,0x20111000L,0x30111000L,
0x20101004L,0x30101004L,0x20111004L,0x30111004L,
},{
/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
0x00000000L,0x08000000L,0x00000008L,0x08000008L,
0x00000400L,0x08000400L,0x00000408L,0x08000408L,
0x00020000L,0x08020000L,0x00020008L,0x08020008L,
0x00020400L,0x08020400L,0x00020408L,0x08020408L,
0x00000001L,0x08000001L,0x00000009L,0x08000009L,
0x00000401L,0x08000401L,0x00000409L,0x08000409L,
0x00020001L,0x08020001L,0x00020009L,0x08020009L,
0x00020401L,0x08020401L,0x00020409L,0x08020409L,
0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
},{
/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
0x00000000L,0x00000100L,0x00080000L,0x00080100L,
0x01000000L,0x01000100L,0x01080000L,0x01080100L,
0x00000010L,0x00000110L,0x00080010L,0x00080110L,
0x01000010L,0x01000110L,0x01080010L,0x01080110L,
0x00200000L,0x00200100L,0x00280000L,0x00280100L,
0x01200000L,0x01200100L,0x01280000L,0x01280100L,
0x00200010L,0x00200110L,0x00280010L,0x00280110L,
0x01200010L,0x01200110L,0x01280010L,0x01280110L,
0x00000200L,0x00000300L,0x00080200L,0x00080300L,
0x01000200L,0x01000300L,0x01080200L,0x01080300L,
0x00000210L,0x00000310L,0x00080210L,0x00080310L,
0x01000210L,0x01000310L,0x01080210L,0x01080310L,
0x00200200L,0x00200300L,0x00280200L,0x00280300L,
0x01200200L,0x01200300L,0x01280200L,0x01280300L,
0x00200210L,0x00200310L,0x00280210L,0x00280310L,
0x01200210L,0x01200310L,0x01280210L,0x01280310L,
},{
/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
0x00000000L,0x04000000L,0x00040000L,0x04040000L,
0x00000002L,0x04000002L,0x00040002L,0x04040002L,
0x00002000L,0x04002000L,0x00042000L,0x04042000L,
0x00002002L,0x04002002L,0x00042002L,0x04042002L,
0x00000020L,0x04000020L,0x00040020L,0x04040020L,
0x00000022L,0x04000022L,0x00040022L,0x04040022L,
0x00002020L,0x04002020L,0x00042020L,0x04042020L,
0x00002022L,0x04002022L,0x00042022L,0x04042022L,
0x00000800L,0x04000800L,0x00040800L,0x04040800L,
0x00000802L,0x04000802L,0x00040802L,0x04040802L,
0x00002800L,0x04002800L,0x00042800L,0x04042800L,
0x00002802L,0x04002802L,0x00042802L,0x04042802L,
0x00000820L,0x04000820L,0x00040820L,0x04040820L,
0x00000822L,0x04000822L,0x00040822L,0x04040822L,
0x00002820L,0x04002820L,0x00042820L,0x04042820L,
0x00002822L,0x04002822L,0x00042822L,0x04042822L,
}};

195
sys/crypto/des/spr.h Normal file
View File

@ -0,0 +1,195 @@
/* crypto/des/spr.h */
/* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* $FreeBSD$
*/
static const DES_LONG des_SPtrans[8][64]={
{
/* nibble 0 */
0x00820200L, 0x00020000L, 0x80800000L, 0x80820200L,
0x00800000L, 0x80020200L, 0x80020000L, 0x80800000L,
0x80020200L, 0x00820200L, 0x00820000L, 0x80000200L,
0x80800200L, 0x00800000L, 0x00000000L, 0x80020000L,
0x00020000L, 0x80000000L, 0x00800200L, 0x00020200L,
0x80820200L, 0x00820000L, 0x80000200L, 0x00800200L,
0x80000000L, 0x00000200L, 0x00020200L, 0x80820000L,
0x00000200L, 0x80800200L, 0x80820000L, 0x00000000L,
0x00000000L, 0x80820200L, 0x00800200L, 0x80020000L,
0x00820200L, 0x00020000L, 0x80000200L, 0x00800200L,
0x80820000L, 0x00000200L, 0x00020200L, 0x80800000L,
0x80020200L, 0x80000000L, 0x80800000L, 0x00820000L,
0x80820200L, 0x00020200L, 0x00820000L, 0x80800200L,
0x00800000L, 0x80000200L, 0x80020000L, 0x00000000L,
0x00020000L, 0x00800000L, 0x80800200L, 0x00820200L,
0x80000000L, 0x80820000L, 0x00000200L, 0x80020200L,
},{
/* nibble 1 */
0x10042004L, 0x00000000L, 0x00042000L, 0x10040000L,
0x10000004L, 0x00002004L, 0x10002000L, 0x00042000L,
0x00002000L, 0x10040004L, 0x00000004L, 0x10002000L,
0x00040004L, 0x10042000L, 0x10040000L, 0x00000004L,
0x00040000L, 0x10002004L, 0x10040004L, 0x00002000L,
0x00042004L, 0x10000000L, 0x00000000L, 0x00040004L,
0x10002004L, 0x00042004L, 0x10042000L, 0x10000004L,
0x10000000L, 0x00040000L, 0x00002004L, 0x10042004L,
0x00040004L, 0x10042000L, 0x10002000L, 0x00042004L,
0x10042004L, 0x00040004L, 0x10000004L, 0x00000000L,
0x10000000L, 0x00002004L, 0x00040000L, 0x10040004L,
0x00002000L, 0x10000000L, 0x00042004L, 0x10002004L,
0x10042000L, 0x00002000L, 0x00000000L, 0x10000004L,
0x00000004L, 0x10042004L, 0x00042000L, 0x10040000L,
0x10040004L, 0x00040000L, 0x00002004L, 0x10002000L,
0x10002004L, 0x00000004L, 0x10040000L, 0x00042000L,
},{
/* nibble 2 */
0x41000000L, 0x01010040L, 0x00000040L, 0x41000040L,
0x40010000L, 0x01000000L, 0x41000040L, 0x00010040L,
0x01000040L, 0x00010000L, 0x01010000L, 0x40000000L,
0x41010040L, 0x40000040L, 0x40000000L, 0x41010000L,
0x00000000L, 0x40010000L, 0x01010040L, 0x00000040L,
0x40000040L, 0x41010040L, 0x00010000L, 0x41000000L,
0x41010000L, 0x01000040L, 0x40010040L, 0x01010000L,
0x00010040L, 0x00000000L, 0x01000000L, 0x40010040L,
0x01010040L, 0x00000040L, 0x40000000L, 0x00010000L,
0x40000040L, 0x40010000L, 0x01010000L, 0x41000040L,
0x00000000L, 0x01010040L, 0x00010040L, 0x41010000L,
0x40010000L, 0x01000000L, 0x41010040L, 0x40000000L,
0x40010040L, 0x41000000L, 0x01000000L, 0x41010040L,
0x00010000L, 0x01000040L, 0x41000040L, 0x00010040L,
0x01000040L, 0x00000000L, 0x41010000L, 0x40000040L,
0x41000000L, 0x40010040L, 0x00000040L, 0x01010000L,
},{
/* nibble 3 */
0x00100402L, 0x04000400L, 0x00000002L, 0x04100402L,
0x00000000L, 0x04100000L, 0x04000402L, 0x00100002L,
0x04100400L, 0x04000002L, 0x04000000L, 0x00000402L,
0x04000002L, 0x00100402L, 0x00100000L, 0x04000000L,
0x04100002L, 0x00100400L, 0x00000400L, 0x00000002L,
0x00100400L, 0x04000402L, 0x04100000L, 0x00000400L,
0x00000402L, 0x00000000L, 0x00100002L, 0x04100400L,
0x04000400L, 0x04100002L, 0x04100402L, 0x00100000L,
0x04100002L, 0x00000402L, 0x00100000L, 0x04000002L,
0x00100400L, 0x04000400L, 0x00000002L, 0x04100000L,
0x04000402L, 0x00000000L, 0x00000400L, 0x00100002L,
0x00000000L, 0x04100002L, 0x04100400L, 0x00000400L,
0x04000000L, 0x04100402L, 0x00100402L, 0x00100000L,
0x04100402L, 0x00000002L, 0x04000400L, 0x00100402L,
0x00100002L, 0x00100400L, 0x04100000L, 0x04000402L,
0x00000402L, 0x04000000L, 0x04000002L, 0x04100400L,
},{
/* nibble 4 */
0x02000000L, 0x00004000L, 0x00000100L, 0x02004108L,
0x02004008L, 0x02000100L, 0x00004108L, 0x02004000L,
0x00004000L, 0x00000008L, 0x02000008L, 0x00004100L,
0x02000108L, 0x02004008L, 0x02004100L, 0x00000000L,
0x00004100L, 0x02000000L, 0x00004008L, 0x00000108L,
0x02000100L, 0x00004108L, 0x00000000L, 0x02000008L,
0x00000008L, 0x02000108L, 0x02004108L, 0x00004008L,
0x02004000L, 0x00000100L, 0x00000108L, 0x02004100L,
0x02004100L, 0x02000108L, 0x00004008L, 0x02004000L,
0x00004000L, 0x00000008L, 0x02000008L, 0x02000100L,
0x02000000L, 0x00004100L, 0x02004108L, 0x00000000L,
0x00004108L, 0x02000000L, 0x00000100L, 0x00004008L,
0x02000108L, 0x00000100L, 0x00000000L, 0x02004108L,
0x02004008L, 0x02004100L, 0x00000108L, 0x00004000L,
0x00004100L, 0x02004008L, 0x02000100L, 0x00000108L,
0x00000008L, 0x00004108L, 0x02004000L, 0x02000008L,
},{
/* nibble 5 */
0x20000010L, 0x00080010L, 0x00000000L, 0x20080800L,
0x00080010L, 0x00000800L, 0x20000810L, 0x00080000L,
0x00000810L, 0x20080810L, 0x00080800L, 0x20000000L,
0x20000800L, 0x20000010L, 0x20080000L, 0x00080810L,
0x00080000L, 0x20000810L, 0x20080010L, 0x00000000L,
0x00000800L, 0x00000010L, 0x20080800L, 0x20080010L,
0x20080810L, 0x20080000L, 0x20000000L, 0x00000810L,
0x00000010L, 0x00080800L, 0x00080810L, 0x20000800L,
0x00000810L, 0x20000000L, 0x20000800L, 0x00080810L,
0x20080800L, 0x00080010L, 0x00000000L, 0x20000800L,
0x20000000L, 0x00000800L, 0x20080010L, 0x00080000L,
0x00080010L, 0x20080810L, 0x00080800L, 0x00000010L,
0x20080810L, 0x00080800L, 0x00080000L, 0x20000810L,
0x20000010L, 0x20080000L, 0x00080810L, 0x00000000L,
0x00000800L, 0x20000010L, 0x20000810L, 0x20080800L,
0x20080000L, 0x00000810L, 0x00000010L, 0x20080010L,
},{
/* nibble 6 */
0x00001000L, 0x00000080L, 0x00400080L, 0x00400001L,
0x00401081L, 0x00001001L, 0x00001080L, 0x00000000L,
0x00400000L, 0x00400081L, 0x00000081L, 0x00401000L,
0x00000001L, 0x00401080L, 0x00401000L, 0x00000081L,
0x00400081L, 0x00001000L, 0x00001001L, 0x00401081L,
0x00000000L, 0x00400080L, 0x00400001L, 0x00001080L,
0x00401001L, 0x00001081L, 0x00401080L, 0x00000001L,
0x00001081L, 0x00401001L, 0x00000080L, 0x00400000L,
0x00001081L, 0x00401000L, 0x00401001L, 0x00000081L,
0x00001000L, 0x00000080L, 0x00400000L, 0x00401001L,
0x00400081L, 0x00001081L, 0x00001080L, 0x00000000L,
0x00000080L, 0x00400001L, 0x00000001L, 0x00400080L,
0x00000000L, 0x00400081L, 0x00400080L, 0x00001080L,
0x00000081L, 0x00001000L, 0x00401081L, 0x00400000L,
0x00401080L, 0x00000001L, 0x00001001L, 0x00401081L,
0x00400001L, 0x00401080L, 0x00401000L, 0x00001001L,
},{
/* nibble 7 */
0x08200020L, 0x08208000L, 0x00008020L, 0x00000000L,
0x08008000L, 0x00200020L, 0x08200000L, 0x08208020L,
0x00000020L, 0x08000000L, 0x00208000L, 0x00008020L,
0x00208020L, 0x08008020L, 0x08000020L, 0x08200000L,
0x00008000L, 0x00208020L, 0x00200020L, 0x08008000L,
0x08208020L, 0x08000020L, 0x00000000L, 0x00208000L,
0x08000000L, 0x00200000L, 0x08008020L, 0x08200020L,
0x00200000L, 0x00008000L, 0x08208000L, 0x00000020L,
0x00200000L, 0x00008000L, 0x08000020L, 0x08208020L,
0x00008020L, 0x08000000L, 0x00000000L, 0x00208000L,
0x08200020L, 0x08008020L, 0x08008000L, 0x00200020L,
0x08208000L, 0x00000020L, 0x00200020L, 0x08008000L,
0x08208020L, 0x00200000L, 0x08200000L, 0x08000020L,
0x00208000L, 0x00008020L, 0x08008020L, 0x08200000L,
0x00000020L, 0x08208000L, 0x00208020L, 0x00000000L,
0x08000000L, 0x08200020L, 0x00008000L, 0x00208020L,
}};

98
sys/crypto/hmac_md5.c Normal file
View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* Based on sample code appeared on RFC2104.
*/
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <crypto/md5.h>
#include <crypto/hmac_md5.h>
void
hmac_md5(src0, srclen, key0, keylen, digest)
caddr_t src0;
size_t srclen;
caddr_t key0;
size_t keylen;
caddr_t digest;
{
u_int8_t *src;
u_int8_t *key;
u_int8_t tk[16];
u_int8_t ipad[65];
u_int8_t opad[65];
size_t i;
src = (u_int8_t *)src0;
key = (u_int8_t *)key0;
/*
* compress the key into 16bytes, if key is too long.
*/
if (64 < keylen) {
md5_init();
md5_loop(key, keylen);
md5_pad();
md5_result(&tk[0]);
key = &tk[0];
keylen = 16;
}
/*
*
*/
bzero(&ipad[0], sizeof ipad);
bzero(&opad[0], sizeof opad);
bcopy(key, &ipad[0], keylen);
bcopy(key, &opad[0], keylen);
for (i = 0; i < 64; i++) {
ipad[i] ^= 0x36;
opad[i] ^= 0x5c;
}
md5_init();
md5_loop(&ipad[0], 64);
md5_loop(src, srclen);
md5_pad();
md5_result((u_int8_t *)digest);
md5_init();
md5_loop(&opad[0], 64);
md5_loop((u_int8_t *)digest, 16);
md5_pad();
md5_result((u_int8_t *)digest);
}

37
sys/crypto/hmac_md5.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NETINET6_HMAC_MD5_H_
#define _NETINET6_HMAC_MD5_H_
extern void hmac_md5 __P((caddr_t, size_t, caddr_t, size_t, caddr_t));
#endif /* ! _NETINET6_HMAC_MD5_H_*/

307
sys/crypto/md5.c Normal file
View File

@ -0,0 +1,307 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <crypto/md5.h>
#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
#define ROUND1(a, b, c, d, k, s, i) { \
(a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define ROUND2(a, b, c, d, k, s, i) { \
(a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define ROUND3(a, b, c, d, k, s, i) { \
(a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define ROUND4(a, b, c, d, k, s, i) { \
(a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
(a) = SHIFT((a), (s)); \
(a) = (b) + (a); \
}
#define Sa 7
#define Sb 12
#define Sc 17
#define Sd 22
#define Se 5
#define Sf 9
#define Sg 14
#define Sh 20
#define Si 4
#define Sj 11
#define Sk 16
#define Sl 23
#define Sm 6
#define Sn 10
#define So 15
#define Sp 21
#define MD5_A0 0x67452301
#define MD5_B0 0xefcdab89
#define MD5_C0 0x98badcfe
#define MD5_D0 0x10325476
/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
static const u_int32_t T[65] = {
0,
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
};
static const u_int8_t md5_paddat[MD5_BUFLEN] = {
0x80, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
static void md5_calc __P((u_int8_t *, md5_ctxt *));
void md5_init(ctxt)
md5_ctxt *ctxt;
{
ctxt->md5_n = 0;
ctxt->md5_i = 0;
ctxt->md5_sta = MD5_A0;
ctxt->md5_stb = MD5_B0;
ctxt->md5_stc = MD5_C0;
ctxt->md5_std = MD5_D0;
bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
}
void md5_loop(ctxt, input, len)
md5_ctxt *ctxt;
u_int8_t *input;
u_int len; /* number of bytes */
{
u_int gap, i;
ctxt->md5_n += len * 8; /* byte to bit */
gap = MD5_BUFLEN - ctxt->md5_i;
if (len >= gap) {
bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
gap);
md5_calc(ctxt->md5_buf, ctxt);
for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
md5_calc((u_int8_t *)(input + i), ctxt);
}
ctxt->md5_i = len - i;
bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
} else {
bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
len);
ctxt->md5_i += len;
}
}
void md5_pad(ctxt)
md5_ctxt *ctxt;
{
u_int gap;
/* Don't count up padding. Keep md5_n. */
gap = MD5_BUFLEN - ctxt->md5_i;
if (gap > 8) {
bcopy((void *)md5_paddat,
(void *)(ctxt->md5_buf + ctxt->md5_i),
gap - sizeof(ctxt->md5_n));
} else {
/* including gap == 8 */
bcopy((void *)md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
gap);
md5_calc(ctxt->md5_buf, ctxt);
bcopy((void *)(md5_paddat + gap),
(void *)ctxt->md5_buf,
MD5_BUFLEN - sizeof(ctxt->md5_n));
}
/* 8 byte word */
#if BYTE_ORDER == LITTLE_ENDIAN
bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
#endif
#if BYTE_ORDER == BIG_ENDIAN
ctxt->md5_buf[56] = ctxt->md5_n8[7];
ctxt->md5_buf[57] = ctxt->md5_n8[6];
ctxt->md5_buf[58] = ctxt->md5_n8[5];
ctxt->md5_buf[59] = ctxt->md5_n8[4];
ctxt->md5_buf[60] = ctxt->md5_n8[3];
ctxt->md5_buf[61] = ctxt->md5_n8[2];
ctxt->md5_buf[62] = ctxt->md5_n8[1];
ctxt->md5_buf[63] = ctxt->md5_n8[0];
#endif
md5_calc(ctxt->md5_buf, ctxt);
}
void md5_result(digest, ctxt)
u_int8_t *digest;
md5_ctxt *ctxt;
{
/* 4 byte words */
#if BYTE_ORDER == LITTLE_ENDIAN
bcopy(&ctxt->md5_st8[0], digest, 16);
#endif
#if BYTE_ORDER == BIG_ENDIAN
digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
#endif
}
#if BYTE_ORDER == BIG_ENDIAN
u_int32_t X[16];
#endif
static void md5_calc(b64, ctxt)
u_int8_t *b64;
md5_ctxt *ctxt;
{
u_int32_t A = ctxt->md5_sta;
u_int32_t B = ctxt->md5_stb;
u_int32_t C = ctxt->md5_stc;
u_int32_t D = ctxt->md5_std;
#if BYTE_ORDER == LITTLE_ENDIAN
u_int32_t *X = (u_int32_t *)b64;
#endif
#if BYTE_ORDER == BIG_ENDIAN
/* 4 byte words */
/* what a brute force but fast! */
u_int8_t *y = (u_int8_t *)X;
y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
#endif
ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
ctxt->md5_sta += A;
ctxt->md5_stb += B;
ctxt->md5_stc += C;
ctxt->md5_std += D;
}

75
sys/crypto/md5.h Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _NETINET6_MD5_H_
#define _NETINET6_MD5_H_
#define MD5_BUFLEN 64
typedef struct {
union {
u_int32_t md5_state32[4];
u_int8_t md5_state8[16];
} md5_st;
#define md5_sta md5_st.md5_state32[0]
#define md5_stb md5_st.md5_state32[1]
#define md5_stc md5_st.md5_state32[2]
#define md5_std md5_st.md5_state32[3]
#define md5_st8 md5_st.md5_state8
union {
u_int64_t md5_count64;
u_int8_t md5_count8[8];
} md5_count;
#define md5_n md5_count.md5_count64
#define md5_n8 md5_count.md5_count8
u_int md5_i;
u_int8_t md5_buf[MD5_BUFLEN];
} md5_ctxt;
extern void md5_init __P((md5_ctxt *));
extern void md5_loop __P((md5_ctxt *, u_int8_t *, u_int));
extern void md5_pad __P((md5_ctxt *));
extern void md5_result __P((u_int8_t *, md5_ctxt *));
/* compatibility */
#define MD5_CTX md5_ctxt
#define MD5Init(x) md5_init((x))
#define MD5Update(x, y, z) md5_loop((x), (y), (z))
#define MD5Final(x, y) \
do { \
md5_pad((y)); \
md5_result((x), (y)); \
} while (0)
#endif /* ! _NETINET6_MD5_H_*/

218
sys/crypto/rc5/rc5.c Normal file
View File

@ -0,0 +1,218 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <crypto/rc5/rc5.h>
void
set_rc5_expandkey(e_key, key, keylen, rounds)
RC5_WORD *e_key;
u_int8_t *key;
size_t keylen;
int rounds;
{
int i, j, k, LL, t, T;
RC5_WORD L[256/WW];
RC5_WORD A, B;
LL = (keylen + WW - 1) / WW;
bzero(L, sizeof(RC5_WORD)*LL);
for (i = 0; i < keylen; i++) {
t = (key[i] & 0xff) << (8*(i%4));
L[i/WW] = L[i/WW] + t;
}
T = 2 * (rounds + 1);
e_key[0] = Pw;
for (i = 1; i < T; i++)
e_key[i] = e_key[i-1] + Qw;
i = j = 0;
A = B = 0;
if (LL > T)
k = 3 * LL;
else
k = 3 * T;
for (; k > 0; k--) {
A = ROTL(e_key[i]+A+B, 3, W);
e_key[i] = A;
B = ROTL(L[j]+A+B, A+B, W);
L[j] = B;
i = (i + 1) % T;
j = (j + 1) % LL;
}
}
/*
*
*/
void
rc5_encrypt_round16(out, in, e_key)
u_int8_t *out;
const u_int8_t *in;
const RC5_WORD *e_key;
{
RC5_WORD A, B;
const RC5_WORD *e_keyA, *e_keyB;
A = in[0] & 0xff;
A += (in[1] & 0xff) << 8;
A += (in[2] & 0xff) << 16;
A += (in[3] & 0xff) << 24;
B = in[4] & 0xff;
B += (in[5] & 0xff) << 8;
B += (in[6] & 0xff) << 16;
B += (in[7] & 0xff) << 24;
e_keyA = e_key;
e_keyB = e_key + 1;
A += *e_keyA; e_keyA += 2;
B += *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 4 */
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 8 */
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 12 */
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2;
A = ROTL(A^B, B, W) + *e_keyA; e_keyA += 2;
B = ROTL(B^A, A, W) + *e_keyB; e_keyB += 2; /* round 16 */
out[0] = A & 0xff;
out[1] = (A >> 8) & 0xff;
out[2] = (A >> 16) & 0xff;
out[3] = (A >> 24) & 0xff;
out[4] = B & 0xff;
out[5] = (B >> 8) & 0xff;
out[6] = (B >> 16) & 0xff;
out[7] = (B >> 24) & 0xff;
}
/*
*
*/
void
rc5_decrypt_round16(out, in, e_key)
u_int8_t *out;
const u_int8_t *in;
const RC5_WORD *e_key;
{
RC5_WORD A, B;
const RC5_WORD *e_keyA, *e_keyB;
A = in[0] & 0xff;
A += (in[1] & 0xff) << 8;
A += (in[2] & 0xff) << 16;
A += (in[3] & 0xff) << 24;
B = in[4] & 0xff;
B += (in[5] & 0xff) << 8;
B += (in[6] & 0xff) << 16;
B += (in[7] & 0xff) << 24;
e_keyA = e_key + 2*16;
e_keyB = e_key + 2*16 + 1;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 4 */
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 8 */
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 12 */
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2;
B = ROTR(B-*e_keyB, A, W) ^ A; e_keyB -= 2;
A = ROTR(A-*e_keyA, B, W) ^ B; e_keyA -= 2; /* round 16 */
B = B - *e_keyB;
A = A - *e_keyA;
out[0] = A & 0xff;
out[1] = (A >> 8) & 0xff;
out[2] = (A >> 16) & 0xff;
out[3] = (A >> 24) & 0xff;
out[4] = B & 0xff;
out[5] = (B >> 8) & 0xff;
out[6] = (B >> 16) & 0xff;
out[7] = (B >> 24) & 0xff;
}

86
sys/crypto/rc5/rc5.h Normal file
View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _RFC2040_RC5_H_
#define _RFC2040_RC5_H_
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
/*
* if RC5_WORD change, W also may be changed.
*/
typedef u_int32_t RC5_WORD;
#define W (32)
#define WW (W / 8)
#define ROT_MASK (W - 1)
#define BB ((2 * W) / 8)
#define SHLL(x, s) ((RC5_WORD)((x) << ((s)&ROT_MASK)))
#define SHLR(x, s, w) ((RC5_WORD)((x) >> ((w)-((s)&ROT_MASK))))
#define SHRL(x, s, w) ((RC5_WORD)((x) << ((w)-((s)&ROT_MASK))))
#define SHRR(x, s) ((RC5_WORD)((x) >> ((s)&ROT_MASK)))
#define ROTL(x, s, w) ((RC5_WORD)(SHLL((x), (s))|SHLR((x), (s), (w))))
#define ROTR(x, s, w) ((RC5_WORD)(SHRL((x), (s), (w))|SHRR((x), (s))))
#define P16 0xb7e1
#define Q16 0x9e37
#define P32 0xb7e15163
#define Q32 0x9e3779b9
#define P64 0xb7e151628aed2a6b
#define Q64 0x9e3779b97f4a7c15
#if W == 16
#define Pw P16
#define Qw Q16
#elif W == 32
#define Pw P32
#define Qw Q32
#elif W == 64
#define Pw P64
#define Qw Q64
#endif
#define RC5_ENCRYPT 1
#define RC5_DECRYPT 0
extern void set_rc5_expandkey __P((RC5_WORD *, u_int8_t *, size_t, int));
extern void rc5_encrypt_round16 __P((u_int8_t *, const u_int8_t *,
const RC5_WORD *));
extern void rc5_decrypt_round16 __P((u_int8_t *, const u_int8_t *,
const RC5_WORD *));
extern void rc5_cbc_process __P((struct mbuf *, size_t, size_t, RC5_WORD *,
u_int8_t *, int));
#endif

211
sys/crypto/rc5/rc5_cbc.c Normal file
View File

@ -0,0 +1,211 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* based on sys/crypto/des/des_cbc.c, rewrote by Tomomi Suzuki
*/
#include <crypto/rc5/rc5.h>
void
rc5_cbc_process(m0, skip, length, e_key, iv, mode)
struct mbuf *m0;
size_t skip;
size_t length;
RC5_WORD *e_key;
u_int8_t *iv;
int mode;
{
u_int8_t inbuf[8], outbuf[8];
struct mbuf *m;
size_t off;
/* sanity check */
if (m0->m_pkthdr.len < skip) {
printf("rc5_cbc_process: mbuf length < skip\n");
return;
}
if (m0->m_pkthdr.len < length) {
printf("rc5_cbc_process: mbuf length < encrypt length\n");
return;
}
if (m0->m_pkthdr.len < skip + length) {
printf("rc5_cbc_process: mbuf length < "
"skip + encrypt length\n");
return;
}
if (length % 8) {
printf("rc5_cbc_process: length(%lu)is not multipleof 8\n",
(u_long)length);
return;
}
m = m0;
off = 0;
/* skip over the header */
while (skip) {
if (!m)
panic("rc5_cbc_process: mbuf chain?\n");
if (m->m_len <= skip) {
skip -= m->m_len;
m = m->m_next;
off = 0;
} else {
off = skip;
skip = 0;
}
}
/* copy iv into outbuf for XOR (encrypt) */
bcopy(iv, outbuf, 8);
/*
* encrypt/decrypt packet
*/
while (length > 0) {
int i;
if (!m)
panic("rc5_cbc_process: mbuf chain?\n");
/*
* copy the source into input buffer.
* don't update off or m, since we need to use them
* later.
*/
if (off + 8 <= m->m_len)
bcopy(mtod(m, u_int8_t *) + off, &inbuf[0], 8);
else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *in;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
in = &inbuf[0];
while (in - &inbuf[0] < 8) {
if (!p) {
panic("rc5_cbc_process: "
"mbuf chain?\n");
}
*in++ = *p++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
}
/* encrypt/decrypt */
switch (mode) {
case RC5_ENCRYPT:
/* XOR */
for (i = 0; i < 8; i++)
inbuf[i] ^= outbuf[i];
/* encrypt */
rc5_encrypt_round16(outbuf, inbuf, e_key);
break;
case RC5_DECRYPT:
/* decrypt */
rc5_decrypt_round16(outbuf, inbuf, e_key);
/* XOR */
for (i = 0; i < 8; i++)
outbuf[i] ^= iv[i];
/* copy inbuf into iv for next XOR */
bcopy(inbuf, iv, 8);
break;
}
/*
* copy the output buffer into the result.
* need to update off and m.
*/
if (off + 8 < m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
off += 8;
} else if (off + 8 == m->m_len) {
bcopy(&outbuf[0], mtod(m, u_int8_t *) + off, 8);
do {
m = m->m_next;
} while (m && !m->m_len);
off = 0;
} else {
struct mbuf *n;
size_t noff;
u_int8_t *p;
u_int8_t *out;
n = m;
noff = off;
p = mtod(n, u_int8_t *) + noff;
out = &outbuf[0];
while (out - &outbuf[0] < 8) {
if (!p) {
panic("rc5_cbc_process: "
"mbuf chain?\n");
}
*p++ = *out++;
noff++;
if (noff < n->m_len)
continue;
do {
n = n->m_next;
} while (n && !n->m_len);
noff = 0;
if (n)
p = mtod(n, u_int8_t *) + noff;
else
p = NULL;
}
m = n;
off = noff;
}
length -= 8;
}
}

275
sys/crypto/sha1.c Normal file
View File

@ -0,0 +1,275 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <crypto/sha1.h>
/* sanity check */
#if BYTE_ORDER != BIG_ENDIAN
# if BYTE_ORDER != LITTLE_ENDIAN
# define unsupported 1
# endif
#endif
#ifndef unsupported
/* constant table */
static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
#define K(t) _K[(t) / 20]
#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
#define F1(b, c, d) (((b) ^ (c)) ^ (d))
#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
#define F3(b, c, d) (((b) ^ (c)) ^ (d))
#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
#define H(n) (ctxt->h.b32[(n)])
#define COUNT (ctxt->count)
#define BCOUNT (ctxt->c.b64[0] / 8)
#define W(n) (ctxt->m.b32[(n)])
#define PUTBYTE(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
ctxt->c.b64[0] += 8; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
#define PUTPAD(x) { \
ctxt->m.b8[(COUNT % 64)] = (x); \
COUNT++; \
COUNT %= 64; \
if (COUNT % 64 == 0) \
sha1_step(ctxt); \
}
static void sha1_step __P((struct sha1_ctxt *));
static void
sha1_step(ctxt)
struct sha1_ctxt *ctxt;
{
u_int32_t a, b, c, d, e;
size_t t, s;
u_int32_t tmp;
#if BYTE_ORDER == LITTLE_ENDIAN
struct sha1_ctxt tctxt;
bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
#endif
a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
for (t = 0; t < 20; t++) {
s = t & 0x0f;
if (t >= 16) {
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
}
tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 20; t < 40; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 40; t < 60; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
for (t = 60; t < 80; t++) {
s = t & 0x0f;
W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
e = d; d = c; c = S(30, b); b = a; a = tmp;
}
H(0) = H(0) + a;
H(1) = H(1) + b;
H(2) = H(2) + c;
H(3) = H(3) + d;
H(4) = H(4) + e;
bzero(&ctxt->m.b8[0], 64);
}
/*------------------------------------------------------------*/
void
sha1_init(ctxt)
struct sha1_ctxt *ctxt;
{
bzero(ctxt, sizeof(struct sha1_ctxt));
H(0) = 0x67452301;
H(1) = 0xefcdab89;
H(2) = 0x98badcfe;
H(3) = 0x10325476;
H(4) = 0xc3d2e1f0;
}
void
sha1_pad(ctxt)
struct sha1_ctxt *ctxt;
{
size_t padlen; /*pad length in bytes*/
size_t padstart;
PUTPAD(0x80);
padstart = COUNT % 64;
padlen = 64 - padstart;
if (padlen < 8) {
bzero(&ctxt->m.b8[padstart], padlen);
COUNT += padlen;
COUNT %= 64;
sha1_step(ctxt);
padstart = COUNT % 64; /* should be 0 */
padlen = 64 - padstart; /* should be 64 */
}
bzero(&ctxt->m.b8[padstart], padlen - 8);
COUNT += (padlen - 8);
COUNT %= 64;
#if BYTE_ORDER == BIG_ENDIAN
PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
#else
PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
#endif
}
void
sha1_loop(ctxt, input0, len)
struct sha1_ctxt *ctxt;
caddr_t input0;
size_t len;
{
u_int8_t *input;
size_t gaplen;
size_t gapstart;
size_t off;
size_t copysiz;
input = (u_int8_t *)input0;
off = 0;
while (off < len) {
gapstart = COUNT % 64;
gaplen = 64 - gapstart;
copysiz = (gaplen < len - off) ? gaplen : len - off;
bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
COUNT += copysiz;
COUNT %= 64;
ctxt->c.b64[0] += copysiz * 8;
if (COUNT % 64 == 0)
sha1_step(ctxt);
off += copysiz;
}
}
void
sha1_result(ctxt, digest0)
struct sha1_ctxt *ctxt;
caddr_t digest0;
{
u_int8_t *digest;
digest = (u_int8_t *)digest0;
sha1_pad(ctxt);
#if BYTE_ORDER == BIG_ENDIAN
bcopy(&ctxt->h.b8[0], digest, 20);
#else
digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
#endif
}
#endif /*unsupported*/

71
sys/crypto/sha1.h Normal file
View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
* based on: http://csrc.nist.gov/fips/fip180-1.txt
* implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
*/
#ifndef _NETINET6_SHA1_H_
#define _NETINET6_SHA1_H_
struct sha1_ctxt {
union {
u_int8_t b8[20];
u_int32_t b32[5];
} h;
union {
u_int8_t b8[8];
u_int64_t b64[1];
} c;
union {
u_int8_t b8[64];
u_int32_t b32[16];
} m;
u_int8_t count;
};
#if defined(KERNEL) || defined(_KERNEL)
extern void sha1_init __P((struct sha1_ctxt *));
extern void sha1_pad __P((struct sha1_ctxt *));
extern void sha1_loop __P((struct sha1_ctxt *, caddr_t, size_t));
extern void sha1_result __P((struct sha1_ctxt *, caddr_t));
/* compatibilty with other SHA1 source codes */
typedef struct sha1_ctxt SHA1_CTX;
#define SHA1Init(x) sha1_init((x))
#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
#define SHA1Final(x, y) sha1_result((y), (x))
#endif
#define SHA1_RESULTLEN (160/8)
#endif /*_NETINET6_SHA1_H_*/

View File

@ -367,6 +367,10 @@ options ROOTDEVNAME=\"da0s2e\"
#
options INET #Internet communications protocols
options INET6 #IPv6 communications protocols
options IPSEC #IP security
options IPSEC_ESP #IP security (crypto; define w/ IPSEC)
options IPSEC_IPV6FWD #IP security tunnel for IPv6
options IPSEC_DEBUG #debug for IP security
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)

View File

@ -367,6 +367,10 @@ options ROOTDEVNAME=\"da0s2e\"
#
options INET #Internet communications protocols
options INET6 #IPv6 communications protocols
options IPSEC #IP security
options IPSEC_ESP #IP security (crypto; define w/ IPSEC)
options IPSEC_IPV6FWD #IP security tunnel for IPv6
options IPSEC_DEBUG #debug for IP security
options IPX #IPX/SPX communications protocols
options IPXIP #IPX in IP encapsulation (not available)

View File

@ -575,7 +575,8 @@ bdg_forward (struct mbuf **m0, struct ifnet *dst)
* pass the pkt to dummynet. Need to include m, dst, rule.
* Dummynet consumes the packet in all cases.
*/
dummynet_io((off & 0xffff), DN_TO_BDG_FWD, m, dst, NULL, 0, rule);
dummynet_io((off & 0xffff), DN_TO_BDG_FWD, m, dst, NULL, 0, rule,
0);
if (canfree) /* dummynet has consumed the original one */
*m0 = NULL ;
return 0 ;

View File

@ -1077,4 +1077,5 @@ rtinit(ifa, cmd, flags)
return (error);
}
SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, route_init, 0);
/* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */
SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);

View File

@ -146,10 +146,11 @@ find_rti(ifp)
}
void
igmp_input(m, iphlen)
igmp_input(m, off, proto)
register struct mbuf *m;
register int iphlen;
int off, proto;
{
register int iphlen = off;
register struct igmp *igmp;
register struct ip *ip;
register int igmplen;
@ -335,7 +336,7 @@ igmp_input(m, iphlen)
* Pass all valid IGMP packets up to any process(es) listening
* on a raw IGMP socket.
*/
rip_input(m, iphlen);
rip_input(m, off, proto);
}
void

View File

@ -86,7 +86,7 @@ struct igmpstat {
#define IGMP_AGE_THRESHOLD 540
void igmp_init __P((void));
void igmp_input __P((struct mbuf *, int));
void igmp_input __P((struct mbuf *, int, int));
void igmp_joingroup __P((struct in_multi *));
void igmp_leavegroup __P((struct in_multi *));
void igmp_fasttimo __P((void));

View File

@ -44,6 +44,7 @@
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
@ -51,8 +52,18 @@
#include <netinet/igmp_var.h>
#include "gif.h"
#if NGIF > 0
#include <net/if_gif.h>
#endif
static MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address");
static int in_mask2len __P((struct in_addr *));
static void in_len2mask __P((struct in_addr *, int));
static int in_lifaddr_ioctl __P((struct socket *, u_long, caddr_t,
struct ifnet *, struct proc *));
static void in_socktrim __P((struct sockaddr_in *));
static int in_ifinit __P((struct ifnet *,
struct in_ifaddr *, struct sockaddr_in *, int));
@ -130,6 +141,44 @@ struct sockaddr_in *ap;
}
}
static int
in_mask2len(mask)
struct in_addr *mask;
{
int x, y;
u_char *p;
p = (u_char *)mask;
for (x = 0; x < sizeof(*mask); x++) {
if (p[x] != 0xff)
break;
}
y = 0;
if (x < sizeof(*mask)) {
for (y = 0; y < 8; y++) {
if ((p[x] & (0x80 >> y)) == 0)
break;
}
}
return x * 8 + y;
}
static void
in_len2mask(mask, len)
struct in_addr *mask;
int len;
{
int i;
u_char *p;
p = (u_char *)mask;
bzero(mask, sizeof(*mask));
for (i = 0; i < len / 8; i++)
p[i] = 0xff;
if (len % 8)
p[i] = (0xff00 >> (len % 8)) & 0xff;
}
static int in_interfaces; /* number of external internet interfaces */
/*
@ -154,6 +203,32 @@ in_control(so, cmd, data, ifp, p)
int error, hostIsNew, maskIsNew, s;
u_long i;
#if NGIF > 0
if (ifp && ifp->if_type == IFT_GIF) {
switch (cmd) {
case SIOCSIFPHYADDR:
if (p &&
(error = suser(p)) != 0)
return(error);
case SIOCGIFPSRCADDR:
case SIOCGIFPDSTADDR:
return gif_ioctl(ifp, cmd, data);
}
}
#endif
switch (cmd) {
case SIOCALIFADDR:
case SIOCDLIFADDR:
if (p && (error = suser(p)) != 0)
return error;
/*fall through*/
case SIOCGLIFADDR:
if (!ifp)
return EINVAL;
return in_lifaddr_ioctl(so, cmd, data, ifp, p);
}
/*
* Find address for this interface, if it exists.
*
@ -363,6 +438,184 @@ in_control(so, cmd, data, ifp, p)
return (0);
}
/*
* SIOC[GAD]LIFADDR.
* SIOCGLIFADDR: get first address. (?!?)
* SIOCGLIFADDR with IFLR_PREFIX:
* get first address that matches the specified prefix.
* SIOCALIFADDR: add the specified address.
* SIOCALIFADDR with IFLR_PREFIX:
* EINVAL since we can't deduce hostid part of the address.
* SIOCDLIFADDR: delete the specified address.
* SIOCDLIFADDR with IFLR_PREFIX:
* delete the first address that matches the specified prefix.
* return values:
* EINVAL on invalid parameters
* EADDRNOTAVAIL on prefix match failed/specified address not found
* other values may be returned from in_ioctl()
*/
static int
in_lifaddr_ioctl(so, cmd, data, ifp, p)
struct socket *so;
u_long cmd;
caddr_t data;
struct ifnet *ifp;
struct proc *p;
{
struct if_laddrreq *iflr = (struct if_laddrreq *)data;
struct ifaddr *ifa;
/* sanity checks */
if (!data || !ifp) {
panic("invalid argument to in_lifaddr_ioctl");
/*NOTRECHED*/
}
switch (cmd) {
case SIOCGLIFADDR:
/* address must be specified on GET with IFLR_PREFIX */
if ((iflr->flags & IFLR_PREFIX) == 0)
break;
/*FALLTHROUGH*/
case SIOCALIFADDR:
case SIOCDLIFADDR:
/* address must be specified on ADD and DELETE */
if (iflr->addr.__ss_family != AF_INET)
return EINVAL;
if (iflr->addr.__ss_len != sizeof(struct sockaddr_in))
return EINVAL;
/* XXX need improvement */
if (iflr->dstaddr.__ss_family
&& iflr->dstaddr.__ss_family != AF_INET)
return EINVAL;
if (iflr->dstaddr.__ss_family
&& iflr->dstaddr.__ss_len != sizeof(struct sockaddr_in))
return EINVAL;
break;
default: /*shouldn't happen*/
return EOPNOTSUPP;
}
if (sizeof(struct in_addr) * 8 < iflr->prefixlen)
return EINVAL;
switch (cmd) {
case SIOCALIFADDR:
{
struct in_aliasreq ifra;
if (iflr->flags & IFLR_PREFIX)
return EINVAL;
/* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */
bzero(&ifra, sizeof(ifra));
bcopy(iflr->iflr_name, ifra.ifra_name,
sizeof(ifra.ifra_name));
bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.__ss_len);
if (iflr->dstaddr.__ss_family) { /*XXX*/
bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr,
iflr->dstaddr.__ss_len);
}
ifra.ifra_mask.sin_family = AF_INET;
ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p);
}
case SIOCGLIFADDR:
case SIOCDLIFADDR:
{
struct in_ifaddr *ia;
struct in_addr mask, candidate, match;
struct sockaddr_in *sin;
int cmp;
bzero(&mask, sizeof(mask));
if (iflr->flags & IFLR_PREFIX) {
/* lookup a prefix rather than address. */
in_len2mask(&mask, iflr->prefixlen);
sin = (struct sockaddr_in *)&iflr->addr;
match.s_addr = sin->sin_addr.s_addr;
match.s_addr &= mask.s_addr;
/* if you set extra bits, that's wrong */
if (match.s_addr != sin->sin_addr.s_addr)
return EINVAL;
cmp = 1;
} else {
if (cmd == SIOCGLIFADDR) {
/* on getting an address, take the 1st match */
cmp = 0; /*XXX*/
} else {
/* on deleting an address, do exact match */
in_len2mask(&mask, 32);
sin = (struct sockaddr_in *)&iflr->addr;
match.s_addr = sin->sin_addr.s_addr;
cmp = 1;
}
}
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
if (!cmp)
break;
candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr;
candidate.s_addr &= mask.s_addr;
if (candidate.s_addr == match.s_addr)
break;
}
if (!ifa)
return EADDRNOTAVAIL;
ia = (struct in_ifaddr *)ifa;
if (cmd == SIOCGLIFADDR) {
/* fill in the if_laddrreq structure */
bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len);
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
ia->ia_dstaddr.sin_len);
} else
bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
iflr->prefixlen =
in_mask2len(&ia->ia_sockmask.sin_addr);
iflr->flags = 0; /*XXX*/
return 0;
} else {
struct in_aliasreq ifra;
/* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */
bzero(&ifra, sizeof(ifra));
bcopy(iflr->iflr_name, ifra.ifra_name,
sizeof(ifra.ifra_name));
bcopy(&ia->ia_addr, &ifra.ifra_addr,
ia->ia_addr.sin_len);
if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr,
ia->ia_dstaddr.sin_len);
}
bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr,
ia->ia_sockmask.sin_len);
return in_control(so, SIOCDIFADDR, (caddr_t)&ifra,
ifp, p);
}
}
}
return EOPNOTSUPP; /*just for safety*/
}
/*
* Delete any existing route for an interface.
*/

View File

@ -419,7 +419,7 @@ struct ip_mreq {
#define IPCTL_STATS 12 /* ipstat structure */
#define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */
#define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */
#define IPCTL_KEEPFAITH 15
#define IPCTL_KEEPFAITH 15 /* FAITH IPv4->IPv6 translater ctl */
#define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */
#define IPCTL_MAXID 17

View File

@ -52,12 +52,15 @@
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/in_gif.h>
#ifdef INET6
#include <netinet/ip6.h>
#endif
#include <netinet/ip_var.h>
#include <netinet/in_gif.h>
#include <netinet/ip_ecn.h>
#ifdef INET6
#include <netinet6/ip6_ecn.h>
#endif
#ifdef MROUTING
#include <netinet/ip_mroute.h>
@ -168,6 +171,8 @@ in_gif_output(ifp, family, m, rt)
/* version will be set in ip_output() */
iphdr.ip_ttl = ip_gif_ttl;
iphdr.ip_len = m->m_pkthdr.len + sizeof(struct ip);
if (ifp->if_flags & IFF_LINK1)
ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos);
/* prepend new IP header */
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
@ -200,33 +205,18 @@ in_gif_output(ifp, family, m, rt)
}
}
#ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
#endif /*IPSEC*/
error = ip_output(m, 0, &sc->gif_ro, 0, 0);
return(error);
}
void
#if __STDC__
in_gif_input(struct mbuf *m, ...)
#else
in_gif_input(m, va_alist)
struct mbuf *m;
va_dcl
#endif
in_gif_input(struct mbuf *m, int off, int proto)
{
int off, proto;
struct gif_softc *sc;
struct ifnet *gifp = NULL;
struct ip *ip;
int i, af;
va_list ap;
va_start(ap, m);
off = va_arg(ap, int);
proto = va_arg(ap, int);
va_end(ap);
u_int8_t otos;
ip = mtod(m, struct ip *);
@ -262,7 +252,7 @@ in_gif_input(m, va_alist)
#ifdef MROUTING
/* for backward compatibility */
if (proto == IPPROTO_IPV4) {
ipip_input(m, off);
ipip_input(m, off, proto);
return;
}
#endif /*MROUTING*/
@ -271,6 +261,7 @@ in_gif_input(m, va_alist)
return;
}
otos = ip->ip_tos;
m_adj(m, off);
switch (proto) {
@ -284,12 +275,15 @@ in_gif_input(m, va_alist)
return;
}
ip = mtod(m, struct ip *);
if (gifp->if_flags & IFF_LINK1)
ip_ecn_egress(ECN_ALLOWED, &otos, &ip->ip_tos);
break;
}
#ifdef INET6
case IPPROTO_IPV6:
{
struct ip6_hdr *ip6;
u_int8_t itos;
af = AF_INET6;
if (m->m_len < sizeof(*ip6)) {
m = m_pullup(m, sizeof(*ip6));
@ -297,7 +291,11 @@ in_gif_input(m, va_alist)
return;
}
ip6 = mtod(m, struct ip6_hdr *);
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
if (gifp->if_flags & IFF_LINK1)
ip_ecn_egress(ECN_ALLOWED, &otos, &itos);
ip6->ip6_flow &= ~htonl(0xff << 20);
ip6->ip6_flow |= htonl((u_int32_t)itos << 20);
break;
}
#endif /* INET6 */

View File

@ -36,7 +36,7 @@
extern int ip_gif_ttl;
void in_gif_input __P((struct mbuf *, ...));
void in_gif_input __P((struct mbuf *, int off, int proto));
int in_gif_output __P((struct ifnet *, int, struct mbuf *, struct rtentry *));
#endif /*_NETINET_IN_GIF_H_*/

View File

@ -34,6 +34,7 @@
* $FreeBSD$
*/
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include <sys/param.h>

View File

@ -36,6 +36,8 @@
#include "opt_ipdivert.h"
#include "opt_ipx.h"
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include <sys/param.h>
#include <sys/kernel.h>
@ -59,10 +61,21 @@
#include <netinet/tcp_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/ipprotosw.h>
/*
* TCP/IP protocol family: IP, ICMP, UDP, TCP.
*/
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#ifdef IPSEC_ESP
#include <netinet6/esp.h>
#endif
#endif /* IPSEC */
#include "gif.h"
#if NGIF > 0
#include <netinet/in_gif.h>
@ -80,7 +93,7 @@
extern struct domain inetdomain;
static struct pr_usrreqs nousrreqs;
struct protosw inetsw[] = {
struct ipprotosw inetsw[] = {
{ 0, &inetdomain, 0, 0,
0, 0, 0, 0,
0,
@ -124,6 +137,22 @@ struct protosw inetsw[] = {
0, 0, 0, 0,
&rip_usrreqs
},
#ifdef IPSEC
{ SOCK_RAW, &inetdomain, IPPROTO_AH, PR_ATOMIC|PR_ADDR,
ah4_input, 0, 0, 0,
0,
0, 0, 0, 0,
&nousrreqs
},
#ifdef IPSEC_ESP
{ SOCK_RAW, &inetdomain, IPPROTO_ESP, PR_ATOMIC|PR_ADDR,
esp4_input, 0, 0, 0,
0,
0, 0, 0, 0,
&nousrreqs
},
#endif
#endif /* IPSEC */
#if NGIF > 0
{ SOCK_RAW, &inetdomain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR,
in_gif_input, 0, 0, 0,
@ -199,7 +228,8 @@ extern int in_inithead __P((void **, int));
struct domain inetdomain =
{ AF_INET, "internet", 0, 0, 0,
inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])], 0,
(struct protosw *)inetsw,
(struct protosw *)&inetsw[sizeof(inetsw)/sizeof(inetsw[0])], 0,
in_inithead, 32, sizeof(struct sockaddr_in)
};
@ -213,6 +243,9 @@ SYSCTL_NODE(_net_inet, IPPROTO_ICMP, icmp, CTLFLAG_RW, 0, "ICMP");
SYSCTL_NODE(_net_inet, IPPROTO_UDP, udp, CTLFLAG_RW, 0, "UDP");
SYSCTL_NODE(_net_inet, IPPROTO_TCP, tcp, CTLFLAG_RW, 0, "TCP");
SYSCTL_NODE(_net_inet, IPPROTO_IGMP, igmp, CTLFLAG_RW, 0, "IGMP");
#ifdef IPSEC
SYSCTL_NODE(_net_inet, IPPROTO_AH, ipsec, CTLFLAG_RW, 0, "IPSEC");
#endif /* IPSEC */
SYSCTL_NODE(_net_inet, IPPROTO_RAW, raw, CTLFLAG_RW, 0, "RAW");
#ifdef IPDIVERT
SYSCTL_NODE(_net_inet, IPPROTO_DIVERT, div, CTLFLAG_RW, 0, "DIVERT");

View File

@ -89,6 +89,10 @@ struct ip {
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
#define IPTOS_MINCOST 0x02
/* ECN bits proposed by Sally Floyd */
#define IPTOS_CE 0x01 /* congestion experienced */
#define IPTOS_ECT 0x02 /* ECN-capable transport */
/*
* Definitions for IP precedence (also in ip_tos) (hopefully unused)

View File

@ -36,6 +36,7 @@
#include "opt_inet.h"
#include "opt_ipfw.h"
#include "opt_ipdivert.h"
#include "opt_ipsec.h"
#ifndef INET
#error "IPDIVERT requires INET."
@ -126,7 +127,7 @@ div_init(void)
* with that protocol number to enter the system from the outside.
*/
void
div_input(struct mbuf *m, int hlen)
div_input(struct mbuf *m, int off, int proto)
{
ipstat.ips_noproto++;
m_freem(m);
@ -296,7 +297,8 @@ div_output(so, m, addr, control)
ipstat.ips_rawout++; /* XXX */
error = ip_output(m, inp->inp_options, &inp->inp_route,
(so->so_options & SO_DONTROUTE) |
IP_ALLOWBROADCAST | IP_RAWOUTPUT, inp->inp_moptions);
IP_ALLOWBROADCAST | IP_RAWOUTPUT | IP_SOCKINMRCVIF,
inp->inp_moptions);
} else {
struct ifaddr *ifa;
@ -344,12 +346,12 @@ div_attach(struct socket *so, int proto, struct proc *p)
if (p && (error = suser(p)) != 0)
return error;
error = soreserve(so, div_sendspace, div_recvspace);
if (error)
return error;
s = splnet();
error = in_pcballoc(so, &divcbinfo, p);
splx(s);
if (error)
return error;
error = soreserve(so, div_sendspace, div_recvspace);
if (error)
return error;
inp = (struct inpcb *)so->so_pcb;
@ -358,6 +360,13 @@ div_attach(struct socket *so, int proto, struct proc *p)
/* The socket is always "connected" because
we always know "where" to send the packet */
so->so_state |= SS_ISCONNECTED;
#ifdef IPSEC
error = ipsec_init_policy(so, &inp->inp_sp);
if (error != 0) {
in_pcbdetach(inp);
return error;
}
#endif /*IPSEC*/
return 0;
}
@ -414,7 +423,7 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
struct mbuf *control, struct proc *p)
{
/* Packet must have a header (but that's about it) */
if (m->m_len < sizeof (struct ip) ||
if (m->m_len < sizeof (struct ip) &&
(m = m_pullup(m, sizeof (struct ip))) == 0) {
ipstat.ips_toosmall++;
m_freem(m);

View File

@ -220,7 +220,7 @@ dn_move(struct dn_pipe *pipe, int immediate)
struct route *ro = &(pkt->ro) ;
(void)ip_output((struct mbuf *)pkt, (struct mbuf *)pkt->ifp,
ro, pkt->dn_dst, NULL);
ro, pkt->flags, NULL);
rt_unref (ro->ro_rt) ;
}
break ;
@ -290,7 +290,7 @@ int
dummynet_io(int pipe_nr, int dir,
struct mbuf *m, struct ifnet *ifp, struct route *ro,
struct sockaddr_in *dst,
struct ip_fw_chain *rule)
struct ip_fw_chain *rule, int flags)
{
struct dn_pkt *pkt;
struct dn_pipe *pipe;
@ -359,6 +359,12 @@ dummynet_io(int pipe_nr, int dir,
dst = (struct sockaddr_in *)&(pkt->ro.ro_dst) ;
pkt->dn_dst = dst; /* XXX this can't be right! */
/*
* 'flags' also need to be kept for later packet treatment
* such as IPSEC. IPSEC consider sending packet's m->m_pkthdr.rcvif
* as 'socket *' at ip_output(), if IP_SOCKINMRCVIF is set.
*/
pkt->flags = flags;
}
if (pipe->r.head == NULL)
pipe->r.head = pkt;

View File

@ -44,6 +44,7 @@ struct dn_pkt {
int delay; /* stays queued until delay=0 */
struct ifnet *ifp; /* interface, for ip_output */
struct route ro; /* route, for ip_output. MUST COPY */
int flags; /* flags, for ip_output */
#ifdef DUMMYNET_DEBUG
struct timeval beg, mid; /* testing only */
@ -109,7 +110,7 @@ void dn_rule_delete(void *r); /* used in ip_fw.c */
int dummynet_io(int pipe, int dir,
struct mbuf *m, struct ifnet *ifp, struct route *ro,
struct sockaddr_in * dst,
struct ip_fw_chain *rule);
struct ip_fw_chain *rule, int flags);
#endif /* KERNEL */
#endif /* _IP_DUMMYNET_H */

149
sys/netinet/ip_ecn.c Normal file
View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ip_ecn.c,v 1.2 1999/07/30 12:17:15 itojun Exp $
* $FreeBSD$
*/
/*
* ECN consideration on tunnel ingress/egress operation.
* http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/errno.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#endif
#ifdef INET6
#ifndef INET
#include <netinet/in.h>
#endif
#include <netinet/ip6.h>
#endif
#include <netinet/ip_ecn.h>
#ifdef INET6
#include <netinet6/ip6_ecn.h>
#endif
/*
* modify outer ECN (TOS) field on ingress operation (tunnel encapsulation).
* call it after you've done the default initialization/copy for the outer.
*/
void
ip_ecn_ingress(mode, outer, inner)
int mode;
u_int8_t *outer;
u_int8_t *inner;
{
if (!outer || !inner)
panic("NULL pointer passed to ip_ecn_ingress");
switch (mode) {
case ECN_ALLOWED: /* ECN allowed */
*outer &= ~IPTOS_CE;
break;
case ECN_FORBIDDEN: /* ECN forbidden */
*outer &= ~(IPTOS_ECT | IPTOS_CE);
break;
case ECN_NOCARE: /* no consideration to ECN */
break;
}
}
/*
* modify inner ECN (TOS) field on egress operation (tunnel decapsulation).
* call it after you've done the default initialization/copy for the inner.
*/
void
ip_ecn_egress(mode, outer, inner)
int mode;
u_int8_t *outer;
u_int8_t *inner;
{
if (!outer || !inner)
panic("NULL pointer passed to ip_ecn_egress");
switch (mode) {
case ECN_ALLOWED:
if (*outer & IPTOS_CE)
*inner |= IPTOS_CE;
break;
case ECN_FORBIDDEN: /* ECN forbidden */
case ECN_NOCARE: /* no consideration to ECN */
break;
}
}
#ifdef INET6
void
ip6_ecn_ingress(mode, outer, inner)
int mode;
u_int32_t *outer;
u_int32_t *inner;
{
u_int8_t outer8, inner8;
if (!outer || !inner)
panic("NULL pointer passed to ip6_ecn_ingress");
outer8 = (ntohl(*outer) >> 20) & 0xff;
inner8 = (ntohl(*inner) >> 20) & 0xff;
ip_ecn_ingress(mode, &outer8, &inner8);
*outer &= ~htonl(0xff << 20);
*outer |= htonl((u_int32_t)outer8 << 20);
}
void
ip6_ecn_egress(mode, outer, inner)
int mode;
u_int32_t *outer;
u_int32_t *inner;
{
u_int8_t outer8, inner8;
if (!outer || !inner)
panic("NULL pointer passed to ip6_ecn_egress");
outer8 = (ntohl(*outer) >> 20) & 0xff;
inner8 = (ntohl(*inner) >> 20) & 0xff;
ip_ecn_egress(mode, &outer8, &inner8);
*inner &= ~htonl(0xff << 20);
*inner |= htonl((u_int32_t)inner8 << 20);
}
#endif

44
sys/netinet/ip_ecn.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ip_ecn.h,v 1.2 1999/08/19 12:57:44 itojun Exp $
* $FreeBSD$
*/
/*
* ECN consideration on tunnel ingress/egress operation.
* http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
*/
#define ECN_ALLOWED 1 /* ECN allowed */
#define ECN_FORBIDDEN 0 /* ECN forbidden */
#define ECN_NOCARE (-1) /* no consideration to ECN */
#if defined(KERNEL) || defined(_KERNEL)
extern void ip_ecn_ingress __P((int, u_int8_t *, u_int8_t *));
extern void ip_ecn_egress __P((int, u_int8_t *, u_int8_t *));
#endif

View File

@ -34,6 +34,8 @@
* $FreeBSD$
*/
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -55,6 +57,16 @@
#include <netinet/ip_var.h>
#include <netinet/icmp_var.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#endif
#include "faith.h"
#if defined(NFAITH) && NFAITH > 0
#include <net/if_types.h>
#endif
/*
* ICMP routines: error generation, receive packet processing, and
* routines to turnaround packets back to the originator, and
@ -219,10 +231,11 @@ static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
* Process a received ICMP message.
*/
void
icmp_input(m, hlen)
icmp_input(m, off, proto)
register struct mbuf *m;
int hlen;
int off, proto;
{
int hlen = off;
register struct icmp *icp;
register struct ip *ip = mtod(m, struct ip *);
int icmplen = ip->ip_len;
@ -263,12 +276,36 @@ icmp_input(m, hlen)
m->m_len += hlen;
m->m_data -= hlen;
#if defined(NFAITH) && 0 < NFAITH
if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
/*
* Deliver very specific ICMP type only.
*/
switch (icp->icmp_type) {
case ICMP_UNREACH:
case ICMP_TIMXCEED:
break;
default:
goto freeit;
}
}
#endif
#ifdef ICMPPRINTFS
if (icmpprintfs)
printf("icmp_input, type %d code %d\n", icp->icmp_type,
icp->icmp_code);
#endif
#ifdef IPSEC
/* drop it if it does not match the policy */
/* XXX Is there meaning of check in here ? */
if (ipsec4_in_reject(m, NULL)) {
ipsecstat.in_polvio++;
goto freeit;
}
#endif
/*
* Message type specific processing.
*/
@ -394,6 +431,10 @@ icmp_input(m, hlen)
}
#endif
/*
* XXX if the packet contains [IPv4 AH TCP], we can't make a
* notification to TCP layer.
*/
ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
if (ctlfunc)
(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
@ -518,6 +559,9 @@ icmp_input(m, hlen)
(struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
(struct sockaddr *)&icmpgw, (struct rtentry **)0);
pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
#ifdef IPSEC
key_sa_routechange((struct sockaddr *)&icmpsrc);
#endif
break;
/*
@ -535,7 +579,7 @@ icmp_input(m, hlen)
}
raw:
rip_input(m, hlen);
rip_input(m, off, proto);
return;
freeit:

View File

@ -186,7 +186,7 @@ struct icmp {
#ifdef KERNEL
void icmp_error __P((struct mbuf *, int, int, n_long, struct ifnet *));
void icmp_input __P((struct mbuf *, int));
void icmp_input __P((struct mbuf *, int, int));
#endif
#endif

View File

@ -42,6 +42,7 @@
#include "opt_ipdivert.h"
#include "opt_ipfilter.h"
#include "opt_ipstealth.h"
#include "opt_ipsec.h"
#include <stddef.h>
@ -72,10 +73,27 @@
#include <netinet/ip_icmp.h>
#include <machine/in_cksum.h>
#include <netinet/ipprotosw.h>
#include <sys/socketvar.h>
#include <netinet/ip_fw.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#endif
#include "faith.h"
#if defined(NFAITH) && NFAITH > 0
#include <net/if_types.h>
#endif
#ifdef DUMMYNET
#include <netinet/ip_dummynet.h>
#endif
@ -104,12 +122,18 @@ static int ip_acceptsourceroute = 0;
SYSCTL_INT(_net_inet_ip, IPCTL_ACCEPTSOURCEROUTE, accept_sourceroute,
CTLFLAG_RW, &ip_acceptsourceroute, 0,
"Enable accepting source routed IP packets");
static int ip_keepfaith = 0;
SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_RW,
&ip_keepfaith, 0,
"Enable packet capture for FAITH IPv4->IPv6 translater daemon");
#ifdef DIAGNOSTIC
static int ipprintfs = 0;
#endif
extern struct domain inetdomain;
extern struct protosw inetsw[];
extern struct ipprotosw inetsw[];
u_char ip_protox[IPPROTO_MAX];
static int ipqmaxlen = IFQ_MAXLEN;
struct in_ifaddrhead in_ifaddrhead; /* first inet address */
@ -181,10 +205,10 @@ static int ip_dooptions __P((struct mbuf *));
static void ip_forward __P((struct mbuf *, int));
static void ip_freef __P((struct ipq *));
#ifdef IPDIVERT
static struct ip *ip_reass __P((struct mbuf *,
static struct mbuf *ip_reass __P((struct mbuf *,
struct ipq *, struct ipq *, u_int32_t *, u_int16_t *));
#else
static struct ip *ip_reass __P((struct mbuf *, struct ipq *, struct ipq *));
static struct mbuf *ip_reass __P((struct mbuf *, struct ipq *, struct ipq *));
#endif
static struct in_ifaddr *ip_rtaddr __P((struct in_addr));
static void ipintr __P((void));
@ -196,17 +220,17 @@ static void ipintr __P((void));
void
ip_init()
{
register struct protosw *pr;
register struct ipprotosw *pr;
register int i;
TAILQ_INIT(&in_ifaddrhead);
pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
pr = (struct ipprotosw *)pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
if (pr == 0)
panic("ip_init");
for (i = 0; i < IPPROTO_MAX; i++)
ip_protox[i] = pr - inetsw;
for (pr = inetdomain.dom_protosw;
pr < inetdomain.dom_protoswNPROTOSW; pr++)
for (pr = (struct ipprotosw *)inetdomain.dom_protosw;
pr < (struct ipprotosw *)inetdomain.dom_protoswNPROTOSW; pr++)
if (pr->pr_domain->dom_family == PF_INET &&
pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
ip_protox[pr->pr_protocol] = pr - inetsw;
@ -387,7 +411,8 @@ ip_input(struct mbuf *m)
#ifdef DUMMYNET
if ((i & IP_FW_PORT_DYNT_FLAG) != 0) {
/* Send packet to the appropriate pipe */
dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule);
dummynet_io(i&0xffff,DN_TO_IP_IN,m,NULL,NULL,0, rule,
0);
return;
}
#endif
@ -523,6 +548,19 @@ ip_input(struct mbuf *m)
if (ip->ip_dst.s_addr == INADDR_ANY)
goto ours;
#if defined(NFAITH) && 0 < NFAITH
/*
* FAITH(Firewall Aided Internet Translator)
*/
if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) {
if (ip_keepfaith) {
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_ICMP)
goto ours;
}
m_freem(m);
return;
}
#endif
/*
* Not for us; forward if possible and desirable.
*/
@ -546,6 +584,11 @@ ip_input(struct mbuf *m)
* but it's not worth the time; just let them time out.)
*/
if (ip->ip_off & (IP_MF | IP_OFFMASK | IP_RF)) {
#if 0 /*
* Reassembly should be able to treat a mbuf cluster, for later
* operation of contiguous protocol headers on the cluster. (KAME)
*/
if (m->m_flags & M_EXT) { /* XXX */
if ((m = m_pullup(m, hlen)) == 0) {
ipstat.ips_toosmall++;
@ -556,6 +599,7 @@ ip_input(struct mbuf *m)
}
ip = mtod(m, struct ip *);
}
#endif
sum = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
/*
* Look for queue of fragments
@ -616,12 +660,12 @@ ip_input(struct mbuf *m)
ipstat.ips_fragments++;
m->m_pkthdr.header = ip;
#ifdef IPDIVERT
ip = ip_reass(m,
m = ip_reass(m,
fp, &ipq[sum], &divert_info, &divert_cookie);
#else
ip = ip_reass(m, fp, &ipq[sum]);
m = ip_reass(m, fp, &ipq[sum]);
#endif
if (ip == 0) {
if (m == 0) {
#ifdef IPFIREWALL_FORWARD
ip_fw_fwd_addr = NULL;
#endif
@ -630,7 +674,7 @@ ip_input(struct mbuf *m)
/* Get the length of the reassembled packets header */
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
ipstat.ips_reassembled++;
m = dtom(ip);
ip = mtod(m, struct ip *);
#ifdef IPDIVERT
/* Restore original checksum before diverting packet */
if (divert_info != 0) {
@ -689,11 +733,15 @@ ip_input(struct mbuf *m)
* Switch out to protocol's input routine.
*/
ipstat.ips_delivered++;
(*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen);
{
int off = hlen, nh = ip->ip_p;
(*inetsw[ip_protox[ip->ip_p]].pr_input)(m, off, nh);
#ifdef IPFIREWALL_FORWARD
ip_fw_fwd_addr = NULL; /* tcp needed it */
#endif
return;
}
bad:
#ifdef IPFIREWALL_FORWARD
ip_fw_fwd_addr = NULL;
@ -731,7 +779,7 @@ NETISR_SET(NETISR_IP, ipintr);
* tells us if we need to divert or tee the packet we're building.
*/
static struct ip *
static struct mbuf *
#ifdef IPDIVERT
ip_reass(m, fp, where, divinfo, divcookie)
#else
@ -801,7 +849,7 @@ ip_reass(m, fp, where)
if (i > 0) {
if (i >= ip->ip_len)
goto dropfrag;
m_adj(dtom(ip), i);
m_adj(m, i);
ip->ip_off += i;
ip->ip_len -= i;
}
@ -908,11 +956,11 @@ ip_reass(m, fp, where)
/* some debugging cruft by sklower, below, will go away soon */
if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */
register int plen = 0;
for (t = m; m; m = m->m_next)
plen += m->m_len;
t->m_pkthdr.len = plen;
for (t = m; t; t = t->m_next)
plen += t->m_len;
m->m_pkthdr.len = plen;
}
return (ip);
return (m);
dropfrag:
#ifdef IPDIVERT
@ -1399,6 +1447,9 @@ ip_forward(m, srcrt)
struct mbuf *mcopy;
n_long dest;
struct ifnet *destifp;
#ifdef IPSEC
struct ifnet dummyifp;
#endif
dest = 0;
#ifdef DIAGNOSTIC
@ -1523,8 +1574,61 @@ ip_forward(m, srcrt)
case EMSGSIZE:
type = ICMP_UNREACH;
code = ICMP_UNREACH_NEEDFRAG;
#ifndef IPSEC
if (ipforward_rt.ro_rt)
destifp = ipforward_rt.ro_rt->rt_ifp;
#else
/*
* If the packet is routed over IPsec tunnel, tell the
* originator the tunnel MTU.
* tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
* XXX quickhack!!!
*/
if (ipforward_rt.ro_rt) {
struct secpolicy *sp = NULL;
int ipsecerror;
int ipsechdr;
struct route *ro;
sp = ipsec4_getpolicybyaddr(mcopy,
IPSEC_DIR_OUTBOUND,
IP_FORWARDING,
&ipsecerror);
if (sp == NULL)
destifp = ipforward_rt.ro_rt->rt_ifp;
else {
/* count IPsec header size */
ipsechdr = ipsec4_hdrsiz(mcopy,
IPSEC_DIR_OUTBOUND,
NULL);
/*
* find the correct route for outer IPv4
* header, compute tunnel MTU.
*
* XXX BUG ALERT
* The "dummyifp" code relies upon the fact
* that icmp_error() touches only ifp->if_mtu.
*/
/*XXX*/
destifp = NULL;
if (sp->req != NULL
&& sp->req->sav != NULL
&& sp->req->sav->sah != NULL) {
ro = &sp->req->sav->sah->sa_route;
if (ro->ro_rt && ro->ro_rt->rt_ifp) {
dummyifp.if_mtu =
ro->ro_rt->rt_ifp->if_mtu;
dummyifp.if_mtu -= ipsechdr;
destifp = &dummyifp;
}
}
key_freesp(sp);
}
}
#endif /*IPSEC*/
ipstat.ips_cantfrag++;
break;

View File

@ -117,9 +117,10 @@ _mrt_ioctl(int req, caddr_t data, struct proc *p)
int (*mrt_ioctl)(int, caddr_t, struct proc *) = _mrt_ioctl;
void
rsvp_input(m, iphlen) /* XXX must fixup manually */
rsvp_input(m, off, proto) /* XXX must fixup manually */
struct mbuf *m;
int iphlen;
int off;
int proto;
{
/* Can still get packets with rsvp_on = 0 if there is a local member
* of the group to which the RSVP packet is addressed. But in this
@ -133,15 +134,15 @@ rsvp_input(m, iphlen) /* XXX must fixup manually */
if (ip_rsvpd != NULL) {
if (rsvpdebug)
printf("rsvp_input: Sending packet up old-style socket\n");
rip_input(m, iphlen);
rip_input(m, off, proto);
return;
}
/* Drop the packet */
m_freem(m);
}
void ipip_input(struct mbuf *m, int iphlen) { /* XXX must fixup manually */
rip_input(m, iphlen);
void ipip_input(struct mbuf *m, int off, int proto) { /* XXX must fixup manually */
rip_input(m, off, proto);
}
int (*legal_vif_num)(int) = 0;
@ -1609,12 +1610,13 @@ encap_send(ip, vifp, m)
*/
void
#ifdef MROUTE_LKM
X_ipip_input(m, iphlen)
X_ipip_input(m, off, proto)
#else
ipip_input(m, iphlen)
ipip_input(m, off, proto)
#endif
register struct mbuf *m;
int iphlen;
int off;
int proto;
{
struct ifnet *ifp = m->m_pkthdr.rcvif;
register struct ip *ip = mtod(m, struct ip *);
@ -1624,7 +1626,7 @@ ipip_input(m, iphlen)
register struct vif *vifp;
if (!have_encap_tunnel) {
rip_input(m, iphlen);
rip_input(m, off, proto);
return;
}
/*
@ -2119,9 +2121,10 @@ ip_rsvp_force_done(so)
}
void
rsvp_input(m, iphlen)
rsvp_input(m, off, proto)
struct mbuf *m;
int iphlen;
int off;
int proto;
{
int vifi;
register struct ip *ip = mtod(m, struct ip *);
@ -2147,7 +2150,7 @@ rsvp_input(m, iphlen)
if (ip_rsvpd != NULL) {
if (rsvpdebug)
printf("rsvp_input: Sending packet up old-style socket\n");
rip_input(m, iphlen);
rip_input(m, off, proto); /* xxx */
return;
}

View File

@ -40,6 +40,7 @@
#include "opt_ipdn.h"
#include "opt_ipdivert.h"
#include "opt_ipfilter.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -49,6 +50,7 @@
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/proc.h>
#include <net/if.h>
#include <net/route.h>
@ -60,6 +62,8 @@
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
#include "faith.h"
#ifdef vax
#include <machine/mtpr.h>
#endif
@ -67,6 +71,16 @@
static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options");
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netkey/key.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#endif /*IPSEC*/
#include <netinet/ip_fw.h>
#ifdef DUMMYNET
@ -123,6 +137,11 @@ ip_output(m0, opt, ro, flags, imo)
struct sockaddr_in *dst;
struct in_ifaddr *ia;
int isbroadcast;
#ifdef IPSEC
struct route iproute;
struct socket *so;
struct secpolicy *sp = NULL;
#endif
u_int16_t divert_cookie; /* firewall cookie */
#ifdef IPFIREWALL_FORWARD
int fwd_rewrite_src = 0;
@ -136,6 +155,32 @@ ip_output(m0, opt, ro, flags, imo)
#else
divert_cookie = 0;
#endif
#ifdef IPSEC
/*
* NOTE: If IP_SOCKINMRCVIF flag is set, 'socket *' is kept in
* m->m_pkthdr.rcvif for later IPSEC check. In this case,
* m->m_pkthdr will be NULL cleared after the contents is saved in
* 'so'.
* NULL clearance of rcvif should be natural because the packet should
* have been sent from my own socket and has no rcvif in this case.
* It is also necessary because someone might consider it as
* 'ifnet *', and cause SEGV.
*/
if ((flags & IP_SOCKINMRCVIF) != 0) {
#if defined(IPFIREWALL) && defined(DUMMYNET)
if (m->m_type == MT_DUMMYNET) {
so = (struct socket *)m->m_next->m_pkthdr.rcvif;
m->m_next->m_pkthdr.rcvif = NULL;
} else
#endif
{
so = (struct socket *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
}
} else
so = NULL;
#endif /*IPSEC*/
#if defined(IPFIREWALL) && defined(DUMMYNET)
/*
@ -151,13 +196,12 @@ ip_output(m0, opt, ro, flags, imo)
* they are used to hold ifp, dst and NULL, respectively.
*/
rule = (struct ip_fw_chain *)(m->m_data) ;
dst = (struct sockaddr_in *)((struct dn_pkt *)m)->dn_dst;
m0 = m = m->m_next ;
ip = mtod(m, struct ip *);
dst = (struct sockaddr_in *)flags ;
ifp = (struct ifnet *)opt;
hlen = IP_VHL_HL(ip->ip_vhl) << 2 ;
opt = NULL ;
flags = 0 ; /* XXX is this correct ? */
goto sendit;
} else
rule = NULL ;
@ -455,7 +499,8 @@ ip_output(m0, opt, ro, flags, imo)
* XXX note: if the ifp or ro entry are deleted
* while a pkt is in dummynet, we are in trouble!
*/
dummynet_io(off & 0xffff, DN_TO_IP_OUT, m,ifp,ro,dst,rule);
dummynet_io(off & 0xffff, DN_TO_IP_OUT, m,ifp,ro,dst,rule,
flags);
goto done;
}
#endif
@ -597,6 +642,125 @@ ip_output(m0, opt, ro, flags, imo)
}
pass:
#ifdef IPSEC
/* get SP for this packet */
if (so == NULL)
sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error);
else
sp = ipsec4_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
if (sp == NULL) {
ipsecstat.out_inval++;
goto bad;
}
error = 0;
/* check policy */
switch (sp->policy) {
case IPSEC_POLICY_DISCARD:
/*
* This packet is just discarded.
*/
ipsecstat.out_polvio++;
goto bad;
case IPSEC_POLICY_BYPASS:
case IPSEC_POLICY_NONE:
/* no need to do IPsec. */
goto skip_ipsec;
case IPSEC_POLICY_IPSEC:
if (sp->req == NULL) {
/* XXX should be panic ? */
printf("ip_output: No IPsec request specified.\n");
error = EINVAL;
goto bad;
}
break;
case IPSEC_POLICY_ENTRUST:
default:
printf("ip_output: Invalid policy found. %d\n", sp->policy);
}
ip->ip_len = htons((u_short)ip->ip_len);
ip->ip_off = htons((u_short)ip->ip_off);
ip->ip_sum = 0;
{
struct ipsec_output_state state;
bzero(&state, sizeof(state));
state.m = m;
if (flags & IP_ROUTETOIF) {
state.ro = &iproute;
bzero(&iproute, sizeof(iproute));
} else
state.ro = ro;
state.dst = (struct sockaddr *)dst;
error = ipsec4_output(&state, sp, flags);
m = state.m;
if (flags & IP_ROUTETOIF) {
/*
* if we have tunnel mode SA, we may need to ignore
* IP_ROUTETOIF.
*/
if (state.ro != &iproute || state.ro->ro_rt != NULL) {
flags &= ~IP_ROUTETOIF;
ro = state.ro;
}
} else
ro = state.ro;
dst = (struct sockaddr_in *)state.dst;
if (error) {
/* mbuf is already reclaimed in ipsec4_output. */
m0 = NULL;
switch (error) {
case EHOSTUNREACH:
case ENETUNREACH:
case EMSGSIZE:
case ENOBUFS:
case ENOMEM:
break;
default:
printf("ip4_output (ipsec): error code %d\n", error);
/*fall through*/
case ENOENT:
/* don't show these error codes to the user */
error = 0;
break;
}
goto bad;
}
}
/* be sure to update variables that are affected by ipsec4_output() */
ip = mtod(m, struct ip *);
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
if (ro->ro_rt == NULL) {
if ((flags & IP_ROUTETOIF) == 0) {
printf("ip_output: "
"can't update route after IPsec processing\n");
error = EHOSTUNREACH; /*XXX*/
goto bad;
}
} else {
/* nobody uses ia beyond here */
ifp = ro->ro_rt->rt_ifp;
}
/* make it flipped, again. */
ip->ip_len = ntohs((u_short)ip->ip_len);
ip->ip_off = ntohs((u_short)ip->ip_off);
skip_ipsec:
#endif /*IPSEC*/
/*
* If small enough for interface, can just send directly.
*/
@ -724,6 +888,17 @@ ip_output(m0, opt, ro, flags, imo)
ipstat.ips_fragmented++;
}
done:
#ifdef IPSEC
if (ro == &iproute && ro->ro_rt) {
RTFREE(ro->ro_rt);
ro->ro_rt = NULL;
}
if (sp != NULL) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ip_output call free SP:%p\n", sp));
key_freesp(sp);
}
#endif /* IPSEC */
return (error);
bad:
m_freem(m0);
@ -868,6 +1043,9 @@ ip_ctloutput(so, sopt)
case IP_RECVRETOPTS:
case IP_RECVDSTADDR:
case IP_RECVIF:
#if defined(NFAITH) && NFAITH > 0
case IP_FAITH:
#endif
error = sooptcopyin(sopt, &optval, sizeof optval,
sizeof optval);
if (error)
@ -902,6 +1080,12 @@ ip_ctloutput(so, sopt)
case IP_RECVIF:
OPTSET(INP_RECVIF);
break;
#if defined(NFAITH) && NFAITH > 0
case IP_FAITH:
OPTSET(INP_FAITH);
break;
#endif
}
break;
#undef OPTSET
@ -943,6 +1127,28 @@ ip_ctloutput(so, sopt)
}
break;
#ifdef IPSEC
case IP_IPSEC_POLICY:
{
caddr_t req;
int priv;
struct mbuf *m;
int optname;
if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
break;
if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
break;
priv = (sopt->sopt_p != NULL &&
suser(sopt->sopt_p) != 0) ? 0 : 1;
req = mtod(m, caddr_t);
optname = sopt->sopt_name;
error = ipsec4_set_policy(inp, optname, req, priv);
m_freem(m);
break;
}
#endif /*IPSEC*/
default:
error = ENOPROTOOPT;
break;
@ -969,6 +1175,9 @@ ip_ctloutput(so, sopt)
case IP_RECVDSTADDR:
case IP_RECVIF:
case IP_PORTRANGE:
#if defined(NFAITH) && NFAITH > 0
case IP_FAITH:
#endif
switch (sopt->sopt_name) {
case IP_TOS:
@ -1005,6 +1214,12 @@ ip_ctloutput(so, sopt)
else
optval = 0;
break;
#if defined(NFAITH) && NFAITH > 0
case IP_FAITH:
optval = OPTBIT(INP_FAITH);
break;
#endif
}
error = sooptcopyout(sopt, &optval, sizeof optval);
break;
@ -1018,6 +1233,22 @@ ip_ctloutput(so, sopt)
error = ip_getmoptions(sopt, inp->inp_moptions);
break;
#ifdef IPSEC
case IP_IPSEC_POLICY:
{
struct mbuf *m;
caddr_t req = NULL;
if (m != 0)
req = mtod(m, caddr_t);
error = ipsec4_get_policy(sotoinpcb(so), req, &m);
if (error == 0)
error = soopt_mcopyout(sopt, m); /* XXX */
m_freem(m);
break;
}
#endif /*IPSEC*/
default:
error = ENOPROTOOPT;
break;

View File

@ -131,6 +131,9 @@ struct ipstat {
#define IP_RAWOUTPUT 0x2 /* raw ip header exists */
#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
#define IP_SOCKINMRCVIF 0x100 /* IPSEC hack;
* socket pointer in sending
* packet's m_pkthdr.rcvif */
struct ip;
struct inpcb;
@ -166,10 +169,10 @@ void ip_stripoptions __P((struct mbuf *, struct mbuf *));
int rip_ctloutput __P((struct socket *, struct sockopt *));
void rip_ctlinput __P((int, struct sockaddr *, void *));
void rip_init __P((void));
void rip_input __P((struct mbuf *, int));
void rip_input __P((struct mbuf *, int, int));
int rip_output __P((struct mbuf *, struct socket *, u_long));
void ipip_input __P((struct mbuf *, int));
void rsvp_input __P((struct mbuf *, int));
void ipip_input __P((struct mbuf *, int, int));
void rsvp_input __P((struct mbuf *, int, int));
int ip_rsvp_init __P((struct socket *));
int ip_rsvp_done __P((void));
int ip_rsvp_vif_init __P((struct socket *, struct sockopt *));
@ -178,7 +181,7 @@ void ip_rsvp_force_done __P((struct socket *));
#ifdef IPDIVERT
void div_init __P((void));
void div_input __P((struct mbuf *, int));
void div_input __P((struct mbuf *, int, int));
void divert_packet __P((struct mbuf *, int, int));
extern struct pr_usrreqs div_usrreqs;
extern u_int16_t ip_divert_cookie;

103
sys/netinet/ipprotosw.h Normal file
View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*-
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)protosw.h 8.1 (Berkeley) 6/2/93
* $FreeBSD$
*/
#ifndef _NETINET_IPPROTOSW_H_
#define _NETINET_IPPROTOSW_H_
/* Forward declare these structures referenced from prototypes below. */
struct mbuf;
struct proc;
struct sockaddr;
struct socket;
struct sockopt;
struct ipprotosw {
short pr_type; /* socket type used for */
struct domain *pr_domain; /* domain protocol a member of */
short pr_protocol; /* protocol number */
short pr_flags; /* see below */
/* protocol-protocol hooks */
void (*pr_input) __P((struct mbuf *, int off, int proto));
/* input to protocol (from below) */
int (*pr_output) __P((struct mbuf *m, struct socket *so));
/* output to protocol (from above) */
void (*pr_ctlinput)__P((int, struct sockaddr *, void *));
/* control input (from below) */
int (*pr_ctloutput)__P((struct socket *, struct sockopt *));
/* control output (from above) */
/* user-protocol hook */
void *pr_ousrreq;
/* utility hooks */
void (*pr_init) __P((void)); /* initialization hook */
void (*pr_fasttimo) __P((void));
/* fast timeout (200ms) */
void (*pr_slowtimo) __P((void));
/* slow timeout (500ms) */
void (*pr_drain) __P((void));
/* flush any excess space possible */
struct pr_usrreqs *pr_usrreqs; /* supersedes pr_usrreq() */
};
#endif /* !_NETINET_IPPROTOSW_H_ */

View File

@ -34,6 +34,9 @@
* $FreeBSD$
*/
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@ -61,6 +64,10 @@
#include <netinet/ip_fw.h>
#ifdef IPSEC
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
#include "opt_ipdn.h"
#ifdef DUMMYNET
#include <netinet/ip_dummynet.h>
@ -105,9 +112,9 @@ static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
* mbuf chain.
*/
void
rip_input(m, iphlen)
rip_input(m, off, proto)
struct mbuf *m;
int iphlen;
int off, proto;
{
register struct ip *ip = mtod(m, struct ip *);
register struct inpcb *inp;
@ -115,8 +122,12 @@ rip_input(m, iphlen)
struct mbuf *opts = 0;
ripsrc.sin_addr = ip->ip_src;
for (inp = ripcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {
if (inp->inp_ip_p && inp->inp_ip_p != ip->ip_p)
LIST_FOREACH(inp, &ripcb, inp_list) {
#ifdef INET6
if ((inp->inp_vflag & INP_IPV4) == 0)
continue;
#endif
if (inp->inp_ip_p && inp->inp_ip_p != proto)
continue;
if (inp->inp_laddr.s_addr &&
inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
@ -215,7 +226,13 @@ rip_output(m, so, dst)
flags |= IP_RAWOUTPUT;
ipstat.ips_rawout++;
}
return (ip_output(m, inp->inp_options, &inp->inp_route, flags,
#ifdef IPSEC
m->m_pkthdr.rcvif = (struct ifnet *)so; /*XXX*/
#endif /*IPSEC*/
return (ip_output(m, inp->inp_options, &inp->inp_route,
flags | IP_SOCKINMRCVIF,
inp->inp_moptions));
}
@ -431,16 +448,24 @@ rip_attach(struct socket *so, int proto, struct proc *p)
if (p && (error = suser(p)) != 0)
return error;
error = soreserve(so, rip_sendspace, rip_recvspace);
if (error)
return error;
s = splnet();
error = in_pcballoc(so, &ripcbinfo, p);
splx(s);
if (error)
return error;
error = soreserve(so, rip_sendspace, rip_recvspace);
if (error)
return error;
inp = (struct inpcb *)so->so_pcb;
inp->inp_vflag |= INP_IPV4;
inp->inp_ip_p = proto;
#ifdef IPSEC
error = ipsec_init_policy(so, &inp->inp_sp);
if (error != 0) {
in_pcbdetach(inp);
return error;
}
#endif /*IPSEC*/
return 0;
}

View File

@ -273,10 +273,11 @@ tcp_reass(tp, ti, m)
* protocol specification dated September, 1981 very closely.
*/
void
tcp_input(m, iphlen)
tcp_input(m, off0, proto)
register struct mbuf *m;
int iphlen;
int off0, proto;
{
int iphlen = off0;
register struct tcpiphdr *ti;
register struct inpcb *inp;
u_char *optp = NULL;

View File

@ -273,10 +273,11 @@ tcp_reass(tp, ti, m)
* protocol specification dated September, 1981 very closely.
*/
void
tcp_input(m, iphlen)
tcp_input(m, off0, proto)
register struct mbuf *m;
int iphlen;
int off0, proto;
{
int iphlen = off0;
register struct tcpiphdr *ti;
register struct inpcb *inp;
u_char *optp = NULL;

View File

@ -34,6 +34,7 @@
* $FreeBSD$
*/
#include "opt_ipsec.h"
#include "opt_tcpdebug.h"
#include <sys/param.h>
@ -63,6 +64,10 @@
#include <netinet/tcp_debug.h>
#endif
#ifdef IPSEC
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
/*
* TCP protocol interface to socket abstraction.
*/
@ -731,6 +736,13 @@ tcp_attach(so, p)
if (error)
return (error);
inp = sotoinpcb(so);
#ifdef IPSEC
error = ipsec_init_policy(so, &inp->inp_sp);
if (error) {
in_pcbdetach(inp);
return (error);
}
#endif /*IPSEC*/
inp->inp_vflag |= INP_IPV4;
tp = tcp_newtcpcb(inp);
if (tp == 0) {

View File

@ -361,7 +361,7 @@ void tcp_fasttimo __P((void));
struct rmxp_tao *
tcp_gettaocache __P((struct inpcb *));
void tcp_init __P((void));
void tcp_input __P((struct mbuf *, int));
void tcp_input __P((struct mbuf *, int, int));
void tcp_mss __P((struct tcpcb *, int));
int tcp_mssopt __P((struct tcpcb *));
void tcp_mtudisc __P((struct inpcb *, int));

View File

@ -34,6 +34,7 @@
* $FreeBSD$
*/
#include "opt_ipsec.h"
#include "opt_inet6.h"
#include <sys/param.h>
@ -705,7 +706,8 @@ udp_output(inp, m, addr, control, p)
#endif /*IPSEC*/
error = ip_output(m, inp->inp_options, &inp->inp_route,
inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
(inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST))
| IP_SOCKINMRCVIF,
inp->inp_moptions);
if (addr) {

88
sys/netinet6/ah.h Normal file
View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1826/2402 authentication header.
*/
#ifndef _NETINET6_AH_H_
#define _NETINET6_AH_H_
struct secasvar;
struct ah {
u_int8_t ah_nxt; /* Next Header */
u_int8_t ah_len; /* Length of data, in 32bit */
u_int16_t ah_reserve; /* Reserved for future use */
u_int32_t ah_spi; /* Security parameter index */
/* variable size, 32bit bound*/ /* Authentication data */
};
struct newah {
u_int8_t ah_nxt; /* Next Header */
u_int8_t ah_len; /* Length of data + 1, in 32bit */
u_int16_t ah_reserve; /* Reserved for future use */
u_int32_t ah_spi; /* Security parameter index */
u_int32_t ah_seq; /* Sequence number field */
/* variable size, 32bit bound*/ /* Authentication data */
};
struct ah_algorithm_state {
struct secasvar *sav;
void* foo; /*per algorithm data - maybe*/
};
struct ah_algorithm {
int (*sumsiz) __P((struct secasvar *));
int (*mature) __P((struct secasvar *));
int keymin; /* in bits */
int keymax; /* in bits */
void (*init) __P((struct ah_algorithm_state *, struct secasvar *));
void (*update) __P((struct ah_algorithm_state *, caddr_t, size_t));
void (*result) __P((struct ah_algorithm_state *, caddr_t));
};
#define AH_MAXSUMSIZE 16
#ifdef KERNEL
extern struct ah_algorithm ah_algorithms[];
/* cksum routines */
extern int ah_hdrlen __P((struct secasvar *));
extern size_t ah_hdrsiz __P((struct ipsecrequest *));
extern void ah4_input __P((struct mbuf *, int, int));
extern int ah4_output __P((struct mbuf *, struct ipsecrequest *));
extern int ah4_calccksum __P((struct mbuf *, caddr_t,
struct ah_algorithm *, struct secasvar *));
#endif /*KERNEL*/
#endif /*_NETINET6_AH_H_*/

49
sys/netinet6/ah6.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1826/2402 authentication header.
*/
#ifndef _NETINET6_AH6_H_
#define _NETINET6_AH6_H_
#ifdef KERNEL
struct secasvar;
extern int ah6_input __P((struct mbuf **, int *, int));
extern int ah6_output __P((struct mbuf *, u_char *, struct mbuf *,
struct ipsecrequest *));
extern int ah6_calccksum __P((struct mbuf *, caddr_t,
struct ah_algorithm *, struct secasvar *));
#endif /*KERNEL*/
#endif /*_NETINET6_AH6_H_*/

1125
sys/netinet6/ah_core.c Normal file

File diff suppressed because it is too large Load Diff

708
sys/netinet6/ah_input.c Normal file
View File

@ -0,0 +1,708 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1826/2402 authentication header.
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/route.h>
#include <net/netisr.h>
#include <machine/cpu.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_ecn.h>
#ifdef INET6
#include <netinet6/ip6_ecn.h>
#endif
#ifdef INET6
#include <netinet6/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/icmp6.h>
#endif
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#ifdef INET6
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#endif
#include <netkey/key.h>
#include <netkey/keydb.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#include <netinet/ipprotosw.h>
#include <machine/stdarg.h>
#include <net/net_osdep.h>
#ifdef INET
extern struct ipprotosw inetsw[];
void
ah4_input(m, off, proto)
struct mbuf *m;
int off, proto;
{
struct ip *ip;
struct ah *ah;
u_int32_t spi;
struct ah_algorithm *algo;
size_t siz;
size_t siz1;
u_char *cksum;
struct secasvar *sav = NULL;
u_int16_t nxt;
size_t hlen;
int s;
if (m->m_len < off + sizeof(struct newah)) {
m = m_pullup(m, off + sizeof(struct newah));
if (!m) {
printf("IPv4 AH input: can't pullup;"
"dropping the packet for simplicity\n");
ipsecstat.in_inval++;
goto fail;
}
}
ip = mtod(m, struct ip *);
ah = (struct ah *)(((caddr_t)ip) + off);
nxt = ah->ah_nxt;
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
/* find the sassoc. */
spi = ah->ah_spi;
if ((sav = key_allocsa(AF_INET,
(caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst,
IPPROTO_AH, spi)) == 0) {
printf("IPv4 AH input: no key association found for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsecstat.in_nosa++;
goto fail;
}
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ah4_input called to allocate SA:%p\n", sav));
if (sav->state != SADB_SASTATE_MATURE
&& sav->state != SADB_SASTATE_DYING) {
printf("IPv4 AH input: non-mature/dying SA found for spi %u; "
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsecstat.in_badspi++;
goto fail;
}
if (sav->alg_auth == SADB_AALG_NONE) {
printf("IPv4 AH input: unspecified authentication algorithm "
"for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsecstat.in_badspi++;
goto fail;
}
algo = &ah_algorithms[sav->alg_auth];
siz = (*algo->sumsiz)(sav);
siz1 = ((siz + 3) & ~(4 - 1));
/*
* sanity checks for header, 1.
*/
{
int sizoff;
sizoff = (sav->flags & SADB_X_EXT_OLD) ? 0 : 4;
if ((ah->ah_len << 2) - sizoff != siz1) {
log(LOG_NOTICE, "sum length mismatch in IPv4 AH input "
"(%d should be %u): %s\n",
(ah->ah_len << 2) - sizoff, (unsigned int)siz1,
ipsec4_logpacketstr(ip, spi));
ipsecstat.in_inval++;
goto fail;
}
if (m->m_len < off + sizeof(struct ah) + sizoff + siz1) {
m = m_pullup(m, off + sizeof(struct ah) + sizoff + siz1);
if (!m) {
printf("IPv4 AH input: can't pullup;"
"dropping the packet for simplicity\n");
ipsecstat.in_inval++;
goto fail;
}
ip = mtod(m, struct ip *);
ah = (struct ah *)(((caddr_t)ip) + off);
}
}
/*
* check for sequence number.
*/
if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
if (ipsec_chkreplay(ntohl(((struct newah *)ah)->ah_seq), sav))
; /*okey*/
else {
ipsecstat.in_ahreplay++;
log(LOG_AUTH, "replay packet in IPv4 AH input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
goto fail;
}
}
/*
* alright, it seems sane. now we are going to check the
* cryptographic checksum.
*/
cksum = malloc(siz1, M_TEMP, M_NOWAIT);
if (!cksum) {
printf("IPv4 AH input: couldn't alloc temporary region for cksum\n");
ipsecstat.in_inval++;
goto fail;
}
{
/*
* some of IP header fields are flipped to the host endian.
* convert them back to network endian. VERY stupid.
*/
ip->ip_len = htons(ip->ip_len + hlen);
ip->ip_id = htons(ip->ip_id);
ip->ip_off = htons(ip->ip_off);
if (ah4_calccksum(m, (caddr_t)cksum, algo, sav)) {
free(cksum, M_TEMP);
ipsecstat.in_inval++;
goto fail;
}
ipsecstat.in_ahhist[sav->alg_auth]++;
/*
* flip them back.
*/
ip->ip_len = ntohs(ip->ip_len) - hlen;
ip->ip_id = ntohs(ip->ip_id);
ip->ip_off = ntohs(ip->ip_off);
}
{
caddr_t sumpos = NULL;
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
sumpos = (caddr_t)(ah + 1);
} else {
/* RFC 2402 */
sumpos = (caddr_t)(((struct newah *)ah) + 1);
}
if (bcmp(sumpos, cksum, siz) != 0) {
log(LOG_AUTH, "checksum mismatch in IPv4 AH input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
free(cksum, M_TEMP);
ipsecstat.in_ahauthfail++;
goto fail;
}
}
free(cksum, M_TEMP);
m->m_flags |= M_AUTHIPHDR;
m->m_flags |= M_AUTHIPDGM;
/* M_AUTH related flags might be cleared here in the future */
if (m->m_flags & M_AUTHIPHDR
&& m->m_flags & M_AUTHIPDGM) {
ipsecstat.in_ahauthsucc++;
} else {
log(LOG_AUTH, "authentication failed in IPv4 AH input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_ahauthfail++;
}
/*
* update sequence number.
*/
if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
(void)ipsec_updatereplay(ntohl(((struct newah *)ah)->ah_seq), sav);
}
/* was it transmitted over the IPsec tunnel SA? */
if (ipsec4_tunnel_validate(ip, nxt, sav) && nxt == IPPROTO_IPV4) {
/*
* strip off all the headers that precedes AH.
* IP xx AH IP' payload -> IP' payload
*
* XXX more sanity checks
* XXX relationship with gif?
*/
size_t stripsiz = 0;
u_int8_t tos;
tos = ip->ip_tos;
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
stripsiz = sizeof(struct ah) + siz1;
} else {
/* RFC 2402 */
stripsiz = sizeof(struct newah) + siz1;
}
m_adj(m, off + stripsiz);
if (m->m_len < sizeof(*ip)) {
m = m_pullup(m, sizeof(*ip));
if (!m) {
ipsecstat.in_inval++;
goto fail;
}
}
ip = mtod(m, struct ip *);
/* ECN consideration. */
ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos);
if (!key_checktunnelsanity(sav, AF_INET,
(caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
log(LOG_NOTICE, "ipsec tunnel address mismatch in IPv4 AH input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_inval++;
goto fail;
}
/*
* Should the inner packet be considered authentic?
* My current answer is: NO.
*
* host1 -- gw1 === gw2 -- host2
* In this case, gw2 can trust the authenticity of the
* outer packet, but NOT inner. Packet may be altered
* between host1 and gw1.
*
* host1 -- gw1 === host2
* This case falls into the same scenario as above.
*
* host1 === host2
* This case is the only case when we may be able to leave
* M_AUTHIPHDR and M_AUTHIPDGM set.
* However, if host1 is wrongly configured, and allows
* attacker to inject some packet with src=host1 and
* dst=host2, you are in risk.
*/
m->m_flags &= ~M_AUTHIPHDR;
m->m_flags &= ~M_AUTHIPDGM;
key_sa_recordxfer(sav, m);
s = splimp();
if (IF_QFULL(&ipintrq)) {
ipsecstat.in_inval++;
goto fail;
}
IF_ENQUEUE(&ipintrq, m);
m = NULL;
schednetisr(NETISR_IP); /*can be skipped but to make sure*/
splx(s);
nxt = IPPROTO_DONE;
} else {
/*
* strip off AH.
* We do deep-copy since KAME requires that
* the packet is placed in a single external mbuf.
*/
size_t stripsiz = 0;
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
stripsiz = sizeof(struct ah) + siz1;
} else {
/* RFC 2402 */
stripsiz = sizeof(struct newah) + siz1;
}
ip = mtod(m, struct ip *);
ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), off);
m->m_data += stripsiz;
m->m_len -= stripsiz;
m->m_pkthdr.len -= stripsiz;
ip = mtod(m, struct ip *);
/*ip_len is in host endian*/
ip->ip_len = ip->ip_len - stripsiz;
ip->ip_p = nxt;
/* forget about IP hdr checksum, the check has already been passed */
if (nxt != IPPROTO_DONE)
(*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt);
else
m_freem(m);
m = NULL;
}
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ah4_input call free SA:%p\n", sav));
key_freesav(sav);
}
ipsecstat.in_success++;
return;
fail:
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ah4_input call free SA:%p\n", sav));
key_freesav(sav);
}
if (m)
m_freem(m);
return;
}
#endif /* INET */
#ifdef INET6
int
ah6_input(mp, offp, proto)
struct mbuf **mp;
int *offp, proto;
{
struct mbuf *m = *mp;
int off = *offp;
struct ip6_hdr *ip6;
struct ah *ah;
u_int32_t spi;
struct ah_algorithm *algo;
size_t siz;
size_t siz1;
u_char *cksum;
struct secasvar *sav = NULL;
u_int16_t nxt;
int s;
IP6_EXTHDR_CHECK(m, off, sizeof(struct ah), IPPROTO_DONE);
ip6 = mtod(m, struct ip6_hdr *);
ah = (struct ah *)(((caddr_t)ip6) + off);
nxt = ah->ah_nxt;
/* find the sassoc. */
spi = ah->ah_spi;
if (ntohs(ip6->ip6_plen) == 0) {
printf("IPv6 AH input: AH with IPv6 jumbogram is not supported.\n");
ipsec6stat.in_inval++;
goto fail;
}
if ((sav = key_allocsa(AF_INET6,
(caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst,
IPPROTO_AH, spi)) == 0) {
printf("IPv6 AH input: no key association found for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsec6stat.in_nosa++;
goto fail;
}
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ah6_input called to allocate SA:%p\n", sav));
if (sav->state != SADB_SASTATE_MATURE
&& sav->state != SADB_SASTATE_DYING) {
printf("IPv6 AH input: non-mature/dying SA found for spi %u; "
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsec6stat.in_badspi++;
goto fail;
}
if (sav->alg_auth == SADB_AALG_NONE) {
printf("IPv6 AH input: unspecified authentication algorithm "
"for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsec6stat.in_badspi++;
goto fail;
}
algo = &ah_algorithms[sav->alg_auth];
siz = (*algo->sumsiz)(sav);
siz1 = ((siz + 3) & ~(4 - 1));
/*
* sanity checks for header, 1.
*/
{
int sizoff;
sizoff = (sav->flags & SADB_X_EXT_OLD) ? 0 : 4;
if ((ah->ah_len << 2) - sizoff != siz1) {
log(LOG_NOTICE, "sum length mismatch in IPv6 AH input "
"(%d should be %u): %s\n",
(ah->ah_len << 2) - sizoff, (unsigned int)siz1,
ipsec6_logpacketstr(ip6, spi));
ipsec6stat.in_inval++;
goto fail;
}
IP6_EXTHDR_CHECK(m, off, sizeof(struct ah) + sizoff + siz1, IPPROTO_DONE);
}
/*
* check for sequence number.
*/
if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
if (ipsec_chkreplay(ntohl(((struct newah *)ah)->ah_seq), sav))
; /*okey*/
else {
ipsec6stat.in_ahreplay++;
log(LOG_AUTH, "replay packet in IPv6 AH input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
goto fail;
}
}
/*
* alright, it seems sane. now we are going to check the
* cryptographic checksum.
*/
cksum = malloc(siz1, M_TEMP, M_NOWAIT);
if (!cksum) {
printf("IPv6 AH input: couldn't alloc temporary region for cksum\n");
ipsec6stat.in_inval++;
goto fail;
}
if (ah6_calccksum(m, (caddr_t)cksum, algo, sav)) {
free(cksum, M_TEMP);
ipsec6stat.in_inval++;
goto fail;
}
ipsec6stat.in_ahhist[sav->alg_auth]++;
{
caddr_t sumpos = NULL;
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
sumpos = (caddr_t)(ah + 1);
} else {
/* RFC 2402 */
sumpos = (caddr_t)(((struct newah *)ah) + 1);
}
if (bcmp(sumpos, cksum, siz) != 0) {
log(LOG_AUTH, "checksum mismatch in IPv6 AH input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
free(cksum, M_TEMP);
ipsec6stat.in_ahauthfail++;
goto fail;
}
}
free(cksum, M_TEMP);
m->m_flags |= M_AUTHIPHDR;
m->m_flags |= M_AUTHIPDGM;
/* M_AUTH related flags might be cleared here in the future */
if (m->m_flags & M_AUTHIPHDR
&& m->m_flags & M_AUTHIPDGM) {
ipsec6stat.in_ahauthsucc++;
} else {
log(LOG_AUTH, "authentication failed in IPv6 AH input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_ahauthfail++;
}
/*
* update sequence number.
*/
if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
(void)ipsec_updatereplay(ntohl(((struct newah *)ah)->ah_seq), sav);
}
/* was it transmitted over the IPsec tunnel SA? */
if (ipsec6_tunnel_validate(ip6, nxt, sav) && nxt == IPPROTO_IPV6) {
/*
* strip off all the headers that precedes AH.
* IP6 xx AH IP6' payload -> IP6' payload
*
* XXX more sanity checks
* XXX relationship with gif?
*/
size_t stripsiz = 0;
u_int32_t flowinfo; /*net endian*/
flowinfo = ip6->ip6_flow;
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
stripsiz = sizeof(struct ah) + siz1;
} else {
/* RFC 2402 */
stripsiz = sizeof(struct newah) + siz1;
}
m_adj(m, off + stripsiz);
if (m->m_len < sizeof(*ip6)) {
/*
* m_pullup is prohibited in KAME IPv6 input processing
* but there's no other way!
*/
m = m_pullup(m, sizeof(*ip6));
if (!m) {
ipsec6stat.in_inval++;
goto fail;
}
}
ip6 = mtod(m, struct ip6_hdr *);
/* ECN consideration. */
ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow);
if (!key_checktunnelsanity(sav, AF_INET6,
(caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
log(LOG_NOTICE, "ipsec tunnel address mismatch in IPv6 AH input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_inval++;
goto fail;
}
/*
* should the inner packet be considered authentic?
* see comment in ah4_input().
*/
m->m_flags &= ~M_AUTHIPHDR;
m->m_flags &= ~M_AUTHIPDGM;
key_sa_recordxfer(sav, m);
s = splimp();
if (IF_QFULL(&ip6intrq)) {
ipsec6stat.in_inval++;
goto fail;
}
IF_ENQUEUE(&ip6intrq, m);
m = NULL;
schednetisr(NETISR_IPV6); /*can be skipped but to make sure*/
splx(s);
nxt = IPPROTO_DONE;
} else {
/*
* strip off AH.
* We do deep-copy since KAME requires that
* the packet is placed in a single mbuf.
*/
size_t stripsiz = 0;
char *prvnxtp;
/*
* Copy the value of the next header field of AH to the
* next header field of the previous header.
* This is necessary because AH will be stripped off below.
*/
prvnxtp = ip6_get_prevhdr(m, off); /* XXX */
*prvnxtp = nxt;
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
stripsiz = sizeof(struct ah) + siz1;
} else {
/* RFC 2402 */
stripsiz = sizeof(struct newah) + siz1;
}
ip6 = mtod(m, struct ip6_hdr *);
ovbcopy((caddr_t)ip6, (caddr_t)(((u_char *)ip6) + stripsiz),
off);
m->m_data += stripsiz;
m->m_len -= stripsiz;
m->m_pkthdr.len -= stripsiz;
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
key_sa_recordxfer(sav, m);
}
*offp = off;
*mp = m;
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ah6_input call free SA:%p\n", sav));
key_freesav(sav);
}
ipsec6stat.in_success++;
return nxt;
fail:
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP ah6_input call free SA:%p\n", sav));
key_freesav(sav);
}
if (m)
m_freem(m);
return IPPROTO_DONE;
}
#endif /* INET6 */

532
sys/netinet6/ah_output.c Normal file
View File

@ -0,0 +1,532 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1826/2402 authentication header.
*/
#include "opt_inet6.h"
#include "opt_ipsec.h"
#define ahdprintf(x) printf x
#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/socketvar.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_var.h>
#include <netinet/in_pcb.h>
#ifdef INET6
#include <netinet6/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/icmp6.h>
#endif
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#ifdef INET6
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#endif
#include <netkey/key.h>
#include <netkey/keydb.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#include <net/net_osdep.h>
static struct in_addr *ah4_finaldst __P((struct mbuf *));
/*
* compute AH header size.
* transport mode only. for tunnel mode, we should implement
* virtual interface, and control MTU/MSS by the interface MTU.
*/
size_t
ah_hdrsiz(isr)
struct ipsecrequest *isr;
{
struct ah_algorithm *algo;
size_t hdrsiz;
/* sanity check */
if (isr == NULL)
panic("ah_hdrsiz: NULL was passed.\n");
if (isr->saidx.proto != IPPROTO_AH)
panic("unsupported mode passed to ah_hdrsiz");
if (isr->sav == NULL)
goto contrive;
if (isr->sav->state != SADB_SASTATE_MATURE
&& isr->sav->state != SADB_SASTATE_DYING)
goto contrive;
/* we need transport mode AH. */
algo = &ah_algorithms[isr->sav->alg_auth];
if (!algo)
goto contrive;
/*
* XXX
* right now we don't calcurate the padding size. simply
* treat the padding size as constant, for simplicity.
*
* XXX variable size padding support
*/
hdrsiz = (((*algo->sumsiz)(isr->sav) + 3) & ~(4 - 1));
if (isr->sav->flags & SADB_X_EXT_OLD)
hdrsiz += sizeof(struct ah);
else
hdrsiz += sizeof(struct newah);
return hdrsiz;
contrive:
/* ASSUMING:
* sizeof(struct newah) > sizeof(struct ah).
* 16 = (16 + 3) & ~(4 - 1).
*/
return sizeof(struct newah) + 16;
}
/*
* Modify the packet so that it includes the authentication data.
* The mbuf passed must start with IPv4 header.
*
* assumes that the first mbuf contains IPv4 header + option only.
* the function does not modify m.
*/
int
ah4_output(m, isr)
struct mbuf *m;
struct ipsecrequest *isr;
{
struct secasvar *sav = isr->sav;
struct ah_algorithm *algo;
u_int32_t spi;
u_char *ahdrpos;
u_char *ahsumpos = NULL;
size_t hlen = 0; /*IP header+option in bytes*/
size_t plen = 0; /*AH payload size in bytes*/
size_t ahlen = 0; /*plen + sizeof(ah)*/
struct ip *ip;
struct in_addr dst;
struct in_addr *finaldst;
int error;
/* sanity checks */
if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
struct ip *ip;
ip = mtod(m, struct ip *);
printf("ah4_output: internal error: "
"sav->replay is null: "
"%x->%x, SPI=%u\n",
(u_int32_t)ntohl(ip->ip_src.s_addr),
(u_int32_t)ntohl(ip->ip_dst.s_addr),
(u_int32_t)ntohl(sav->spi));
ipsecstat.out_inval++;
m_freem(m);
return EINVAL;
}
algo = &ah_algorithms[sav->alg_auth];
spi = sav->spi;
/*
* determine the size to grow.
*/
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
plen = ((*algo->sumsiz)(sav) + 3) & ~(4 - 1); /*XXX pad to 8byte?*/
ahlen = plen + sizeof(struct ah);
} else {
/* RFC 2402 */
plen = ((*algo->sumsiz)(sav) + 3) & ~(4 - 1); /*XXX pad to 8byte?*/
ahlen = plen + sizeof(struct newah);
}
/*
* grow the mbuf to accomodate AH.
*/
ip = mtod(m, struct ip *);
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
if (m->m_len != hlen)
panic("ah4_output: assumption failed (first mbuf length)");
if (M_LEADINGSPACE(m->m_next) < ahlen) {
struct mbuf *n;
MGET(n, M_DONTWAIT, MT_DATA);
if (!n) {
printf("ENOBUFS in ah4_output %d\n", __LINE__);
m_freem(m);
return ENOBUFS;
}
n->m_len = ahlen;
n->m_next = m->m_next;
m->m_next = n;
m->m_pkthdr.len += ahlen;
ahdrpos = mtod(n, u_char *);
} else {
m->m_next->m_len += ahlen;
m->m_next->m_data -= ahlen;
m->m_pkthdr.len += ahlen;
ahdrpos = mtod(m->m_next, u_char *);
}
ip = mtod(m, struct ip *); /*just to be sure*/
/*
* initialize AH.
*/
if (sav->flags & SADB_X_EXT_OLD) {
struct ah *ahdr;
ahdr = (struct ah *)ahdrpos;
ahsumpos = (u_char *)(ahdr + 1);
ahdr->ah_len = plen >> 2;
ahdr->ah_nxt = ip->ip_p;
ahdr->ah_reserve = htons(0);
ahdr->ah_spi = spi;
bzero(ahdr + 1, plen);
} else {
struct newah *ahdr;
ahdr = (struct newah *)ahdrpos;
ahsumpos = (u_char *)(ahdr + 1);
ahdr->ah_len = (plen >> 2) + 1; /* plus one for seq# */
ahdr->ah_nxt = ip->ip_p;
ahdr->ah_reserve = htons(0);
ahdr->ah_spi = spi;
sav->replay->count++;
/*
* XXX sequence number must not be cycled, if the SA is
* installed by IKE daemon.
*/
ahdr->ah_seq = htonl(sav->replay->count);
bzero(ahdr + 1, plen);
}
/*
* modify IPv4 header.
*/
ip->ip_p = IPPROTO_AH;
if (ahlen < (IP_MAXPACKET - ntohs(ip->ip_len)))
ip->ip_len = htons(ntohs(ip->ip_len) + ahlen);
else {
printf("IPv4 AH output: size exceeds limit\n");
ipsecstat.out_inval++;
m_freem(m);
return EMSGSIZE;
}
/*
* If there is source routing option, update destination field in
* the IPv4 header to the final destination.
* Note that we do not need to update source routing option itself
* (as done in IPv4 AH processing -- see ip6_output()), since
* source routing option is not part of the ICV computation.
*/
finaldst = ah4_finaldst(m);
if (finaldst) {
dst.s_addr = ip->ip_dst.s_addr;
ip->ip_dst.s_addr = finaldst->s_addr;
}
/*
* calcurate the checksum, based on security association
* and the algorithm specified.
*/
error = ah4_calccksum(m, (caddr_t)ahsumpos, algo, sav);
if (error) {
printf("error after ah4_calccksum, called from ah4_output");
m = NULL;
ipsecstat.out_inval++;
return error;
}
if (finaldst) {
ip = mtod(m, struct ip *); /*just to make sure*/
ip->ip_dst.s_addr = dst.s_addr;
}
ipsecstat.out_success++;
ipsecstat.out_ahhist[sav->alg_auth]++;
key_sa_recordxfer(sav, m);
return 0;
}
/* Calculate AH length */
int
ah_hdrlen(sav)
struct secasvar *sav;
{
struct ah_algorithm *algo;
int plen, ahlen;
algo = &ah_algorithms[sav->alg_auth];
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1826 */
plen = ((*algo->sumsiz)(sav) + 3) & ~(4 - 1); /*XXX pad to 8byte?*/
ahlen = plen + sizeof(struct ah);
} else {
/* RFC 2402 */
plen = ((*algo->sumsiz)(sav) + 3) & ~(4 - 1); /*XXX pad to 8byte?*/
ahlen = plen + sizeof(struct newah);
}
return(ahlen);
}
#ifdef INET6
/*
* Fill in the Authentication Header and calculate checksum.
*/
int
ah6_output(m, nexthdrp, md, isr)
struct mbuf *m;
u_char *nexthdrp;
struct mbuf *md;
struct ipsecrequest *isr;
{
struct mbuf *mprev;
struct mbuf *mah;
struct secasvar *sav = isr->sav;
struct ah_algorithm *algo;
u_int32_t spi;
u_char *ahsumpos = NULL;
size_t plen; /*AH payload size in bytes*/
int error = 0;
int ahlen;
struct ip6_hdr *ip6;
if (m->m_len < sizeof(struct ip6_hdr)) {
printf("ah6_output: first mbuf too short\n");
m_freem(m);
return EINVAL;
}
ahlen = ah_hdrlen(sav);
if (ahlen == 0)
return 0;
for (mprev = m; mprev && mprev->m_next != md; mprev = mprev->m_next)
;
if (!mprev || mprev->m_next != md) {
printf("ah6_output: md is not in chain\n");
m_freem(m);
return EINVAL;
}
MGET(mah, M_DONTWAIT, MT_DATA);
if (!mah) {
m_freem(m);
return ENOBUFS;
}
if (ahlen > MLEN) {
MCLGET(mah, M_DONTWAIT);
if ((mah->m_flags & M_EXT) == 0) {
m_free(mah);
m_freem(m);
return ENOBUFS;
}
}
mah->m_len = ahlen;
mah->m_next = md;
mprev->m_next = mah;
m->m_pkthdr.len += ahlen;
/* fix plen */
if (m->m_pkthdr.len - sizeof(struct ip6_hdr) > IPV6_MAXPACKET) {
printf("ip6_output: AH with IPv6 jumbogram is not supported\n");
m_freem(m);
return EINVAL;
}
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
printf("ah6_output: internal error: "
"sav->replay is null: SPI=%u\n",
(u_int32_t)ntohl(sav->spi));
ipsec6stat.out_inval++;
return 0; /* no change at all */
}
algo = &ah_algorithms[sav->alg_auth];
spi = sav->spi;
/*
* initialize AH.
*/
if (sav->flags & SADB_X_EXT_OLD) {
struct ah *ahdr = mtod(mah, struct ah *);
plen = mah->m_len - sizeof(struct ah);
ahsumpos = (u_char *)(ahdr + 1);
ahdr->ah_nxt = *nexthdrp;
*nexthdrp = IPPROTO_AH;
ahdr->ah_len = plen >> 2;
ahdr->ah_reserve = htons(0);
ahdr->ah_spi = spi;
bzero(ahdr + 1, plen);
} else {
struct newah *ahdr = mtod(mah, struct newah *);
plen = mah->m_len - sizeof(struct newah);
ahsumpos = (u_char *)(ahdr + 1);
ahdr->ah_nxt = *nexthdrp;
*nexthdrp = IPPROTO_AH;
ahdr->ah_len = (plen >> 2) + 1; /* plus one for seq# */
ahdr->ah_reserve = htons(0);
ahdr->ah_spi = spi;
sav->replay->count++;
/*
* XXX sequence number must not be cycled, if the SA is
* installed by IKE daemon.
*/
ahdr->ah_seq = htonl(sav->replay->count);
bzero(ahdr + 1, plen);
}
/*
* calcurate the checksum, based on security association
* and the algorithm specified.
*/
error = ah6_calccksum(m, (caddr_t)ahsumpos, algo, sav);
if (error)
ipsec6stat.out_inval++;
else
ipsec6stat.out_success++;
ipsec6stat.out_ahhist[sav->alg_auth]++;
key_sa_recordxfer(sav, m);
return(error);
}
#endif
/*
* Find the final destination if there is loose/strict source routing option.
* Returns NULL if there's no source routing options.
* Returns NULL on errors too.
* Note that this function will return a pointer INTO the given parameter,
* struct mbuf *m.
* The mbuf must be pulled up toward, at least, ip option part.
*/
static struct in_addr *
ah4_finaldst(m)
struct mbuf *m;
{
struct ip *ip;
int optlen;
u_char *q;
int i;
int hlen;
if (!m)
panic("ah4_finaldst: m == NULL");
ip = mtod(m, struct ip *);
hlen = (ip->ip_hl << 2);
if (m->m_len < hlen) {
printf("ah4_finaldst: parameter mbuf wrong (not pulled up)\n");
return NULL;
}
if (hlen == sizeof(struct ip))
return NULL;
optlen = hlen - sizeof(struct ip);
if (optlen < 0) {
printf("ah4_finaldst: wrong optlen %d\n", optlen);
return NULL;
}
q = (u_char *)(ip + 1);
i = 0;
while (i < optlen) {
switch (q[i + IPOPT_OPTVAL]) {
case IPOPT_EOL:
i = optlen; /* bye */
break;
case IPOPT_NOP:
i++;
break;
case IPOPT_LSRR:
case IPOPT_SSRR:
if (q[i + IPOPT_OLEN] <= 0
|| optlen - i < q[i + IPOPT_OLEN]) {
printf("ip_finaldst: invalid IP option "
"(code=%02x len=%02x)\n",
q[i + IPOPT_OPTVAL], q[i + IPOPT_OLEN]);
return NULL;
}
i += q[i + IPOPT_OLEN] - sizeof(struct in_addr);
return (struct in_addr *)(q + i);
default:
if (q[i + IPOPT_OLEN] <= 0
|| optlen - i < q[i + IPOPT_OLEN]) {
printf("ip_finaldst: invalid IP option "
"(code=%02x len=%02x)\n",
q[i + IPOPT_OPTVAL], q[i + IPOPT_OLEN]);
return NULL;
}
i += q[i + IPOPT_OLEN];
break;
}
}
return NULL;
}

99
sys/netinet6/esp.h Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1827/2406 Encapsulated Security Payload.
*/
#ifndef _NETINET6_ESP_H_
#define _NETINET6_ESP_H_
struct secasvar;
struct esp {
u_int32_t esp_spi; /* ESP */
/*variable size, 32bit bound*/ /* Initialization Vector */
/*variable size*/ /* Payload data */
/*variable size*/ /* padding */
/*8bit*/ /* pad size */
/*8bit*/ /* next header */
/*8bit*/ /* next header */
/*variable size, 32bit bound*/ /* Authentication data (new IPsec) */
};
struct newesp {
u_int32_t esp_spi; /* ESP */
u_int32_t esp_seq; /* Sequence number */
/*variable size*/ /* (IV and) Payload data */
/*variable size*/ /* padding */
/*8bit*/ /* pad size */
/*8bit*/ /* next header */
/*8bit*/ /* next header */
/*variable size, 32bit bound*/ /* Authentication data */
};
struct esptail {
u_int8_t esp_padlen; /* pad length */
u_int8_t esp_nxt; /* Next header */
/*variable size, 32bit bound*/ /* Authentication data (new IPsec)*/
};
struct esp_algorithm_state {
struct secasvar *sav;
void* foo; /*per algorithm data - maybe*/
};
/* XXX yet to be defined */
struct esp_algorithm {
size_t padbound; /* pad boundary, in byte */
int (*mature) __P((struct secasvar *));
int keymin; /* in bits */
int keymax; /* in bits */
int (*ivlen) __P((struct secasvar *));
int (*decrypt) __P((struct mbuf *, size_t,
struct secasvar *, struct esp_algorithm *, int));
int (*encrypt) __P((struct mbuf *, size_t, size_t,
struct secasvar *, struct esp_algorithm *, int));
};
#ifdef KERNEL
extern struct esp_algorithm esp_algorithms[];
/* crypt routines */
extern int esp4_output __P((struct mbuf *, struct ipsecrequest *));
extern void esp4_input __P((struct mbuf *, int, int));
extern size_t esp_hdrsiz __P((struct ipsecrequest *));
#endif /*KERNEL*/
extern int esp_auth __P((struct mbuf *, size_t, size_t,
struct secasvar *, u_char *));
#endif /*_NETINET6_ESP_H_*/

45
sys/netinet6/esp6.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1827/2406 Encapsulated Security Payload.
*/
#ifndef _NETINET6_ESP6_H_
#define _NETINET6_ESP6_H_
#ifdef KERNEL
extern int esp6_output __P((struct mbuf *, u_char *, struct mbuf *,
struct ipsecrequest *));
extern int esp6_input __P((struct mbuf **, int *, int));
#endif /*KERNEL*/
#endif /*_NETINET6_ESP6_H_*/

1236
sys/netinet6/esp_core.c Normal file

File diff suppressed because it is too large Load Diff

984
sys/netinet6/esp_input.c Normal file
View File

@ -0,0 +1,984 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* RFC1827/2406 Encapsulated Security Payload.
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/route.h>
#include <net/netisr.h>
#include <machine/cpu.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/in_var.h>
#include <netinet/ip_ecn.h>
#ifdef INET6
#include <netinet6/ip6_ecn.h>
#endif
#ifdef INET6
#include <netinet6/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/icmp6.h>
#endif
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#ifdef INET6
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#endif
#ifdef IPSEC_ESP
#include <netinet6/esp.h>
#ifdef INET6
#include <netinet6/esp6.h>
#endif
#endif
#include <netkey/key.h>
#include <netkey/keydb.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#include <netinet/ipprotosw.h>
#include <machine/stdarg.h>
#include <net/net_osdep.h>
#ifdef INET
extern struct ipprotosw inetsw[];
void
esp4_input(m, off, proto)
struct mbuf *m;
int off, proto;
{
struct ip *ip;
struct esp *esp;
struct esptail *esptail;
u_int32_t spi;
struct secasvar *sav = NULL;
size_t taillen;
u_int16_t nxt;
struct esp_algorithm *algo;
int ivlen;
size_t hlen;
size_t esplen;
int s;
/* sanity check for alignment. */
if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
printf("IPv4 ESP input: packet alignment problem "
"(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len);
ipsecstat.in_inval++;
goto bad;
}
if (m->m_len < off + sizeof(struct esp)) {
m = m_pullup(m, off + sizeof(struct esp));
if (!m) {
printf("IPv4 ESP input: can't pullup in esp4_input\n");
ipsecstat.in_inval++;
goto bad;
}
}
ip = mtod(m, struct ip *);
esp = (struct esp *)(((u_int8_t *)ip) + off);
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
/* find the sassoc. */
spi = esp->esp_spi;
if ((sav = key_allocsa(AF_INET,
(caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst,
IPPROTO_ESP, spi)) == 0) {
printf("IPv4 ESP input: no key association found for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsecstat.in_nosa++;
goto bad;
}
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP esp4_input called to allocate SA:%p\n", sav));
if (sav->state != SADB_SASTATE_MATURE
&& sav->state != SADB_SASTATE_DYING) {
printf("IPv4 ESP input: non-mature/dying SA found for spi %u; "
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsecstat.in_badspi++;
goto bad;
}
if (sav->alg_enc == SADB_EALG_NONE) {
printf("IPv4 ESP input: unspecified encryption algorithm "
"for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsecstat.in_badspi++;
goto bad;
}
algo = &esp_algorithms[sav->alg_enc]; /*XXX*/
/* check if we have proper ivlen information */
ivlen = sav->ivlen;
if (ivlen < 0) {
log(LOG_NOTICE, "inproper ivlen in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_inval++;
goto bad;
}
if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
&& (sav->alg_auth && sav->key_auth)))
goto noreplaycheck;
if (sav->alg_auth == SADB_AALG_NULL)
goto noreplaycheck;
/*
* check for sequence number.
*/
if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
; /*okey*/
else {
ipsecstat.in_espreplay++;
log(LOG_AUTH, "replay packet in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
goto bad;
}
/* check ICV */
{
struct mbuf *n;
int len;
u_char sum0[AH_MAXSUMSIZE];
u_char sum[AH_MAXSUMSIZE];
struct ah_algorithm *sumalgo;
size_t siz;
sumalgo = &ah_algorithms[sav->alg_auth];
siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
if (AH_MAXSUMSIZE < siz) {
printf("internal error: AH_MAXSUMSIZE must be larger than %lu\n",
(u_long)siz);
ipsecstat.in_inval++;
goto bad;
}
n = m;
len = m->m_pkthdr.len;
len -= siz;
while (n && 0 < len) {
if (len < n->m_len)
break;
len -= n->m_len;
n = n->m_next;
}
if (!n) {
printf("mbuf chain problem?\n");
ipsecstat.in_inval++;
goto bad;
}
m_copydata(n, len, siz, &sum0[0]);
if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
log(LOG_AUTH, "auth fail in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_espauthfail++;
goto bad;
}
if (bcmp(sum0, sum, siz) != 0) {
log(LOG_AUTH, "auth fail in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_espauthfail++;
goto bad;
}
/* strip off */
m->m_pkthdr.len -= siz;
n->m_len -= siz;
ip = mtod(m, struct ip *);
ip->ip_len = ip->ip_len - siz;
m->m_flags |= M_AUTHIPDGM;
ipsecstat.in_espauthsucc++;
}
/*
* update sequence number.
*/
if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
(void)ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav);
}
noreplaycheck:
/* process main esp header. */
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1827 */
esplen = sizeof(struct esp);
} else {
/* RFC 2406 */
if (sav->flags & SADB_X_EXT_DERIV)
esplen = sizeof(struct esp);
else
esplen = sizeof(struct newesp);
}
if (m->m_len < off + esplen + ivlen) {
m = m_pullup(m, off + esplen + ivlen);
if (!m) {
printf("IPv4 ESP input: can't pullup in esp4_input\n");
ipsecstat.in_inval++;
goto bad;
}
}
{
/*
* decrypt the packet.
*/
if (!algo->decrypt)
panic("internal error: no decrypt function");
if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
log(LOG_AUTH, "decrypt fail in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_inval++;
goto bad;
}
ipsecstat.in_esphist[sav->alg_enc]++;
m->m_flags |= M_DECRYPTED;
}
#ifdef garbled_data_found_on_mbuf_after_packet
{
/*
* For simplicity, we'll trim the packet so that there's no extra
* part appended after IP packet.
* This is rare case for some odd drivers, so there should be no
* performance hit.
*/
/*
* Note that, in ip_input, ip_len was already flipped and header
* length was subtracted from ip_len.
*/
if (m->m_pkthdr.len != hlen + ip->ip_len)
{
size_t siz;
struct mbuf *n;
siz = hlen + ip->ip_len;
/* find the final mbuf */
for (n = m; n; n = n->m_next) {
if (n->m_len < siz)
siz -= n->m_len;
else
break;
}
if (!n) {
printf("invalid packet\n");
ipsecstat.in_inval++;
goto bad;
}
/* trim the final mbuf */
if (n->m_len < siz) {
printf("invalid size: %d %d\n", n->m_len, siz);
ipsecstat.in_inval++;
goto bad;
}
n->m_len = siz;
/* dispose the rest of the packet */
m_freem(n->m_next);
n->m_next = NULL;
m->m_pkthdr.len = hlen + ip->ip_len;
}
}
#endif
{
/*
* find the trailer of the ESP.
*/
struct mbuf *n; /*the last mbuf on the mbuf chain, m_len > 0 */
struct mbuf *o; /*the last mbuf on the mbuf chain */
o = m;
n = NULL;
while (o) {
if (0 < o->m_len)
n = o;
o = o->m_next;
}
if (!n || n->m_len < sizeof(struct esptail)) {
printf("IPv4 ESP input: assertion on pad part failed; "
"dropping the packet\n");
ipsecstat.in_inval++;
goto bad;
}
esptail = (struct esptail *)
(mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
nxt = esptail->esp_nxt;
taillen = esptail->esp_padlen + 2;
if (m->m_pkthdr.len < taillen
|| m->m_pkthdr.len - taillen < hlen) { /*?*/
log(LOG_NOTICE, "bad pad length in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_inval++;
goto bad;
}
/*
* strip off the trailing pad area.
*/
if (taillen < n->m_len) {
/* trailing pad data is included in the last mbuf item. */
n->m_len -= taillen;
m->m_pkthdr.len -= taillen;
} else {
/* trailing pad data spans on multiple mbuf item. */
size_t siz;
siz = m->m_pkthdr.len;
if (siz < taillen) {
log(LOG_NOTICE, "bad packet length in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_inval++;
goto bad;
}
siz -= taillen;
/* find the final mbuf */
for (n = m; n; n = n->m_next) {
if (n->m_len < siz)
siz -= n->m_len;
else
break;
}
if (!n) {
printf("invalid packet\n");
ipsecstat.in_inval++;
goto bad;
}
/* trim the final mbuf */
if (n->m_len < siz) {
printf("invalid size: %d %lu\n", n->m_len, (u_long)siz);
ipsecstat.in_inval++;
goto bad;
}
n->m_len = siz;
/* dispose the rest of the packet */
m_freem(n->m_next);
n->m_next = NULL;
m->m_pkthdr.len -= taillen;
}
ip->ip_len = ip->ip_len - taillen;
}
/* was it transmitted over the IPsec tunnel SA? */
if (ipsec4_tunnel_validate(ip, nxt, sav) && nxt == IPPROTO_IPV4) {
/*
* strip off all the headers that precedes ESP header.
* IP4 xx ESP IP4' payload -> IP4' payload
*
* XXX more sanity checks
* XXX relationship with gif?
*/
struct ip oip; /* for debug */
u_int8_t tos;
tos = ip->ip_tos;
bcopy(mtod(m, struct ip *), &oip, sizeof(oip)); /* for debug */
m_adj(m, off + esplen + ivlen);
if (m->m_len < sizeof(*ip)) {
m = m_pullup(m, sizeof(*ip));
if (!m) {
ipsecstat.in_inval++;
goto bad;
}
}
ip = mtod(m, struct ip *);
/* ECN consideration. */
ip_ecn_egress(ip4_ipsec_ecn, &tos, &ip->ip_tos);
if (!key_checktunnelsanity(sav, AF_INET,
(caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst)) {
log(LOG_NOTICE, "ipsec tunnel address mismatch in IPv4 ESP input: %s %s\n",
ipsec4_logpacketstr(ip, spi),
ipsec_logsastr(sav));
ipsecstat.in_inval++;
goto bad;
}
key_sa_recordxfer(sav, m);
s = splimp();
if (IF_QFULL(&ipintrq)) {
ipsecstat.in_inval++;
goto bad;
}
IF_ENQUEUE(&ipintrq, m);
m = NULL;
schednetisr(NETISR_IP); /*can be skipped but to make sure*/
splx(s);
nxt = IPPROTO_DONE;
} else {
/*
* strip off ESP header and IV.
* We do deep-copy since KAME requires packet to be placed
* in a single mbuf.
*/
size_t stripsiz;
stripsiz = esplen + ivlen;
ip = mtod(m, struct ip *);
ovbcopy((caddr_t)ip, (caddr_t)(((u_char *)ip) + stripsiz), off);
m->m_data += stripsiz;
m->m_len -= stripsiz;
m->m_pkthdr.len -= stripsiz;
ip = mtod(m, struct ip *);
ip->ip_len = ip->ip_len - stripsiz;
ip->ip_p = nxt;
key_sa_recordxfer(sav, m);
if (nxt != IPPROTO_DONE)
(*inetsw[ip_protox[nxt]].pr_input)(m, off, nxt);
else
m_freem(m);
m = NULL;
}
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP esp4_input call free SA:%p\n", sav));
key_freesav(sav);
}
ipsecstat.in_success++;
return;
bad:
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP esp4_input call free SA:%p\n", sav));
key_freesav(sav);
}
if (m)
m_freem(m);
return;
}
#endif /* INET */
#ifdef INET6
int
esp6_input(mp, offp, proto)
struct mbuf **mp;
int *offp, proto;
{
struct mbuf *m = *mp;
int off = *offp;
struct ip6_hdr *ip6;
struct esp *esp;
struct esptail *esptail;
u_int32_t spi;
struct secasvar *sav = NULL;
size_t taillen;
u_int16_t nxt;
struct esp_algorithm *algo;
int ivlen;
size_t esplen;
int s;
/* sanity check for alignment. */
if (off % 4 != 0 || m->m_pkthdr.len % 4 != 0) {
printf("IPv6 ESP input: packet alignment problem "
"(off=%d, pktlen=%d)\n", off, m->m_pkthdr.len);
ipsec6stat.in_inval++;
goto bad;
}
IP6_EXTHDR_CHECK(m, off, sizeof(struct esp), IPPROTO_DONE);
ip6 = mtod(m, struct ip6_hdr *);
esp = (struct esp *)(((u_int8_t *)ip6) + off);
if (ntohs(ip6->ip6_plen) == 0) {
printf("IPv6 ESP input: ESP with IPv6 jumbogram is not supported.\n");
ipsec6stat.in_inval++;
goto bad;
}
/* find the sassoc. */
spi = esp->esp_spi;
if ((sav = key_allocsa(AF_INET6,
(caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst,
IPPROTO_ESP, spi)) == 0) {
printf("IPv6 ESP input: no key association found for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsec6stat.in_nosa++;
goto bad;
}
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP esp6_input called to allocate SA:%p\n", sav));
if (sav->state != SADB_SASTATE_MATURE
&& sav->state != SADB_SASTATE_DYING) {
printf("IPv6 ESP input: non-mature/dying SA found for spi %u; "
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsec6stat.in_badspi++;
goto bad;
}
if (sav->alg_enc == SADB_EALG_NONE) {
printf("IPv6 ESP input: unspecified encryption algorithm "
"for spi %u;"
"dropping the packet for simplicity\n",
(u_int32_t)ntohl(spi));
ipsec6stat.in_badspi++;
goto bad;
}
algo = &esp_algorithms[sav->alg_enc]; /*XXX*/
/* check if we have proper ivlen information */
ivlen = sav->ivlen;
if (ivlen < 0) {
log(LOG_NOTICE, "inproper ivlen in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_badspi++;
goto bad;
}
if (!((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay
&& (sav->alg_auth && sav->key_auth)))
goto noreplaycheck;
if (sav->alg_auth == SADB_AALG_NULL)
goto noreplaycheck;
/*
* check for sequence number.
*/
if (ipsec_chkreplay(ntohl(((struct newesp *)esp)->esp_seq), sav))
; /*okey*/
else {
ipsec6stat.in_espreplay++;
log(LOG_AUTH, "replay packet in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
goto bad;
}
/* check ICV */
{
struct mbuf *n;
size_t len;
u_char sum0[AH_MAXSUMSIZE];
u_char sum[AH_MAXSUMSIZE];
struct ah_algorithm *sumalgo;
size_t siz;
sumalgo = &ah_algorithms[sav->alg_auth];
siz = (((*sumalgo->sumsiz)(sav) + 3) & ~(4 - 1));
if (AH_MAXSUMSIZE < siz) {
printf("internal error: AH_MAXSUMSIZE must be larger than %lu\n",
(u_long)siz);
ipsec6stat.in_inval++;
goto bad;
}
n = m;
len = m->m_pkthdr.len;
len -= siz; /*XXX*/
while (n && 0 < len) {
if (len < n->m_len)
break;
len -= n->m_len;
n = n->m_next;
}
if (!n) {
printf("mbuf chain problem?\n");
ipsec6stat.in_inval++;
goto bad;
}
m_copydata(n, len, siz, &sum0[0]);
if (esp_auth(m, off, m->m_pkthdr.len - off - siz, sav, sum)) {
log(LOG_AUTH, "auth fail in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_espauthfail++;
goto bad;
}
if (bcmp(sum0, sum, siz) != 0) {
log(LOG_AUTH, "auth fail in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_espauthfail++;
goto bad;
}
/* strip off */
m->m_pkthdr.len -= siz;
n->m_len -= siz;
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - siz);
m->m_flags |= M_AUTHIPDGM;
ipsec6stat.in_espauthsucc++;
}
/*
* update sequence number.
*/
if ((sav->flags & SADB_X_EXT_OLD) == 0 && sav->replay) {
(void)ipsec_updatereplay(ntohl(((struct newesp *)esp)->esp_seq), sav);
}
noreplaycheck:
/* process main esp header. */
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1827 */
esplen = sizeof(struct esp);
} else {
/* RFC 2406 */
if (sav->flags & SADB_X_EXT_DERIV)
esplen = sizeof(struct esp);
else
esplen = sizeof(struct newesp);
}
IP6_EXTHDR_CHECK(m, off, esplen + ivlen, IPPROTO_DONE); /*XXX*/
/*
* decrypt the packet.
*/
if (!algo->decrypt)
panic("internal error: no decrypt function");
if ((*algo->decrypt)(m, off, sav, algo, ivlen)) {
log(LOG_AUTH, "decrypt fail in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_inval++;
goto bad;
}
ipsec6stat.in_esphist[sav->alg_enc]++;
m->m_flags |= M_DECRYPTED;
#ifdef garbled_data_found_on_mbuf_after_packet
{
/*
* For simplicity, we'll trim the packet so that there's no extra
* part appended after IP packet.
* This is rare case for some odd drivers, so there should be no
* performance hit.
*/
/*
* Note that, in ip_input, ip_len was already flipped and header
* length was subtracted from ip_len.
*/
if (m->m_pkthdr.len != hlen + ip->ip_len)
{
size_t siz;
struct mbuf *n;
siz = hlen + ip->ip_len;
/* find the final mbuf */
for (n = m; n; n = n->m_next) {
if (n->m_len < siz)
siz -= n->m_len;
else
break;
}
if (!n) {
printf("invalid packet\n");
ipsec6stat.in_inval++;
goto bad;
}
/* trim the final mbuf */
if (n->m_len < siz) {
printf("invalid size: %d %d\n", n->m_len, siz);
ipsec6stat.in_inval++;
goto bad;
}
n->m_len = siz;
/* dispose the rest of the packet */
m_freem(n->m_next);
n->m_next = NULL;
m->m_pkthdr.len = hlen + ip->ip_len;
}
}
#endif
{
/*
* find the trailer of the ESP.
*/
struct mbuf *n; /*the last mbuf on the mbuf chain, m_len > 0 */
struct mbuf *o; /*the last mbuf on the mbuf chain */
o = m;
n = NULL;
while (o) {
if (0 < o->m_len)
n = o;
o = o->m_next;
}
if (!n || n->m_len < sizeof(struct esptail)) {
printf("IPv6 ESP input: assertion on pad part failed; "
"dropping the packet\n");
ipsec6stat.in_inval++;
goto bad;
}
esptail = (struct esptail *)
(mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
nxt = esptail->esp_nxt;
taillen = esptail->esp_padlen + 2;
if (m->m_pkthdr.len < taillen
|| m->m_pkthdr.len - taillen < sizeof(struct ip6_hdr)) { /*?*/
log(LOG_NOTICE, "bad pad length in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_inval++;
goto bad;
}
/*
* XXX strip off the padding.
*/
if (taillen < n->m_len) {
/* trailing pad data is included in the last mbuf item. */
n->m_len -= taillen;
m->m_pkthdr.len -= taillen;
} else {
/* trailing pad data spans on multiple mbuf item. */
size_t siz;
siz = m->m_pkthdr.len;
if (siz < taillen) {
log(LOG_NOTICE, "bad packet length in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_inval++;
goto bad;
}
siz -= taillen;
/* find the final mbuf */
for (n = m; n; n = n->m_next) {
if (n->m_len < siz)
siz -= n->m_len;
else
break;
}
if (!n) {
printf("invalid packet\n");
ipsec6stat.in_inval++;
goto bad;
}
/* trim the final mbuf */
if (n->m_len < siz) {
printf("invalid size: %d %lu\n", n->m_len, (u_long)siz);
ipsec6stat.in_inval++;
goto bad;
}
n->m_len = siz;
/* dispose the rest of the packet */
m_freem(n->m_next);
n->m_next = NULL;
m->m_pkthdr.len -= taillen;
}
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - taillen);
}
/* was it transmitted over the IPsec tunnel SA? */
if (ipsec6_tunnel_validate(ip6, nxt, sav) && nxt == IPPROTO_IPV6) {
/*
* strip off all the headers that precedes ESP header.
* IP6 xx ESP IP6' payload -> IP6' payload
*
* XXX more sanity checks
* XXX relationship with gif?
*/
u_int32_t flowinfo; /*net endian*/
flowinfo = ip6->ip6_flow;
m_adj(m, off + esplen + ivlen);
if (m->m_len < sizeof(*ip6)) {
/*
* m_pullup is prohibited in KAME IPv6 input processing
* but there's no other way!
*/
m = m_pullup(m, sizeof(*ip6));
if (!m) {
ipsec6stat.in_inval++;
goto bad;
}
}
ip6 = mtod(m, struct ip6_hdr *);
/* ECN consideration. */
ip6_ecn_egress(ip6_ipsec_ecn, &flowinfo, &ip6->ip6_flow);
if (!key_checktunnelsanity(sav, AF_INET6,
(caddr_t)&ip6->ip6_src, (caddr_t)&ip6->ip6_dst)) {
log(LOG_NOTICE, "ipsec tunnel address mismatch in IPv6 ESP input: %s %s\n",
ipsec6_logpacketstr(ip6, spi),
ipsec_logsastr(sav));
ipsec6stat.in_inval++;
goto bad;
}
key_sa_recordxfer(sav, m);
s = splimp();
if (IF_QFULL(&ip6intrq)) {
ipsec6stat.in_inval++;
goto bad;
}
IF_ENQUEUE(&ip6intrq, m);
m = NULL;
schednetisr(NETISR_IPV6); /*can be skipped but to make sure*/
splx(s);
nxt = IPPROTO_DONE;
} else {
/*
* strip off ESP header and IV.
* We do deep-copy since KAME requires packet to be placed
* in a single mbuf.
*/
size_t stripsiz;
char *prvnxtp;
/*
* Set the next header field of the previous header correctly.
*/
prvnxtp = ip6_get_prevhdr(m, off); /* XXX */
*prvnxtp = nxt;
stripsiz = esplen + ivlen;
ip6 = mtod(m, struct ip6_hdr *);
ovbcopy((caddr_t)ip6, (caddr_t)(((u_char *)ip6) + stripsiz),
off);
m->m_data += stripsiz;
m->m_len -= stripsiz;
m->m_pkthdr.len -= stripsiz;
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_plen = htons(ntohs(ip6->ip6_plen) - stripsiz);
key_sa_recordxfer(sav, m);
}
*offp = off;
*mp = m;
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP esp6_input call free SA:%p\n", sav));
key_freesav(sav);
}
ipsec6stat.in_success++;
return nxt;
bad:
if (sav) {
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP esp6_input call free SA:%p\n", sav));
key_freesav(sav);
}
if (m)
m_freem(m);
return IPPROTO_DONE;
}
#endif /* INET6 */

683
sys/netinet6/esp_output.c Normal file
View File

@ -0,0 +1,683 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
/*
* RFC1827/2406 Encapsulated Security Payload.
*/
#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/socketvar.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_var.h>
#include <netinet/in_pcb.h>
#ifdef INET6
#include <netinet6/ip6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/icmp6.h>
#endif
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#ifdef INET6
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#endif
#ifdef IPSEC_ESP
#include <netinet6/esp.h>
#ifdef INET6
#include <netinet6/esp6.h>
#endif
#endif
#include <netkey/key.h>
#include <netkey/keydb.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#include <net/net_osdep.h>
static int esp_output __P((struct mbuf *, u_char *, struct mbuf *,
struct ipsecrequest *, int));
/*
* compute ESP header size.
*/
size_t
esp_hdrsiz(isr)
struct ipsecrequest *isr;
{
struct secasvar *sav;
struct esp_algorithm *algo;
size_t ivlen;
size_t authlen;
size_t hdrsiz;
/* sanity check */
if (isr == NULL)
panic("esp_hdrsiz: NULL was passed.\n");
sav = isr->sav;
if (isr->saidx.proto != IPPROTO_ESP)
panic("unsupported mode passed to esp_hdrsiz");
if (sav == NULL)
goto contrive;
if (sav->state != SADB_SASTATE_MATURE
&& sav->state != SADB_SASTATE_DYING)
goto contrive;
/* we need transport mode ESP. */
algo = &esp_algorithms[sav->alg_enc];
if (!algo)
goto contrive;
ivlen = sav->ivlen;
if (ivlen < 0)
goto contrive;
/*
* XXX
* right now we don't calcurate the padding size. simply
* treat the padding size as constant, for simplicity.
*
* XXX variable size padding support
*/
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1827 */
hdrsiz = sizeof(struct esp) + ivlen + 9;
} else {
/* RFC 2406 */
if (sav->replay && sav->alg_auth && sav->key_auth)
authlen = (*ah_algorithms[sav->alg_auth].sumsiz)(sav);
else
authlen = 0;
hdrsiz = sizeof(struct newesp) + ivlen + 9 + authlen;
}
return hdrsiz;
contrive:
/*
* ASSUMING:
* sizeof(struct newesp) > sizeof(struct esp).
* 8 = ivlen for CBC mode (RFC2451).
* 9 = (maximum padding length without random Padding length)
* + (Pad Length field) + (Next Header field).
* 16 = maximum ICV we supported.
*/
return sizeof(struct newesp) + 8 + 9 + 16;
}
/*
* Modify the packet so that the payload is encrypted.
* The mbuf (m) must start with IPv4 or IPv6 header.
* On failure, free the given mbuf and return NULL.
*
* on invocation:
* m nexthdrp md
* v v v
* IP ......... payload
* during the encryption:
* m nexthdrp mprev md
* v v v v
* IP ............... esp iv payload pad padlen nxthdr
* <--><-><------><--------------->
* esplen plen extendsiz
* ivlen
* <-----> esphlen
* <-> hlen
* <-----------------> espoff
*/
static int
esp_output(m, nexthdrp, md, isr, af)
struct mbuf *m;
u_char *nexthdrp;
struct mbuf *md;
struct ipsecrequest *isr;
int af;
{
struct mbuf *n;
struct mbuf *mprev;
struct esp *esp;
struct esptail *esptail;
struct secasvar *sav = isr->sav;
struct esp_algorithm *algo;
u_int32_t spi;
u_int8_t nxt = 0;
size_t plen; /*payload length to be encrypted*/
size_t espoff;
int ivlen;
int afnumber;
size_t extendsiz;
int error = 0;
switch (af) {
#ifdef INET
case AF_INET:
afnumber = 4;
break;
#endif
#ifdef INET6
case AF_INET6:
afnumber = 6;
break;
#endif
default:
printf("esp_output: unsupported af %d\n", af);
return 0; /* no change at all */
}
/* some sanity check */
if ((sav->flags & SADB_X_EXT_OLD) == 0 && !sav->replay) {
switch (af) {
#ifdef INET
case AF_INET:
{
struct ip *ip;
ip = mtod(m, struct ip *);
printf("esp4_output: internal error: "
"sav->replay is null: "
"%x->%x, SPI=%u\n",
(u_int32_t)ntohl(ip->ip_src.s_addr),
(u_int32_t)ntohl(ip->ip_dst.s_addr),
(u_int32_t)ntohl(sav->spi));
ipsecstat.out_inval++;
m_freem(m);
return EINVAL;
}
#endif /*INET*/
#ifdef INET6
case AF_INET6:
{
struct ip6_hdr *ip6;
ip6 = mtod(m, struct ip6_hdr *);
printf("esp6_output: internal error: "
"sav->replay is null: SPI=%u\n",
(u_int32_t)ntohl(sav->spi));
ipsec6stat.out_inval++;
m_freem(m);
return EINVAL;
}
#endif /*INET6*/
}
}
algo = &esp_algorithms[sav->alg_enc]; /*XXX*/
spi = sav->spi;
ivlen = sav->ivlen;
/* should be okey */
if (ivlen < 0) {
panic("invalid ivlen");
}
{
/*
* insert ESP header.
* XXX inserts ESP header right after IPv4 header. should
* chase the header chain.
* XXX sequential number
*/
#ifdef INET
struct ip *ip = NULL;
#endif
#ifdef INET6
struct ip6_hdr *ip6 = NULL;
#endif
size_t esplen; /*sizeof(struct esp/newesp)*/
size_t esphlen; /*sizeof(struct esp/newesp) + ivlen*/
size_t hlen = 0; /*ip header len*/
if (sav->flags & SADB_X_EXT_OLD) {
/* RFC 1827 */
esplen = sizeof(struct esp);
} else {
/* RFC 2406 */
if (sav->flags & SADB_X_EXT_DERIV)
esplen = sizeof(struct esp);
else
esplen = sizeof(struct newesp);
}
esphlen = esplen + ivlen;
for (mprev = m; mprev && mprev->m_next != md; mprev = mprev->m_next)
;
if (mprev == NULL || mprev->m_next != md) {
printf("esp%d_output: md is not in chain\n", afnumber);
m_freem(m);
return EINVAL;
}
plen = 0;
for (n = md; n; n = n->m_next)
plen += n->m_len;
switch (af) {
#ifdef INET
case AF_INET:
ip = mtod(m, struct ip *);
#ifdef _IP_VHL
hlen = IP_VHL_HL(ip->ip_vhl) << 2;
#else
hlen = ip->ip_hl << 2;
#endif
break;
#endif
#ifdef INET6
case AF_INET6:
ip6 = mtod(m, struct ip6_hdr *);
hlen = sizeof(*ip6);
break;
#endif
}
/* make the packet over-writable */
mprev->m_next = NULL;
if ((md = ipsec_copypkt(md)) == NULL) {
m_freem(m);
error = ENOBUFS;
goto fail;
}
mprev->m_next = md;
espoff = m->m_pkthdr.len - plen;
/*
* grow the mbuf to accomodate ESP header.
* before: IP ... payload
* after: IP ... ESP IV payload
*/
if (M_LEADINGSPACE(md) < esphlen) {
MGET(n, M_DONTWAIT, MT_DATA);
if (!n) {
m_freem(m);
error = ENOBUFS;
goto fail;
}
n->m_len = esphlen;
mprev->m_next = n;
n->m_next = md;
m->m_pkthdr.len += esphlen;
esp = mtod(n, struct esp *);
} else {
md->m_len += esphlen;
md->m_data -= esphlen;
m->m_pkthdr.len += esphlen;
esp = mtod(md, struct esp *);
}
nxt = *nexthdrp;
*nexthdrp = IPPROTO_ESP;
switch (af) {
#ifdef INET
case AF_INET:
if (esphlen < (IP_MAXPACKET - ntohs(ip->ip_len)))
ip->ip_len = htons(ntohs(ip->ip_len) + esphlen);
else {
printf("IPv4 ESP output: size exceeds limit\n");
ipsecstat.out_inval++;
m_freem(m);
error = EMSGSIZE;
goto fail;
}
break;
#endif
#ifdef INET6
case AF_INET6:
/* total packet length will be computed in ip6_output() */
break;
#endif
}
}
/* initialize esp header. */
esp->esp_spi = spi;
if ((sav->flags & SADB_X_EXT_OLD) == 0) {
struct newesp *nesp;
nesp = (struct newesp *)esp;
sav->replay->count++;
/*
* XXX sequence number must not be cycled, if the SA is
* installed by IKE daemon.
*/
nesp->esp_seq = htonl(sav->replay->count);
}
{
/*
* find the last mbuf. make some room for ESP trailer.
* XXX new-esp authentication data
*/
#ifdef INET
struct ip *ip = NULL;
#endif
size_t padbound;
if (algo->padbound)
padbound = algo->padbound;
else
padbound = 4;
/* ESP packet, including nxthdr field, must be length of 4n */
if (padbound < 4)
padbound = 4;
extendsiz = padbound - (plen % padbound);
if (extendsiz == 1)
extendsiz = padbound + 1;
n = m;
while (n->m_next)
n = n->m_next;
/*
* if M_EXT, the external part may be shared among
* two consequtive TCP packets.
*/
if (!(n->m_flags & M_EXT) && extendsiz < M_TRAILINGSPACE(n)) {
switch (sav->flags & SADB_X_EXT_PMASK) {
case SADB_X_EXT_PRAND:
break;
case SADB_X_EXT_PZERO:
bzero((caddr_t)(mtod(n, u_int8_t *) + n->m_len),
extendsiz);
break;
case SADB_X_EXT_PSEQ:
{
int i;
u_char *p;
p = mtod(n, u_char *) + n->m_len;
for (i = 0; i < extendsiz; i++)
p[i] = i + 1;
break;
}
}
n->m_len += extendsiz;
m->m_pkthdr.len += extendsiz;
} else {
struct mbuf *nn;
MGET(nn, M_DONTWAIT, MT_DATA);
if (!nn) {
printf("esp%d_output: can't alloc mbuf", afnumber);
m_freem(m);
error = ENOBUFS;
goto fail;
}
nn->m_len = extendsiz;
switch (sav->flags & SADB_X_EXT_PMASK) {
case SADB_X_EXT_PRAND:
break;
case SADB_X_EXT_PZERO:
bzero(mtod(nn, caddr_t), extendsiz);
break;
case SADB_X_EXT_PSEQ:
{
int i;
u_char *p;
p = mtod(nn, u_char *);
for (i = 0; i < extendsiz; i++)
p[i] = i + 1;
break;
}
}
nn->m_next = NULL;
n->m_next = nn;
n = nn;
m->m_pkthdr.len += extendsiz;
}
/* initialize esp trailer. */
esptail = (struct esptail *)
(mtod(n, u_int8_t *) + n->m_len - sizeof(struct esptail));
esptail->esp_nxt = nxt;
esptail->esp_padlen = extendsiz - 2;
/* modify IP header (for ESP header part only) */
switch (af) {
#ifdef INET
case AF_INET:
ip = mtod(m, struct ip *);
if (extendsiz < (IP_MAXPACKET - ntohs(ip->ip_len)))
ip->ip_len = htons(ntohs(ip->ip_len) + extendsiz);
else {
printf("IPv4 ESP output: size exceeds limit\n");
ipsecstat.out_inval++;
m_freem(m);
error = EMSGSIZE;
goto fail;
}
break;
#endif
#ifdef INET6
case AF_INET6:
/* total packet length will be computed in ip6_output() */
break;
#endif
}
}
/*
* encrypt the packet, based on security association
* and the algorithm specified.
*/
if (!algo->encrypt)
panic("internal error: no encrypt function");
if ((*algo->encrypt)(m, espoff, plen + extendsiz, sav, algo, ivlen)) {
printf("packet encryption failure\n");
m_freem(m);
switch (af) {
#ifdef INET
case AF_INET:
ipsecstat.out_inval++;
break;
#endif
#ifdef INET6
case AF_INET6:
ipsec6stat.out_inval++;
break;
#endif
}
error = EINVAL;
goto fail;
}
/*
* calculate ICV if required.
*/
if (!sav->replay)
goto noantireplay;
if (!sav->key_auth)
goto noantireplay;
if (!sav->alg_auth)
goto noantireplay;
{
u_char authbuf[AH_MAXSUMSIZE];
struct mbuf *n;
u_char *p;
size_t siz;
struct ip *ip;
siz = (((*ah_algorithms[sav->alg_auth].sumsiz)(sav) + 3) & ~(4 - 1));
if (AH_MAXSUMSIZE < siz)
panic("assertion failed for AH_MAXSUMSIZE");
if (esp_auth(m, espoff, m->m_pkthdr.len - espoff, sav, authbuf))
goto noantireplay;
n = m;
while (n->m_next)
n = n->m_next;
if (!(n->m_flags & M_EXT) && siz < M_TRAILINGSPACE(n)) { /*XXX*/
n->m_len += siz;
m->m_pkthdr.len += siz;
p = mtod(n, u_char *) + n->m_len - siz;
} else {
struct mbuf *nn;
MGET(nn, M_DONTWAIT, MT_DATA);
if (!nn) {
printf("can't alloc mbuf in esp%d_output", afnumber);
m_freem(m);
error = ENOBUFS;
goto fail;
}
nn->m_len = siz;
nn->m_next = NULL;
n->m_next = nn;
n = nn;
m->m_pkthdr.len += siz;
p = mtod(nn, u_char *);
}
bcopy(authbuf, p, siz);
/* modify IP header (for ESP header part only) */
switch (af) {
#ifdef INET
case AF_INET:
ip = mtod(m, struct ip *);
if (siz < (IP_MAXPACKET - ntohs(ip->ip_len)))
ip->ip_len = htons(ntohs(ip->ip_len) + siz);
else {
printf("IPv4 ESP output: size exceeds limit\n");
ipsecstat.out_inval++;
m_freem(m);
error = EMSGSIZE;
goto fail;
}
break;
#endif
#ifdef INET6
case AF_INET6:
/* total packet length will be computed in ip6_output() */
break;
#endif
}
}
noantireplay:
if (!m)
printf("NULL mbuf after encryption in esp%d_output", afnumber);
else {
switch (af) {
#ifdef INET
case AF_INET:
ipsecstat.out_success++;
break;
#endif
#ifdef INET6
case AF_INET6:
ipsec6stat.out_success++;
break;
#endif
}
}
switch (af) {
#ifdef INET
case AF_INET:
ipsecstat.out_esphist[sav->alg_enc]++;
break;
#endif
#ifdef INET6
case AF_INET6:
ipsec6stat.out_esphist[sav->alg_enc]++;
break;
#endif
}
key_sa_recordxfer(sav, m);
return 0;
fail:
#if 1
return error;
#else
panic("something bad in esp_output");
#endif
}
#ifdef INET
int
esp4_output(m, isr)
struct mbuf *m;
struct ipsecrequest *isr;
{
struct ip *ip;
if (m->m_len < sizeof(struct ip)) {
printf("esp4_output: first mbuf too short\n");
m_freem(m);
return NULL;
}
ip = mtod(m, struct ip *);
/* XXX assumes that m->m_next points to payload */
return esp_output(m, &ip->ip_p, m->m_next, isr, AF_INET);
}
#endif /*INET*/
#ifdef INET6
int
esp6_output(m, nexthdrp, md, isr)
struct mbuf *m;
u_char *nexthdrp;
struct mbuf *md;
struct ipsecrequest *isr;
{
if (m->m_len < sizeof(struct ip6_hdr)) {
printf("esp6_output: first mbuf too short\n");
m_freem(m);
return NULL;
}
return esp_output(m, nexthdrp, md, isr, AF_INET6);
}
#endif /*INET6*/

View File

@ -64,7 +64,7 @@
* @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
*/
#include "opt_key.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -96,15 +96,15 @@
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#include <netkey/key.h>
#ifdef KEY_DEBUG
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define DPRINTF(lev,arg)
#define DDO(lev, stmt)
#define DP(x, y, z)
#endif /* KEY_DEBUG */
#define KEYDEBUG(lev,arg)
#endif
#endif /* IPSEC */
#include "faith.h"
@ -1285,9 +1285,6 @@ icmp6_reflect(m, off)
*/
m->m_flags &= ~(M_BCAST|M_MCAST);
#ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
#endif /*IPSEC*/
#ifdef COMPAT_RFC1885
ip6_output(m, NULL, &icmp6_reflect_rt, 0, NULL, &outif);
@ -1725,9 +1722,6 @@ noredhdropt:;
= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), ntohs(ip6->ip6_plen));
/* send the packet to outside... */
#ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
#endif /*IPSEC*/
ip6_output(m, NULL, NULL, 0, NULL, &outif);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);

View File

@ -386,8 +386,8 @@ struct rr_pco_use { /* use prefix part */
u_int32_t rpu_flags;
struct in6_addr rpu_prefix;
};
#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20
#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80
#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40
#if BYTE_ORDER == BIG_ENDIAN
#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000

View File

@ -55,6 +55,8 @@
#include <netinet6/ip6_var.h>
#include <netinet6/in6_gif.h>
#include <netinet6/ip6.h>
#include <netinet/ip_ecn.h>
#include <netinet6/ip6_ecn.h>
#include <net/if_gif.h>
@ -73,6 +75,7 @@ in6_gif_output(ifp, family, m, rt)
struct sockaddr_in6 *sin6_dst = (struct sockaddr_in6 *)sc->gif_pdst;
struct ip6_hdr *ip6;
int proto;
u_int8_t itos, otos;
if (sin6_src == NULL || sin6_dst == NULL ||
sin6_src->sin6_family != AF_INET6 ||
@ -94,6 +97,7 @@ in6_gif_output(ifp, family, m, rt)
return ENOBUFS;
}
ip = mtod(m, struct ip *);
itos = ip->ip_tos;
break;
}
#endif
@ -107,6 +111,7 @@ in6_gif_output(ifp, family, m, rt)
return ENOBUFS;
}
ip6 = mtod(m, struct ip6_hdr *);
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
break;
}
default:
@ -153,6 +158,11 @@ in6_gif_output(ifp, family, m, rt)
return ENETUNREACH;
}
}
if (ifp->if_flags & IFF_LINK1) {
otos = 0;
ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
ip6->ip6_flow |= htonl((u_int32_t)otos << 20);
}
if (dst->sin6_family != sin6_dst->sin6_family ||
!IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) {
@ -175,9 +185,6 @@ in6_gif_output(ifp, family, m, rt)
}
}
#ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
#endif /*IPSEC*/
return(ip6_output(m, 0, &sc->gif_ro6, 0, 0, NULL));
}
@ -191,6 +198,7 @@ int in6_gif_input(mp, offp, proto)
struct ip6_hdr *ip6;
int i;
int af = 0;
u_int32_t otos;
ip6 = mtod(m, struct ip6_hdr *);
@ -222,7 +230,8 @@ int in6_gif_input(mp, offp, proto)
ip6stat.ip6s_nogif++;
return IPPROTO_DONE;
}
otos = ip6->ip6_flow;
m_adj(m, *offp);
switch (proto) {
@ -230,13 +239,17 @@ int in6_gif_input(mp, offp, proto)
case IPPROTO_IPV4:
{
struct ip *ip;
u_int8_t otos8;
af = AF_INET;
otos8 = (ntohl(otos) >> 20) & 0xff;
if (m->m_len < sizeof(*ip)) {
m = m_pullup(m, sizeof(*ip));
if (!m)
return IPPROTO_DONE;
}
ip = mtod(m, struct ip *);
if (gifp->if_flags & IFF_LINK1)
ip_ecn_egress(ECN_ALLOWED, &otos8, &ip->ip_tos);
break;
}
#endif /* INET */
@ -250,6 +263,8 @@ int in6_gif_input(mp, offp, proto)
return IPPROTO_DONE;
}
ip6 = mtod(m, struct ip6_hdr *);
if (gifp->if_flags & IFF_LINK1)
ip6_ecn_egress(ECN_ALLOWED, &otos, &ip6->ip6_flow);
break;
}
default:

View File

@ -65,7 +65,7 @@
* $FreeBSD$
*/
#include "opt_key.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -99,15 +99,15 @@
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netinet6/ah.h>
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#include <netkey/key.h>
#ifdef KEY_DEBUG
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define DPRINTF(lev,arg)
#define DDO(lev, stmt)
#define DP(x, y, z)
#endif /* KEY_DEBUG */
#define KEYDEBUG(lev,arg)
#endif /* IPSEC_DEBUG */
#endif /* IPSEC */
struct in6_addr zeroin6_addr;

View File

@ -64,6 +64,8 @@
* @(#)in_proto.c 8.1 (Berkeley) 6/10/93
*/
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@ -102,12 +104,13 @@
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netinet6/ipsec6.h>
#include <netinet6/ah.h>
#include <netinet6/ipsec6.h>
#include <netinet6/ah6.h>
#ifdef IPSEC_ESP
#include <netinet6/esp.h>
#include <netinet6/esp6.h>
#endif
#include <netinet6/ipcomp.h>
#endif /*IPSEC*/
#include <netinet6/ip6protosw.h>
@ -186,12 +189,6 @@ struct ip6protosw inet6sw[] = {
&nousrreqs,
},
#endif
{ SOCK_RAW, &inet6domain, IPPROTO_IPCOMP, PR_ATOMIC|PR_ADDR,
ipcomp6_input, 0, 0, 0,
0,
0, 0, 0, 0,
&nousrreqs,
},
#endif /* IPSEC */
#if NGIF > 0
{ SOCK_RAW, &inet6domain, IPPROTO_IPV4, PR_ATOMIC|PR_ADDR,

View File

@ -75,12 +75,16 @@
struct ip6_hdr {
union {
struct ip6_hdrctl {
u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
u_int32_t ip6_un1_flow; /* 4 bits version,
* 8 bits traffic
* class,
* 20 bits flow-ID */
u_int16_t ip6_un1_plen; /* payload length */
u_int8_t ip6_un1_nxt; /* next header */
u_int8_t ip6_un1_hlim; /* hop limit */
} ip6_un1;
u_int8_t ip6_un2_vfc; /* 4 bits version, 4 bits class */
u_int8_t ip6_un2_vfc; /* 4 bits version,
* top 4 bits trafic class */
} ip6_ctlun;
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */

43
sys/netinet6/ip6_ecn.h Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ip_ecn.h,v 1.2 1999/08/19 12:57:44 itojun Exp $
* $FreeBSD$
*/
/*
* ECN consideration on tunnel ingress/egress operation.
* http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt
*/
#if defined(KERNEL) || defined(_KERNEL)
extern void ip6_ecn_ingress __P((int, u_int32_t *, u_int32_t *));
extern void ip6_ecn_egress __P((int, u_int32_t *, u_int32_t *));
#endif

View File

@ -29,7 +29,7 @@
* $FreeBSD$
*/
#include "opt_key.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -57,13 +57,11 @@
#include <netinet6/ipsec.h>
#include <netinet6/ipsec6.h>
#include <netkey/key.h>
#ifdef KEY_DEBUG
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define DPRINTF(lev,arg)
#define DDO(lev, stmt)
#define DP(x, y, z)
#endif /* KEY_DEBUG */
#define KEYDEBUG(lev,arg)
#endif
#endif /* IPSEC_IPV6FWD */
#ifdef IPV6FIREWALL

View File

@ -1,202 +0,0 @@
/*
* Copyright (c) 1993 Daniel Boulet
* Copyright (c) 1994 Ugen J.S.Antsilevich
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
*
* Redistribution in binary form may occur without any restrictions.
* Obviously, it would be nice if you gave credit where credit is due
* but requiring it would be too onerous.
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
* $Id: ip6_fw.h,v 1.1 1999/08/06 14:10:09 itojun Exp $
* $FreeBSD$
*/
#ifndef _IP6_FW_H
#define _IP6_FW_H
#include <net/if.h>
/*
* This union structure identifies an interface, either explicitly
* by name or implicitly by IP address. The flags IP_FW_F_IIFNAME
* and IP_FW_F_OIFNAME say how to interpret this structure. An
* interface unit number of -1 matches any unit number, while an
* IP address of 0.0.0.0 indicates matches any interface.
*
* The receive and transmit interfaces are only compared against the
* the packet if the corresponding bit (IP_FW_F_IIFACE or IP_FW_F_OIFACE)
* is set. Note some packets lack a receive or transmit interface
* (in which case the missing "interface" never matches).
*/
union ip6_fw_if {
struct in6_addr fu_via_ip6; /* Specified by IPv6 address */
struct { /* Specified by interface name */
#define FW_IFNLEN IFNAMSIZ
char name[FW_IFNLEN];
short unit; /* -1 means match any unit */
} fu_via_if;
};
/*
* Format of an IP firewall descriptor
*
* fw_src, fw_dst, fw_smsk, fw_dmsk are always stored in network byte order.
* fw_flg and fw_n*p are stored in host byte order (of course).
* Port numbers are stored in HOST byte order.
* Warning: setsockopt() will fail if sizeof(struct ip_fw) > MLEN (108)
*/
struct ip6_fw {
u_long fw_pcnt,fw_bcnt; /* Packet and byte counters */
struct in6_addr fw_src, fw_dst; /* Source and destination IPv6 addr */
/* Mask for src and dest IPv6 addr */
struct in6_addr fw_smsk, fw_dmsk;
u_short fw_number; /* Rule number */
u_short fw_flg; /* Flags word */
#define IPV6_FW_MAX_PORTS 10 /* A reasonable maximum */
/* Array of port numbers to match */
u_short fw_pts[IPV6_FW_MAX_PORTS];
u_char fw_ip6opt,fw_ip6nopt; /* IPv6 options set/unset */
u_char fw_tcpf,fw_tcpnf; /* TCP flags set/unset */
#define IPV6_FW_ICMPTYPES_DIM (32 / (sizeof(unsigned) * 8))
/* ICMP types bitmap */
unsigned fw_icmp6types[IPV6_FW_ICMPTYPES_DIM];
long timestamp; /* timestamp (tv_sec) of last match */
/* Incoming and outgoing interfaces */
union ip6_fw_if fw_in_if, fw_out_if;
union {
u_short fu_divert_port; /* Divert/tee port (options IP6DIVERT) */
u_short fu_skipto_rule; /* SKIPTO command rule number */
u_short fu_reject_code; /* REJECT response code */
} fw_un;
u_char fw_prot; /* IPv6 protocol */
u_char fw_nports; /* N'of src ports and # of dst ports */
/* in ports array (dst ports follow */
/* src ports; max of 10 ports in all; */
/* count of 0 means match all ports) */
};
#define IPV6_FW_GETNSRCP(rule) ((rule)->fw_nports & 0x0f)
#define IPV6_FW_SETNSRCP(rule, n) do { \
(rule)->fw_nports &= ~0x0f; \
(rule)->fw_nports |= (n); \
} while (0)
#define IPV6_FW_GETNDSTP(rule) ((rule)->fw_nports >> 4)
#define IPV6_FW_SETNDSTP(rule, n) do { \
(rule)->fw_nports &= ~0xf0; \
(rule)->fw_nports |= (n) << 4;\
} while (0)
#define fw_divert_port fw_un.fu_divert_port
#define fw_skipto_rule fw_un.fu_skipto_rule
#define fw_reject_code fw_un.fu_reject_code
struct ip6_fw_chain {
LIST_ENTRY(ip6_fw_chain) chain;
struct ip6_fw *rule;
};
/*
* Values for "flags" field .
*/
#define IPV6_FW_F_IN 0x0001 /* Check inbound packets */
#define IPV6_FW_F_OUT 0x0002 /* Check outbound packets */
#define IPV6_FW_F_IIFACE 0x0004 /* Apply inbound interface test */
#define IPV6_FW_F_OIFACE 0x0008 /* Apply outbound interface test */
#define IPV6_FW_F_COMMAND 0x0070 /* Mask for type of chain entry: */
#define IPV6_FW_F_DENY 0x0000 /* This is a deny rule */
#define IPV6_FW_F_REJECT 0x0010 /* Deny and send a response packet */
#define IPV6_FW_F_ACCEPT 0x0020 /* This is an accept rule */
#define IPV6_FW_F_COUNT 0x0030 /* This is a count rule */
#define IPV6_FW_F_DIVERT 0x0040 /* This is a divert rule */
#define IPV6_FW_F_TEE 0x0050 /* This is a tee rule */
#define IPV6_FW_F_SKIPTO 0x0060 /* This is a skipto rule */
#define IPV6_FW_F_PRN 0x0080 /* Print if this rule matches */
#define IPV6_FW_F_SRNG 0x0100 /* The first two src ports are a min *
* and max range (stored in host byte *
* order). */
#define IPV6_FW_F_DRNG 0x0200 /* The first two dst ports are a min *
* and max range (stored in host byte *
* order). */
/* In interface by name/unit (not IP) */
#define IPV6_FW_F_IIFNAME 0x0400
/* Out interface by name/unit (not IP) */
#define IPV6_FW_F_OIFNAME 0x0800
#define IPV6_FW_F_INVSRC 0x1000 /* Invert sense of src check */
#define IPV6_FW_F_INVDST 0x2000 /* Invert sense of dst check */
#define IPV6_FW_F_FRAG 0x4000 /* Fragment */
#define IPV6_FW_F_ICMPBIT 0x8000 /* ICMP type bitmap is valid */
#define IPV6_FW_F_MASK 0xFFFF /* All possible flag bits mask */
/*
* For backwards compatibility with rules specifying "via iface" but
* not restricted to only "in" or "out" packets, we define this combination
* of bits to represent this configuration.
*/
#define IF6_FW_F_VIAHACK (IPV6_FW_F_IN|IPV6_FW_F_OUT|IPV6_FW_F_IIFACE|\
IPV6_FW_F_OIFACE)
/*
* Definitions for REJECT response codes.
* Values less than 256 correspond to ICMP unreachable codes.
*/
#define IPV6_FW_REJECT_RST 0x0100 /* TCP packets: send RST */
/*
* Definitions for IPv6 option names.
*/
#define IPV6_FW_IP6OPT_HOPOPT 0x01
#define IPV6_FW_IP6OPT_ROUTE 0x02
#define IPV6_FW_IP6OPT_FRAG 0x04
#define IPV6_FW_IP6OPT_ESP 0x08
#define IPV6_FW_IP6OPT_AH 0x10
#define IPV6_FW_IP6OPT_NONXT 0x20
#define IPV6_FW_IP6OPT_OPTS 0x40
/*
* Definitions for TCP flags.
*/
#define IPV6_FW_TCPF_FIN TH_FIN
#define IPV6_FW_TCPF_SYN TH_SYN
#define IPV6_FW_TCPF_RST TH_RST
#define IPV6_FW_TCPF_PSH TH_PUSH
#define IPV6_FW_TCPF_ACK TH_ACK
#define IPV6_FW_TCPF_URG TH_URG
#define IPV6_FW_TCPF_ESTAB 0x40
/*
* Main firewall chains definitions and global var's definitions.
*/
#ifdef _KERNEL
/*
* Function definitions.
*/
void ip6_fw_init(void);
/* Firewall hooks */
struct ip6_hdr;
typedef int ip6_fw_chk_t __P((struct ip6_hdr**, struct ifnet*,
u_short *, struct mbuf**));
typedef int ip6_fw_ctl_t __P((int, struct mbuf**));
extern ip6_fw_chk_t *ip6_fw_chk_ptr;
extern ip6_fw_ctl_t *ip6_fw_ctl_ptr;
#endif /* _KERNEL */
#endif /* _IP6_FW_H */

View File

@ -64,6 +64,8 @@
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
*/
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@ -209,7 +211,8 @@ ip6_init2(dummy)
}
/* cheat */
SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_init2, NULL);
/* This must be after route_init(), which is now SI_ORDER_THIRD */
SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL);
/*
* IP6 input interrupt handling. Just pass the packet to ip6_input.

View File

@ -64,7 +64,7 @@
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
*/
#include "opt_key.h"
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/malloc.h>
@ -92,13 +92,11 @@
#include <netinet6/ipsec.h>
#include <netinet6/ipsec6.h>
#include <netkey/key.h>
#ifdef KEY_DEBUG
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define DPRINTF(lev,arg)
#define DDO(lev, stmt)
#define DP(x, y, z)
#endif /* KEY_DEBUG */
#define KEYDEBUG(lev,arg)
#endif
#endif /* IPSEC */
#include "loop.h"
@ -166,8 +164,11 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
struct secpolicy *sp = NULL;
/* for AH processing. stupid to have "socket" variable in IP layer... */
so = (struct socket *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
if ((flags & IPV6_SOCKINMRCVIF) != 0) {
so = (struct socket *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
} else
so = NULL;
ip6 = mtod(m, struct ip6_hdr *);
#endif /* IPSEC */
@ -1321,9 +1322,11 @@ ip6_ctloutput(so, sopt)
caddr_t req = NULL;
struct mbuf *m;
if (error = soopt_getm(sopt, &m)) /* XXX */
if ((error = soopt_getm(sopt, &m))
!= 0) /* XXX */
break;
if (error = soopt_mcopyin(sopt, m)) /* XXX */
if ((error = soopt_mcopyin(sopt, m))
!= 0) /* XXX */
break;
if (m != 0)
req = mtod(m, caddr_t);
@ -1345,9 +1348,11 @@ ip6_ctloutput(so, sopt)
if (ip6_fw_ctl_ptr == NULL)
return EINVAL;
if (error = soopt_getm(sopt, &m)) /* XXX */
if ((error = soopt_getm(sopt, &m))
!= 0) /* XXX */
break;
if (error = soopt_mcopyin(sopt, m)) /* XXX */
if ((error = soopt_mcopyin(sopt, m))
!= 0) /* XXX */
break;
error = (*ip6_fw_ctl_ptr)(optname, mp);
m = *mp;

View File

@ -173,6 +173,9 @@ struct ip6stat {
/* flags passed to ip6_output as last parameter */
#define IPV6_DADOUTPUT 0x01 /* DAD */
#define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */
#define IPV6_SOCKINMRCVIF 0x100 /* IPSEC hack;
* socket pointer in sending
* packet's m_pkthdr.rcvif */
extern struct ip6stat ip6stat; /* statistics */
extern u_int32_t ip6_id; /* fragment identifier */

3061
sys/netinet6/ipsec.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -238,6 +238,11 @@ struct ipsecstat {
}
#ifdef KERNEL
#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_inet_ipsec);
#endif
struct ipsec_output_state {
struct mbuf *m;
struct route *ro;
@ -303,6 +308,7 @@ extern struct mbuf *ipsec_copypkt __P((struct mbuf *));
#endif /*KERNEL*/
#ifndef KERNEL
extern caddr_t ipsec_set_policy __P((char *policy, int buflen));
extern int ipsec_get_policylen __P((caddr_t buf));
extern char *ipsec_dump_policy __P((caddr_t buf, char *delimiter));

View File

@ -38,6 +38,10 @@
#ifdef KERNEL
#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_inet6_ipsec6);
#endif
extern struct ipsecstat ipsec6stat;
extern struct secpolicy ip6_def_policy;
extern int ip6_esp_trans_deflev;

View File

@ -68,6 +68,8 @@
* @(#)igmp.c 8.1 (Berkeley) 7/19/93
*/
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -391,10 +393,6 @@ mld6_sendpkt(in6m, type, dst)
return;
}
mh->m_next = md;
#ifdef IPSEC
mh->m_pkthdr.rcvif = NULL;
#endif
mh->m_pkthdr.len = sizeof(struct ip6_hdr) + sizeof(struct mld6_hdr);
mh->m_len = sizeof(struct ip6_hdr);
MH_ALIGN(mh, sizeof(struct ip6_hdr));

View File

@ -29,6 +29,8 @@
* $FreeBSD$
*/
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
@ -423,9 +425,6 @@ nd6_ns_output(ifp, daddr6, taddr6, ln, dad)
nd_ns->nd_ns_cksum
= in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
#ifdef IPSEC
m->m_pkthdr.rcvif = NULL;
#endif /*IPSEC*/
ip6_output(m, NULL, NULL, dad ? IPV6_DADOUTPUT : 0, &im6o, &outif);
if (outif) {
icmp6_ifstat_inc(outif, ifs6_out_msg);

View File

@ -64,6 +64,8 @@
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
*/
#include "opt_ipsec.h"
#include <stddef.h>
#include <sys/param.h>
@ -140,7 +142,7 @@ rip6_input(mp, offp, proto)
init_sin6(&rip6src, m); /* general init */
LIST_FOREACH(in6p, &ripcb, inp_list) {
if ((in6p->in6p_vflag & INP_IPV6) == NULL)
if ((in6p->in6p_vflag & INP_IPV6) == 0)
continue;
if (in6p->in6p_ip6_nxt &&
in6p->in6p_ip6_nxt != proto)
@ -328,9 +330,10 @@ rip6_output(m, va_alist)
if (in6p->in6p_route.ro_rt)
oifp = ifindex2ifnet[in6p->in6p_route.ro_rt->rt_ifp->if_index];
}
ip6->ip6_flow = in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK;
ip6->ip6_vfc = IPV6_VERSION;
ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
(in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK);
ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
(IPV6_VERSION & IPV6_VERSION_MASK);
/* ip6_plen will be filled in ip6_output, so not fill it here. */
ip6->ip6_nxt = in6p->in6p_ip6_nxt;
ip6->ip6_hlim = in6_selecthlim(in6p, oifp);
@ -370,8 +373,8 @@ rip6_output(m, va_alist)
m->m_pkthdr.rcvif = (struct ifnet *)so;
#endif /*IPSEC*/
error = ip6_output(m, optp, &in6p->in6p_route, 0, in6p->in6p_moptions,
&oifp);
error = ip6_output(m, optp, &in6p->in6p_route, IPV6_SOCKINMRCVIF,
in6p->in6p_moptions, &oifp);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
icmp6_ifoutstat_inc(oifp, type, code);
@ -446,11 +449,9 @@ rip6_attach(struct socket *so, int proto, struct proc *p)
if (p && (error = suser(p)) != 0)
return error;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
error = soreserve(so, rip_sendspace, rip_recvspace);
if (error)
return error;
}
error = soreserve(so, rip_sendspace, rip_recvspace);
if (error)
return error;
s = splnet();
error = in_pcballoc(so, &ripcbinfo, p);
splx(s);

View File

@ -63,6 +63,8 @@
* $FreeBSD$
*/
#include "opt_ipsec.h"
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
@ -98,6 +100,7 @@
#ifdef IPSEC
#include <netinet6/ipsec.h>
#include <netinet6/ipsec6.h>
#endif /*IPSEC*/
#include "faith.h"
@ -251,11 +254,10 @@ udp6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
if (last != NULL &&
ipsec6_in_reject_so(m, last->inp_socket)) {
if (ipsec6_in_reject_so(m, last->inp_socket))
ipsec6stat.in_polvio++;
/* do not inject data into pcb */
} else
else
#endif /*IPSEC*/
if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
/*
@ -310,7 +312,7 @@ udp6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
if (last != NULL && ipsec6_in_reject_so(m, last->inp_socket)) {
if (ipsec6_in_reject_so(m, last->inp_socket)) {
ipsec6stat.in_polvio++;
goto bad;
}
@ -358,7 +360,7 @@ udp6_input(mp, offp, proto)
/*
* Check AH/ESP integrity.
*/
if (in6p != NULL && ipsec6_in_reject_so(m, in6p->in6p_socket)) {
if (ipsec6_in_reject_so(m, in6p->in6p_socket)) {
ipsec6stat.in_polvio++;
goto bad;
}
@ -475,7 +477,7 @@ udp6_getcred SYSCTL_HANDLER_ARGS
addrs[1].sin6_port,
&addrs[0].sin6_addr, addrs[0].sin6_port,
1, NULL);
if (!inp || !inp->inp_socket || !inp->inp_socket->so_cred) {
if (!inp || !inp->inp_socket) {
error = ENOENT;
goto out;
}
@ -556,8 +558,10 @@ udp6_output(in6p, m, addr6, control, p)
* Stuff checksum and output datagram.
*/
ip6 = mtod(m, struct ip6_hdr *);
ip6->ip6_flow = in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK;
ip6->ip6_vfc = IPV6_VERSION;
ip6->ip6_flow = (ip6->ip6_flow & ~IPV6_FLOWINFO_MASK) |
(in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK);
ip6->ip6_vfc = (ip6->ip6_vfc & ~IPV6_VERSION_MASK) |
(IPV6_VERSION & IPV6_VERSION_MASK);
/* ip6_plen will be filled in ip6_output. */
ip6->ip6_nxt = IPPROTO_UDP;
ip6->ip6_hlim = in6_selecthlim(in6p,
@ -584,7 +588,7 @@ udp6_output(in6p, m, addr6, control, p)
m->m_pkthdr.rcvif = (struct ifnet *)in6p->in6p_socket;
#endif /*IPSEC*/
error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
0, in6p->in6p_moptions, NULL);
IPV6_SOCKINMRCVIF, in6p->in6p_moptions, NULL);
if (addr6) {
in6_pcbdisconnect(in6p);

File diff suppressed because it is too large Load Diff

View File

@ -1,299 +1,78 @@
/*----------------------------------------------------------------------
* key.h : Declarations and Definitions for Key Engine for BSD.
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Copyright 1995 by Bao Phan, Randall Atkinson, & Dan McDonald,
* All Rights Reserved. All rights have been assigned to the US
* Naval Research Laboratory (NRL). The NRL Copyright Notice and
* License Agreement governs distribution and use of this software.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* Patents are pending on this technology. NRL grants a license
* to use this technology at no cost under the terms below with
* the additional requirement that software, hardware, and
* documentation relating to use of this technology must include
* the note that:
* This product includes technology developed at and
* licensed from the Information Technology Division,
* US Naval Research Laboratory.
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
----------------------------------------------------------------------*/
/*----------------------------------------------------------------------
# @(#)COPYRIGHT 1.1a (NRL) 17 August 1995
COPYRIGHT NOTICE
All of the documentation and software included in this software
distribution from the US Naval Research Laboratory (NRL) are
copyrighted by their respective developers.
This software and documentation were developed at NRL by various
people. Those developers have each copyrighted the portions that they
developed at NRL and have assigned All Rights for those portions to
NRL. Outside the USA, NRL also has copyright on the software
developed at NRL. The affected files all contain specific copyright
notices and those notices must be retained in any derived work.
NRL LICENSE
NRL grants permission for redistribution and use in source and binary
forms, with or without modification, of the software and documentation
created at NRL provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed at the Information
Technology Division, US Naval Research Laboratory.
4. Neither the name of the NRL nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation
are those of the authors and should not be interpreted as representing
official policies, either expressed or implied, of the US Naval
Research Laboratory (NRL).
----------------------------------------------------------------------*/
#ifndef _netkey_key_h
#define _netkey_key_h 1
/*
* PF_KEY messages
* $FreeBSD$
*/
#define KEY_ADD 1
#define KEY_DELETE 2
#define KEY_UPDATE 3
#define KEY_GET 4
#define KEY_ACQUIRE 5
#define KEY_GETSPI 6
#define KEY_REGISTER 7
#define KEY_EXPIRE 8
#define KEY_DUMP 9
#define KEY_FLUSH 10
/* $Id: key.h,v 1.1.6.1.6.1 1999/05/17 17:03:14 itojun Exp $ */
#define KEY_VERSION 1
#define POLICY_VERSION 1
#ifndef _NETKEY_KEY_H_
#define _NETKEY_KEY_H_
#define SECURITY_TYPE_NONE 0
#if defined(KERNEL)
#define KEY_TYPE_AH 1
#define KEY_TYPE_ESP 2
#define KEY_TYPE_RSVP 3
#define KEY_TYPE_OSPF 4
#define KEY_TYPE_RIPV2 5
#define KEY_TYPE_MIPV4 6
#define KEY_TYPE_MIPV6 7
#define KEY_TYPE_MAX 7
extern struct key_cb key_cb;
/*
* Security association state
*/
struct secpolicy;
struct secpolicyindex;
struct ipsecrequest;
struct secasvar;
struct sockaddr;
struct socket;
struct sadb_msg;
struct sadb_x_policy;
#define K_USED 0x1 /* Key used/not used */
#define K_UNIQUE 0x2 /* Key unique/reusable */
#define K_LARVAL 0x4 /* SPI assigned, but sa incomplete */
#define K_ZOMBIE 0x8 /* sa expired but still useable */
#define K_DEAD 0x10 /* sa marked for deletion, ready for reaping */
#define K_INBOUND 0x20 /* sa for inbound packets, ie. dst=myhost */
#define K_OUTBOUND 0x40 /* sa for outbound packets, ie. src=myhost */
extern struct secpolicy *key_allocsp __P((struct secpolicyindex *spidx,
u_int dir));
extern int key_checkrequest __P((struct ipsecrequest *isr));
extern struct secasvar *key_allocsa __P((u_int family, caddr_t src, caddr_t dst,
u_int proto, u_int32_t spi));
extern void key_freesp __P((struct secpolicy *sp));
extern void key_freeso __P((struct socket *so));
extern void key_freesav __P((struct secasvar *sav));
extern struct secpolicy *key_newsp __P((void));
extern struct secpolicy *key_msg2sp __P((struct sadb_x_policy *xpl0));
extern struct sadb_x_policy *key_sp2msg __P((struct secpolicy *sp));
extern int key_ismyaddr __P((u_int family, caddr_t addr));
extern void key_timehandler __P((void));
extern void key_srandom __P((void));
extern void key_freereg __P((struct socket *so));
extern int key_parse __P((struct sadb_msg **msgp, struct socket *so,
int *targetp));
extern void key_init __P((void));
extern int key_checktunnelsanity __P((struct secasvar *sav, u_int family,
caddr_t src, caddr_t dst));
extern void key_sa_recordxfer __P((struct secasvar *sav, struct mbuf *m));
extern void key_sa_routechange __P((struct sockaddr *dst));
#ifdef MALLOC_DECLARE
MALLOC_DECLARE(M_SECA);
#endif /* MALLOC_DECLARE */
#ifndef MAX_SOCKADDR_SZ
#ifdef INET6
#define MAX_SOCKADDR_SZ (sizeof(struct sockaddr_in6))
#else /* INET6 */
#define MAX_SOCKADDR_SZ (sizeof(struct sockaddr_in))
#endif /* INET6 */
#endif /* MAX_SOCKADDR_SZ */
#ifndef MAX_KEY_SZ
#define MAX_KEY_SZ 16
#endif /* MAX_KEY_SZ */
#ifndef MAX_IV_SZ
#define MAX_IV_SZ 16
#endif /* MAX_IV_SZ */
/* Security association data for IP Security */
struct key_secassoc {
u_int8_t len; /* Length of the data (for radix) */
u_int8_t type; /* Type of association */
u_int8_t vers; /* Version of association (AH/ESP) */
u_int8_t state; /* State of the association */
u_int8_t label; /* Sensitivity label (unused) */
u_int32_t spi; /* SPI */
u_int8_t keylen; /* Key length */
u_int8_t ekeylen; /* Extra key length */
u_int8_t ivlen; /* Initialization vector length */
u_int8_t algorithm; /* Algorithm switch index */
u_int8_t lifetype; /* Type of lifetime */
caddr_t iv; /* Initialization vector */
caddr_t key; /* Key */
caddr_t ekey; /* Extra key */
u_int32_t lifetime1; /* Lifetime value 1 */
u_int32_t lifetime2; /* Lifetime value 2 */
struct sockaddr *src; /* Source host address */
struct sockaddr *dst; /* Destination host address */
struct sockaddr *from; /* Originator of association */
int antireplay; /*anti replay flag*/
u_int32_t sequence; /*send: sequence number*/
u_int32_t replayright; /*receive: replay window, right*/
u_int64_t replaywindow; /*receive: replay window*/
};
/*
* Structure for key message header. PF_KEY message consists of key_msghdr
* followed by src struct sockaddr, dest struct sockaddr, from struct
* sockaddr, key, and iv. Assumes size of key message header less than MHLEN.
*/
struct key_msghdr {
u_short key_msglen; /* length of message including
* src/dst/from/key/iv */
u_char key_msgvers; /* key version number */
u_char key_msgtype; /* key message type, eg. KEY_ADD */
pid_t key_pid; /* process id of message sender */
int key_seq; /* message sequence number */
int key_errno; /* error code */
u_int8_t type; /* type of security association */
u_int8_t vers; /* version of sassoc (AH/ESP) */
u_int8_t state; /* state of security association */
u_int8_t label; /* sensitivity level */
u_int8_t pad; /* padding for allignment */
u_int32_t spi; /* spi value */
u_int8_t keylen; /* key length */
u_int8_t ekeylen; /* extra key length */
u_int8_t ivlen; /* iv length */
u_int8_t algorithm; /* algorithm identifier */
u_int8_t lifetype; /* type of lifetime */
u_int32_t lifetime1; /* lifetime value 1 */
u_int32_t lifetime2; /* lifetime value 2 */
int antireplay; /* anti replay flag */
};
struct key_msgdata {
struct sockaddr *src; /* source host address */
struct sockaddr *dst; /* destination host address */
struct sockaddr *from; /* originator of security association */
caddr_t iv; /* initialization vector */
caddr_t key; /* key */
caddr_t ekey; /* extra key */
int ivlen; /* key length */
int keylen; /* iv length */
int ekeylen; /* extra key length */
};
struct policy_msghdr {
u_short policy_msglen; /* message length */
u_char policy_msgvers; /* message version */
u_char policy_msgtype; /* message type */
int policy_seq; /* message sequence number */
int policy_errno; /* error code */
};
/*
* Key engine table structures
*/
struct socketlist {
struct socket *socket; /* pointer to socket */
struct socketlist *next; /* next */
};
struct key_tblnode {
int alloc_count; /* number of sockets allocated to
* secassoc */
int ref_count; /* number of sockets referencing
* secassoc */
struct socketlist *solist; /* list of sockets allocated to
* secassoc */
struct key_secassoc *secassoc; /* security association */
struct key_tblnode *next; /* next node */
};
struct key_allocnode {
struct key_tblnode *keynode;
struct key_allocnode *next;
};
struct key_so2spinode {
struct socket *socket; /* socket pointer */
struct key_tblnode *keynode; /* pointer to tblnode containing
* secassoc */
/* info for socket */
struct key_so2spinode *next;
};
struct key_registry {
u_int8_t type; /* secassoc type that key mgnt. daemon can
* acquire */
struct socket *socket; /* key management daemon socket pointer */
struct key_registry *next;
};
struct key_acquirelist {
u_int8_t type; /* secassoc type to acquire */
struct sockaddr *target; /* destination address of secassoc */
u_int32_t count; /* number of acquire messages sent */
u_long expiretime; /* expiration time for acquire message */
struct key_acquirelist *next;
};
struct keyso_cb {
int ip4_count;
#ifdef INET6
int ip6_count;
#endif /*INET6*/
int any_count; /* Sum of above counters */
};
#ifdef KERNEL
extern int key_secassoc2msghdr __P((struct key_secassoc *, struct key_msghdr *,
struct key_msgdata *));
extern int key_msghdr2secassoc __P((struct key_secassoc *, struct key_msghdr *,
struct key_msgdata *));
extern int key_inittables __P((void));
extern void key_sodelete __P((struct socket *, int));
extern int key_add __P((struct key_secassoc *));
extern int key_delete __P((struct key_secassoc *));
extern int key_get __P((u_int, struct sockaddr *, struct sockaddr *,
u_int32_t, struct key_secassoc **));
extern void key_flush __P((void));
extern int key_dump __P((struct socket *));
extern int key_getspi __P((u_int, u_int, struct sockaddr *, struct sockaddr *,
u_int32_t, u_int32_t, u_int32_t *));
extern int key_update __P((struct key_secassoc *));
extern int key_register __P((struct socket *, u_int));
extern void key_unregister __P((struct socket *, u_int, int));
extern int key_acquire __P((u_int, struct sockaddr *, struct sockaddr *));
extern int getassocbyspi __P((u_int, struct sockaddr *, struct sockaddr *,
u_int32_t, struct key_tblnode **));
extern int getassocbysocket __P((u_int, struct sockaddr *, struct sockaddr *,
struct socket *, u_int, struct key_tblnode **));
extern void key_free __P((struct key_tblnode *));
extern int key_parse __P((struct key_msghdr ** km, struct socket * so,
int *));
#endif /* KERNEL */
#endif /* _netkey_key_h */
#endif /* defined(KERNEL) */
#endif /* _NETKEY_KEY_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,187 +1,89 @@
/*
* modified by Jun-ichiro itojun Itoh <itojun@itojun.org>, 1997
*/
/*
* in6_debug.h -- Insipired by Craig Metz's Net/2 in6_debug.h, but
* not quite as heavyweight (initially, anyway).
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* In particular, if function exit-entries are to be
* documented, do them in a lightweight fashion.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* Copyright 1995 by Dan McDonald, Bao Phan, and Randall Atkinson,
* All Rights Reserved.
* All Rights under this copyright have been assigned to NRL.
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*----------------------------------------------------------------------
# @(#)COPYRIGHT 1.1a (NRL) 17 August 1995
/* $Id: key_debug.h,v 1.1.6.2.6.1 1999/05/17 17:03:16 itojun Exp $ */
COPYRIGHT NOTICE
#ifndef _NETKEY_KEY_DEBUG_H_
#define _NETKEY_KEY_DEBUG_H_
All of the documentation and software included in this software
distribution from the US Naval Research Laboratory (NRL) are
copyrighted by their respective developers.
/* debug flags */
#define KEYDEBUG_STAMP 0x00000001 /* path */
#define KEYDEBUG_DATA 0x00000002 /* data */
#define KEYDEBUG_DUMP 0x00000004 /* dump */
This software and documentation were developed at NRL by various
people. Those developers have each copyrighted the portions that they
developed at NRL and have assigned All Rights for those portions to
NRL. Outside the USA, NRL also has copyright on the software
developed at NRL. The affected files all contain specific copyright
notices and those notices must be retained in any derived work.
#define KEYDEBUG_KEY 0x00000010 /* key processing */
#define KEYDEBUG_ALG 0x00000020 /* ciph & auth algorithm */
#define KEYDEBUG_IPSEC 0x00000040 /* ipsec processing */
NRL LICENSE
#define KEYDEBUG_KEY_STAMP (KEYDEBUG_KEY | KEYDEBUG_STAMP)
#define KEYDEBUG_KEY_DATA (KEYDEBUG_KEY | KEYDEBUG_DATA)
#define KEYDEBUG_KEY_DUMP (KEYDEBUG_KEY | KEYDEBUG_DUMP)
#define KEYDEBUG_ALG_STAMP (KEYDEBUG_ALG | KEYDEBUG_STAMP)
#define KEYDEBUG_ALG_DATA (KEYDEBUG_ALG | KEYDEBUG_DATA)
#define KEYDEBUG_ALG_DUMP (KEYDEBUG_ALG | KEYDEBUG_DUMP)
#define KEYDEBUG_IPSEC_STAMP (KEYDEBUG_IPSEC | KEYDEBUG_STAMP)
#define KEYDEBUG_IPSEC_DATA (KEYDEBUG_IPSEC | KEYDEBUG_DATA)
#define KEYDEBUG_IPSEC_DUMP (KEYDEBUG_IPSEC | KEYDEBUG_DUMP)
NRL grants permission for redistribution and use in source and binary
forms, with or without modification, of the software and documentation
created at NRL provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed at the Information
Technology Division, US Naval Research Laboratory.
4. Neither the name of the NRL nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation
are those of the authors and should not be interpreted as representing
official policies, either expressed or implied, of the US Naval
Research Laboratory (NRL).
----------------------------------------------------------------------*/
#define KEYDEBUG(lev,arg) if ((key_debug_level & (lev)) == (lev)) { arg; }
#ifdef KERNEL
/* IDL_* is IPv6 Debug Level */
#define IDL_ALL 0xFFFFFFFE /* Report all messages. */
#define IDL_NONE 0 /* Report no messages. */
#define IDL_CRITICAL 3
#define IDL_ERROR 7
#define IDL_MAJOR_EVENT 10
#define IDL_EVENT 15
#define IDL_GROSS_EVENT 20
#define IDL_FINISHED 0xFFFFFFF0
/*
* Make sure argument for DPRINTF is in parentheses.
*
* For both DPRINTF and DDO, and attempt was made to make both macros
* be usable as normal C statments. There is a small amount of compiler
* trickery (if-else clauses with effectively null statements), which may
* cause a few compilers to complain.
*/
#ifdef KEY_DEBUG
/*
* DPRINTF() is a general printf statement. The "arg" is literally what
* would follow the function name printf, which means it has to be in
* parenthesis. Unlimited arguments can be used this way.
*
* EXAMPLE:
* DPRINTF(IDL_MAJOR_EVENT,("Hello, world. IP version %d.\n",vers));
*/
#define DPRINTF(lev,arg) \
if ((lev) < in6_debug_level) { \
printf arg; \
} else \
in6_debug_level = in6_debug_level
/*
* DDO() executes a series of statements at a certain debug level. The
* "stmt" argument is a statement in the sense of a "statement list" in a
* C grammar. "stmt" does not have to end with a semicolon.
*
* EXAMPLE:
* DDO(IDL_CRITICAL,dump_ipv6(header), dump_inpcb(inp));
*/
#define DDO(lev,stmt) \
if ((lev) < in6_debug_level) { \
stmt ; \
} else \
in6_debug_level = in6_debug_level
/*
* DP() is a shortcut for DPRINTF(). Basically:
*
* DP(lev, var, fmt) == DPRINTF(IDL_lev, ("var = %fmt\n", var))
*
* It is handy for printing single variables without a lot of typing.
*
* EXAMPLE:
*
* DP(CRITICAL,length,d);
* same as DPRINTF(IDL_CRITICAL, ("length = %d\n", length))
*/
#define DP(lev, var, fmt) DPRINTF(IDL_ ## lev, (#var " = %" #fmt "\n", var))
struct inpcb;
extern void in6_debug_init __P((void));
#ifdef INET6
extern void dump_in6_addr __P((struct in6_addr *));
#endif
extern void dump_in_addr __P((struct in_addr *));
#ifdef INET6
extern void dump_sockaddr_in6 __P((struct sockaddr_in6 *));
#endif
extern void dump_sockaddr_in __P((struct sockaddr_in *));
extern void dump_sockaddr __P((struct sockaddr *));
extern void dump_sockaddr_dl __P((struct sockaddr_dl *));
extern void dump_smart_sockaddr __P((struct sockaddr *));
#ifdef INET6
extern void dump_ipv6 __P((struct ip6 *));
extern void dump_ipv6_icmp __P((struct icmp6 *));
#endif /*INET6*/
extern void dump_mbuf_hdr __P((struct mbuf *));
extern void dump_mbuf __P((struct mbuf *));
extern void dump_mchain __P((struct mbuf *));
extern void dump_tcpdump __P((struct mbuf *));
extern void dump_ifa __P((struct ifaddr *));
extern void dump_ifp __P((struct ifnet *));
extern void dump_route __P((struct route *));
extern void dump_rtentry __P((struct rtentry *));
extern void dump_inpcb __P((struct inpcb *));
#ifdef INET6
extern void dump_in6pcb __P((struct in6pcb *));
#endif
extern void dump_buf __P((char *, int));
extern void dump_keytblnode __P((struct key_tblnode *));
extern void dump_secassoc __P((struct key_secassoc *));
extern void dump_keymsghdr __P((struct key_msghdr *));
extern void dump_keymsginfo __P((struct key_msgdata *));
#else /* ! KEY_DEBUG */
#define DPRINTF(lev,arg)
#define DDO(lev, stmt)
#define DP(x, y, z)
#endif /* KEY_DEBUG */
#ifndef INET6_DEBUG_C
extern unsigned int in6_debug_level;
#endif
extern u_int32_t key_debug_level;
#endif /*KERNEL*/
struct sadb_msg;
struct sadb_ext;
extern void kdebug_sadb __P((struct sadb_msg *));
extern void kdebug_sadb_x_policy __P((struct sadb_ext *));
#ifdef KERNEL
struct secpolicy;
struct secpolicyindex;
struct secasindex;
struct secasvar;
struct secreplay;
struct mbuf;
extern void kdebug_secpolicy __P((struct secpolicy *));
extern void kdebug_secpolicyindex __P((struct secpolicyindex *));
extern void kdebug_secasindex __P((struct secasindex *));
extern void kdebug_secasv __P((struct secasvar *));
extern void kdebug_mbufhdr __P((struct mbuf *));
extern void kdebug_mbuf __P((struct mbuf *));
#endif /*KERNEL*/
struct sockaddr;
extern void kdebug_sockaddr __P((struct sockaddr *));
extern void ipsec_hexdump __P((caddr_t, int));
extern void ipsec_bindump __P((caddr_t, int));
#endif /* _NETKEY_KEY_DEBUG_H_ */

View File

@ -43,40 +43,12 @@
#define KEYCTL_BLOCKACQ_LIFETIME 8
#define KEYCTL_MAXID 9
#define KEYCTL_NAMES { \
{ 0, 0 }, \
{ "debug", CTLTYPE_INT }, \
{ "spi_try", CTLTYPE_INT }, \
{ "spi_min_value", CTLTYPE_INT }, \
{ "spi_max_value", CTLTYPE_INT }, \
{ "random_int", CTLTYPE_INT }, \
{ "larval_lifetime", CTLTYPE_INT }, \
{ "blockacq_count", CTLTYPE_INT }, \
{ "blockacq_lifetime", CTLTYPE_INT }, \
}
#define KEYCTL_VARS { \
0, \
&key_debug_level, \
&key_spi_trycnt, \
&key_spi_minval, \
&key_spi_maxval, \
&key_int_random, \
&key_larval_lifetime, \
&key_blockacq_count, \
&key_blockacq_lifetime, \
}
#define _ARRAYLEN(p) (sizeof(p)/sizeof(p[0]))
#define _KEYLEN(key) ((u_int)((key)->sadb_key_bits >> 3))
#define _KEYBITS(key) ((u_int)((key)->sadb_key_bits))
#define _KEYBUF(key) ((caddr_t)((caddr_t)(key) + sizeof(struct sadb_key)))
#define _INADDR(in) ((struct sockaddr_in *)(in))
/* should not ifdef kernel opt in kernel header file */
#if !defined(KERNEL) && !defined(_KERNEL)
#if defined(INET6)
#define _IN6ADDR(in6) ((struct sockaddr_in6 *)(in6))
#define _SALENBYAF(family) \
(((family) == AF_INET) ? \
@ -94,13 +66,9 @@
((((struct sockaddr *)(saddr))->sa_family == AF_INET) ? \
((struct sockaddr_in *)(saddr))->sin_port : \
((struct sockaddr_in6 *)(saddr))->sin6_port)
#else
#define _IN6ADDR(in6) "#error"
#define _SALENBYAF(family) sizeof(struct sockaddr_in)
#define _INALENBYAF(family) sizeof(struct in_addr)
#define _INADDRBYSA(saddr) ((caddr_t)&((struct sockaddr_in *)(saddr))->sin_addr)
#define _INPORTBYSA(saddr) (((struct sockaddr_in *)(saddr))->sin_port)
#endif /* defined(INET6) */
#endif /* !defined(KERNEL) && !defined(_KERNEL) */
#ifdef SYSCTL_DECL
SYSCTL_DECL(_net_key);
#endif
#endif /* _NETKEY_KEY_VAR_H_ */

542
sys/netkey/keysock.c Normal file
View File

@ -0,0 +1,542 @@
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/* KAME @(#)$Id: keysock.c,v 1.2 1999/08/16 19:30:36 shin Exp $ */
/* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
#include <opt_ipsec.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <machine/ipl.h>
#include <net/raw_cb.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key.h>
#include <netkey/keysock.h>
#ifdef IPSEC_DEBUG
#include <netkey/key_debug.h>
#else
#define KEYDEBUG(lev,arg)
#endif
#include <machine/stdarg.h>
static MALLOC_DEFINE(M_SECA, "key mgmt",
"security associations, key management");
struct sockaddr key_dst = { 2, PF_KEY, };
struct sockaddr key_src = { 2, PF_KEY, };
struct sockproto key_proto = { PF_KEY, PF_KEY_V2 };
static int key_sendup0 __P((struct rawcb *, struct mbuf *, int));
#define KMALLOC(p, t, n) \
((p) = (t) malloc((unsigned long)(n), M_SECA, M_NOWAIT))
#define KFREE(p) \
free((caddr_t)(p), M_SECA);
/*
* key_abort()
* derived from net/rtsock.c:rts_abort()
*/
static int
key_abort(struct socket *so)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_abort(so);
splx(s);
return error;
}
/*
* key_attach()
* derived from net/rtsock.c:rts_attach()
*/
static int
key_attach(struct socket *so, int proto, struct proc *p)
{
struct keycb *kp;
int s, error;
if (sotorawcb(so) != 0)
return EISCONN; /* XXX panic? */
MALLOC(kp, struct keycb *, sizeof *kp, M_PCB, M_WAITOK); /* XXX */
if (kp == 0)
return ENOBUFS;
bzero(kp, sizeof *kp);
/*
* The splnet() is necessary to block protocols from sending
* error notifications (like RTM_REDIRECT or RTM_LOSING) while
* this PCB is extant but incompletely initialized.
* Probably we should try to do more of this work beforehand and
* eliminate the spl.
*/
s = splnet();
so->so_pcb = (caddr_t)kp;
error = raw_usrreqs.pru_attach(so, proto, p);
kp = (struct keycb *)sotorawcb(so);
if (error) {
free(kp, M_PCB);
so->so_pcb = (caddr_t) 0;
splx(s);
printf("key_usrreq: key_usrreq results %d\n", error);
return error;
}
kp->kp_promisc = kp->kp_registered = 0;
if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
key_cb.key_count++;
key_cb.any_count++;
kp->kp_raw.rcb_laddr = &key_src;
kp->kp_raw.rcb_faddr = &key_dst;
soisconnected(so);
so->so_options |= SO_USELOOPBACK;
splx(s);
return 0;
}
/*
* key_bind()
* derived from net/rtsock.c:rts_bind()
*/
static int
key_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_bind(so, nam, p); /* xxx just EINVAL */
splx(s);
return error;
}
/*
* key_connect()
* derived from net/rtsock.c:rts_connect()
*/
static int
key_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_connect(so, nam, p); /* XXX just EINVAL */
splx(s);
return error;
}
/*
* key_detach()
* derived from net/rtsock.c:rts_detach()
*/
static int
key_detach(struct socket *so)
{
struct keycb *kp = (struct keycb *)sotorawcb(so);
int s, error;
s = splnet();
if (kp != 0) {
if (kp->kp_raw.rcb_proto.sp_protocol
== PF_KEY) /* XXX: AF_KEY */
key_cb.key_count--;
key_cb.any_count--;
key_freereg(so);
}
error = raw_usrreqs.pru_detach(so);
splx(s);
return error;
}
/*
* key_disconnect()
* derived from net/rtsock.c:key_disconnect()
*/
static int
key_disconnect(struct socket *so)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_disconnect(so);
splx(s);
return error;
}
/*
* key_peeraddr()
* derived from net/rtsock.c:rts_peeraddr()
*/
static int
key_peeraddr(struct socket *so, struct sockaddr **nam)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_peeraddr(so, nam);
splx(s);
return error;
}
/*
* key_send()
* derived from net/rtsock.c:rts_send()
*/
static int
key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
struct mbuf *control, struct proc *p)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_send(so, flags, m, nam, control, p);
splx(s);
return error;
}
/*
* key_shutdown()
* derived from net/rtsock.c:rts_shutdown()
*/
static int
key_shutdown(struct socket *so)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_shutdown(so);
splx(s);
return error;
}
/*
* key_sockaddr()
* derived from net/rtsock.c:rts_sockaddr()
*/
static int
key_sockaddr(struct socket *so, struct sockaddr **nam)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_sockaddr(so, nam);
splx(s);
return error;
}
struct pr_usrreqs key_usrreqs = {
key_abort, pru_accept_notsupp, key_attach, key_bind,
key_connect,
pru_connect2_notsupp, pru_control_notsupp, key_detach,
key_disconnect, pru_listen_notsupp, key_peeraddr,
pru_rcvd_notsupp,
pru_rcvoob_notsupp, key_send, pru_sense_null, key_shutdown,
key_sockaddr, sosend, soreceive, sopoll
};
/*
* key_output()
*/
int
key_output(struct mbuf *m, struct socket *so)
{
struct sadb_msg *msg = NULL;
int len, error = 0;
int s;
int target;
if (m == 0)
panic("key_output: NULL pointer was passed.\n");
if (m->m_len < sizeof(long)
&& (m = m_pullup(m, 8)) == 0) {
printf("key_output: can't pullup mbuf\n");
error = ENOBUFS;
goto end;
}
if ((m->m_flags & M_PKTHDR) == 0)
panic("key_output: not M_PKTHDR ??");
#if defined(IPSEC_DEBUG)
KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m));
#endif /* defined(IPSEC_DEBUG) */
len = m->m_pkthdr.len;
if (len < sizeof(struct sadb_msg)
|| len != PFKEY_UNUNIT64(mtod(m, struct sadb_msg *)->sadb_msg_len)) {
printf("key_output: Invalid message length.\n");
error = EINVAL;
goto end;
}
/*
* allocate memory for sadb_msg, and copy to sadb_msg from mbuf
* XXX: To be processed directly without a copy.
*/
KMALLOC(msg, struct sadb_msg *, len);
if (msg == 0) {
printf("key_output: No more memory.\n");
error = ENOBUFS;
goto end;
/* or do panic ? */
}
m_copydata(m, 0, len, (caddr_t)msg);
/*XXX giant lock*/
s = splnet();
if ((len = key_parse(&msg, so, &target)) == 0) {
/* discard. i.e. no need to reply. */
error = 0;
splx(s);
goto end;
}
/* send up message to the socket */
error = key_sendup(so, msg, len, target);
splx(s);
KFREE(msg);
end:
m_freem(m);
return (error);
}
/*
* send message to the socket.
*/
static int
key_sendup0(rp, m, promisc)
struct rawcb *rp;
struct mbuf *m;
int promisc;
{
if (promisc) {
struct sadb_msg *pmsg;
M_PREPEND(m, sizeof(struct sadb_msg), M_NOWAIT);
if (m && m->m_len < sizeof(struct sadb_msg))
m = m_pullup(m, sizeof(struct sadb_msg));
if (!m) {
printf("key_sendup0: cannot pullup\n");
m_freem(m);
return ENOBUFS;
}
m->m_pkthdr.len += sizeof(*pmsg);
pmsg = mtod(m, struct sadb_msg *);
bzero(pmsg, sizeof(*pmsg));
pmsg->sadb_msg_version = PF_KEY_V2;
pmsg->sadb_msg_type = SADB_X_PROMISC;
pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
/* pid and seq? */
}
if (!sbappendaddr(&rp->rcb_socket->so_rcv,
(struct sockaddr *)&key_src, m, NULL)) {
printf("key_sendup0: sbappendaddr failed\n");
m_freem(m);
return ENOBUFS;
}
sorwakeup(rp->rcb_socket);
return 0;
}
int
key_sendup(so, msg, len, target)
struct socket *so;
struct sadb_msg *msg;
u_int len;
int target; /*target of the resulting message*/
{
struct mbuf *m, *n, *mprev;
struct keycb *kp;
int sendup;
struct rawcb *rp;
int error;
int tlen;
/* sanity check */
if (so == 0 || msg == 0)
panic("key_sendup: NULL pointer was passed.\n");
KEYDEBUG(KEYDEBUG_KEY_DUMP,
printf("key_sendup: \n");
kdebug_sadb(msg));
/*
* Get mbuf chain whenever possible (not clusters),
* to save socket buffer. We'll be generating many SADB_ACQUIRE
* messages to listening key sockets. If we simmply allocate clusters,
* sbappendaddr() will raise ENOBUFS due to too little sbspace().
* sbspace() computes # of actual data bytes AND mbuf region.
*
* TODO: SADB_ACQUIRE filters should be implemented.
*/
tlen = len;
m = mprev = NULL;
while (tlen > 0) {
if (tlen == len) {
MGETHDR(n, M_DONTWAIT, MT_DATA);
n->m_len = MHLEN;
} else {
MGET(n, M_DONTWAIT, MT_DATA);
n->m_len = MLEN;
}
if (!n)
return ENOBUFS;
if (tlen > MCLBYTES) { /*XXX better threshold? */
MCLGET(n, M_DONTWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_free(n);
m_freem(m);
return ENOBUFS;
}
n->m_len = MCLBYTES;
}
if (tlen < n->m_len)
n->m_len = tlen;
n->m_next = NULL;
if (m == NULL)
m = mprev = n;
else {
mprev->m_next = n;
mprev = n;
}
tlen -= n->m_len;
n = NULL;
}
m->m_pkthdr.len = len;
m->m_pkthdr.rcvif = NULL;
m_copyback(m, 0, len, (caddr_t)msg);
LIST_FOREACH(rp, &rawcb_list, list)
{
if (rp->rcb_proto.sp_family != PF_KEY)
continue;
if (rp->rcb_proto.sp_protocol
&& rp->rcb_proto.sp_protocol != PF_KEY_V2) {
continue;
}
kp = (struct keycb *)rp;
/*
* If you are in promiscuous mode, and when you get broadcasted
* reply, you'll get two PF_KEY messages.
* (based on pf_key@inner.net message on 14 Oct 1998)
*/
if (((struct keycb *)rp)->kp_promisc) {
if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
(void)key_sendup0(rp, n, 1);
n = NULL;
}
}
/* the exact target will be processed later */
if (sotorawcb(so) == rp)
continue;
sendup = 0;
switch (target) {
case KEY_SENDUP_ONE:
/* the statement has no effect */
if (sotorawcb(so) == rp)
sendup++;
break;
case KEY_SENDUP_ALL:
sendup++;
break;
case KEY_SENDUP_REGISTERED:
if (kp->kp_registered)
sendup++;
break;
}
if (!sendup)
continue;
if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
printf("key_sendup: m_copy fail\n");
m_freem(m);
return ENOBUFS;
}
if ((error = key_sendup0(rp, n, 0)) != 0) {
m_freem(m);
return error;
}
n = NULL;
}
error = key_sendup0(sotorawcb(so), m, 0);
m = NULL;
return error;
}
/* sysctl */
SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family");
/*
* Definitions of protocols supported in the KEY domain.
*/
extern struct domain keydomain;
struct protosw keysw[] = {
{ SOCK_RAW, &keydomain, PF_KEY_V2, PR_ATOMIC|PR_ADDR,
0, key_output, raw_ctlinput, 0,
0,
raw_init, 0, 0, 0,
&key_usrreqs
}
};
struct domain keydomain =
{ PF_KEY, "key", key_init, 0, 0,
keysw, &keysw[sizeof(keysw)/sizeof(keysw[0])] };
DOMAIN_SET(key);

View File

@ -41,7 +41,7 @@ struct keycb {
int kp_registered; /* registered socket */
};
extern int key_output __P((struct mbuf *, ...));
extern int key_output __P((struct mbuf *, struct socket *));
extern int key_usrreq __P((struct socket *, int, struct mbuf *,
struct mbuf *, struct mbuf *));

View File

@ -363,7 +363,7 @@ struct cmsgcred {
/* given pointer to struct cmsghdr, return pointer to next cmsghdr */
#define CMSG_NXTHDR(mhdr, cmsg) \
(((caddr_t)(cmsg) + (cmsg)->cmsg_len + sizeof(struct cmsghdr) > \
(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
(caddr_t)(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
(struct cmsghdr *)NULL : \
(struct cmsghdr *)((caddr_t)(cmsg) + CMSG_ALIGN((cmsg)->cmsg_len)))

Some files were not shown because too many files have changed in this diff Show More