diff options
author | shin <shin@FreeBSD.org> | 1999-12-22 19:13:38 +0000 |
---|---|---|
committer | shin <shin@FreeBSD.org> | 1999-12-22 19:13:38 +0000 |
commit | 50ba589c666f7d356304339b9cfc7fc9d173ad8d (patch) | |
tree | 46d6ae7c9680a93ce1c3a13378cef283df9f6544 /sys/crypto/rc5 | |
parent | e396740391e7e60805bda6799ac3397d1fc8c539 (diff) | |
download | FreeBSD-src-50ba589c666f7d356304339b9cfc7fc9d173ad8d.zip FreeBSD-src-50ba589c666f7d356304339b9cfc7fc9d173ad8d.tar.gz |
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
Diffstat (limited to 'sys/crypto/rc5')
-rw-r--r-- | sys/crypto/rc5/rc5.c | 218 | ||||
-rw-r--r-- | sys/crypto/rc5/rc5.h | 86 | ||||
-rw-r--r-- | sys/crypto/rc5/rc5_cbc.c | 211 |
3 files changed, 515 insertions, 0 deletions
diff --git a/sys/crypto/rc5/rc5.c b/sys/crypto/rc5/rc5.c new file mode 100644 index 0000000..52ccdd1 --- /dev/null +++ b/sys/crypto/rc5/rc5.c @@ -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; +} + diff --git a/sys/crypto/rc5/rc5.h b/sys/crypto/rc5/rc5.h new file mode 100644 index 0000000..20c235b --- /dev/null +++ b/sys/crypto/rc5/rc5.h @@ -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 diff --git a/sys/crypto/rc5/rc5_cbc.c b/sys/crypto/rc5/rc5_cbc.c new file mode 100644 index 0000000..c588eda --- /dev/null +++ b/sys/crypto/rc5/rc5_cbc.c @@ -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; + } +} + |