diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1998-07-21 22:23:21 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1998-07-21 22:23:21 +0000 |
commit | 76077be4bf3b32f321f86f8155efaec34aee1cb1 (patch) | |
tree | 9aef4dd593c5037b59f88e74ad77d5bbbc991271 /lib/libc | |
parent | cd9dff9842030a7dcf68d2d82df316ac047209b4 (diff) |
Add CAST encryption, implementation by Steve Reid <sreid@sea-to-sky.net>.
Man pages will come soon, I hope.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/crypt/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/crypt/cast.c | 240 |
2 files changed, 242 insertions, 2 deletions
diff --git a/lib/libc/crypt/Makefile.inc b/lib/libc/crypt/Makefile.inc index 7866f46a8e9..9d96d657dbe 100644 --- a/lib/libc/crypt/Makefile.inc +++ b/lib/libc/crypt/Makefile.inc @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile.inc,v 1.9 1997/04/16 12:11:27 deraadt Exp $ +# $OpenBSD: Makefile.inc,v 1.10 1998/07/21 22:23:20 provos Exp $ .PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/crypt ${.CURDIR}/crypt -SRCS+= crypt.c morecrypt.c md5crypt.c arc4random.c blowfish.c +SRCS+= cast.c crypt.c morecrypt.c md5crypt.c arc4random.c blowfish.c SRCS+= bcrypt.c MAN+= crypt.3 blowfish.3 arc4random.3 diff --git a/lib/libc/crypt/cast.c b/lib/libc/crypt/cast.c new file mode 100644 index 00000000000..69dad6b6d23 --- /dev/null +++ b/lib/libc/crypt/cast.c @@ -0,0 +1,240 @@ +/* $OpenBSD: cast.c,v 1.1 1998/07/21 22:23:19 provos Exp $ */ +/* + * CAST-128 in C + * Written by Steve Reid <sreid@sea-to-sky.net> + * 100% Public Domain - no warranty + * Released 1997.10.11 + */ + +#include <netinet/ip_cast.h> +#include <netinet/ip_castsb.h> + +/* Macros to access 8-bit bytes out of a 32-bit word */ +#define U8a(x) ( (u8) (x>>24) ) +#define U8b(x) ( (u8) ((x>>16)&255) ) +#define U8c(x) ( (u8) ((x>>8)&255) ) +#define U8d(x) ( (u8) ((x)&255) ) + +/* Circular left shift */ +#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) ) + +/* CAST-128 uses three different round functions */ +#define F1(l, r, i) \ + t = ROL(key->xkey[i] + r, key->xkey[i+16]); \ + l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) - \ + cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)]; +#define F2(l, r, i) \ + t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \ + l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) + \ + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)]; +#define F3(l, r, i) \ + t = ROL(key->xkey[i] - r, key->xkey[i+16]); \ + l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) ^ \ + cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)]; + + +/***** Encryption Function *****/ + +void cast_encrypt(cast_key* key, u8* inblock, u8* outblock) +{ +u32 t, l, r; + + /* Get inblock into l,r */ + l = ((u32)inblock[0] << 24) | ((u32)inblock[1] << 16) | + ((u32)inblock[2] << 8) | (u32)inblock[3]; + r = ((u32)inblock[4] << 24) | ((u32)inblock[5] << 16) | + ((u32)inblock[6] << 8) | (u32)inblock[7]; + /* Do the work */ + F1(l, r, 0); + F2(r, l, 1); + F3(l, r, 2); + F1(r, l, 3); + F2(l, r, 4); + F3(r, l, 5); + F1(l, r, 6); + F2(r, l, 7); + F3(l, r, 8); + F1(r, l, 9); + F2(l, r, 10); + F3(r, l, 11); + /* Only do full 16 rounds if key length > 80 bits */ + if (key->rounds > 12) { + F1(l, r, 12); + F2(r, l, 13); + F3(l, r, 14); + F1(r, l, 15); + } + /* Put l,r into outblock */ + outblock[0] = U8a(r); + outblock[1] = U8b(r); + outblock[2] = U8c(r); + outblock[3] = U8d(r); + outblock[4] = U8a(l); + outblock[5] = U8b(l); + outblock[6] = U8c(l); + outblock[7] = U8d(l); + /* Wipe clean */ + t = l = r = 0; +} + + +/***** Decryption Function *****/ + +void cast_decrypt(cast_key* key, u8* inblock, u8* outblock) +{ +u32 t, l, r; + + /* Get inblock into l,r */ + r = ((u32)inblock[0] << 24) | ((u32)inblock[1] << 16) | + ((u32)inblock[2] << 8) | (u32)inblock[3]; + l = ((u32)inblock[4] << 24) | ((u32)inblock[5] << 16) | + ((u32)inblock[6] << 8) | (u32)inblock[7]; + /* Do the work */ + /* Only do full 16 rounds if key length > 80 bits */ + if (key->rounds > 12) { + F1(r, l, 15); + F3(l, r, 14); + F2(r, l, 13); + F1(l, r, 12); + } + F3(r, l, 11); + F2(l, r, 10); + F1(r, l, 9); + F3(l, r, 8); + F2(r, l, 7); + F1(l, r, 6); + F3(r, l, 5); + F2(l, r, 4); + F1(r, l, 3); + F3(l, r, 2); + F2(r, l, 1); + F1(l, r, 0); + /* Put l,r into outblock */ + outblock[0] = U8a(l); + outblock[1] = U8b(l); + outblock[2] = U8c(l); + outblock[3] = U8d(l); + outblock[4] = U8a(r); + outblock[5] = U8b(r); + outblock[6] = U8c(r); + outblock[7] = U8d(r); + /* Wipe clean */ + t = l = r = 0; +} + + +/***** Key Schedual *****/ + +void cast_setkey(cast_key* key, u8* rawkey, int keybytes) +{ +u32 t[4], z[4], x[4]; +int i; + + /* Set number of rounds to 12 or 16, depending on key length */ + key->rounds = (keybytes <= 10 ? 12 : 16); + + /* Copy key to workspace x */ + for (i = 0; i < 4; i++) { + x[i] = 0; + if ((i*4+0) < keybytes) x[i] = (u32)rawkey[i*4+0] << 24; + if ((i*4+1) < keybytes) x[i] |= (u32)rawkey[i*4+1] << 16; + if ((i*4+2) < keybytes) x[i] |= (u32)rawkey[i*4+2] << 8; + if ((i*4+3) < keybytes) x[i] |= (u32)rawkey[i*4+3]; + } + /* Generate 32 subkeys, four at a time */ + for (i = 0; i < 32; i+=4) { + switch (i & 4) { + case 0: + t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])] ^ + cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])] ^ + cast_sbox8[U8c(x[3])] ^ cast_sbox7[U8a(x[2])]; + t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])] ^ + cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])] ^ + cast_sbox8[U8d(z[0])] ^ cast_sbox8[U8c(x[2])]; + t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])] ^ + cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])] ^ + cast_sbox8[U8a(z[1])] ^ cast_sbox5[U8b(x[2])]; + t[3] = z[3] = x[1] ^ cast_sbox5[U8c(z[2])] ^ + cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])] ^ + cast_sbox8[U8a(z[2])] ^ cast_sbox6[U8d(x[2])]; + break; + case 4: + t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])] ^ + cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])] ^ + cast_sbox8[U8c(z[1])] ^ cast_sbox7[U8a(z[0])]; + t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])] ^ + cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])] ^ + cast_sbox8[U8d(x[0])] ^ cast_sbox8[U8c(z[0])]; + t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])] ^ + cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])] ^ + cast_sbox8[U8a(x[1])] ^ cast_sbox5[U8b(z[0])]; + t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])] ^ + cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])] ^ + cast_sbox8[U8a(x[2])] ^ cast_sbox6[U8d(z[0])]; + break; + } + switch (i & 12) { + case 0: + case 12: + key->xkey[i+0] = cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])] ^ + cast_sbox7[U8d(t[1])] ^ cast_sbox8[U8c(t[1])]; + key->xkey[i+1] = cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])] ^ + cast_sbox7[U8b(t[1])] ^ cast_sbox8[U8a(t[1])]; + key->xkey[i+2] = cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])] ^ + cast_sbox7[U8d(t[0])] ^ cast_sbox8[U8c(t[0])]; + key->xkey[i+3] = cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])] ^ + cast_sbox7[U8b(t[0])] ^ cast_sbox8[U8a(t[0])]; + break; + case 4: + case 8: + key->xkey[i+0] = cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])] ^ + cast_sbox7[U8a(t[3])] ^ cast_sbox8[U8b(t[3])]; + key->xkey[i+1] = cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])] ^ + cast_sbox7[U8c(t[3])] ^ cast_sbox8[U8d(t[3])]; + key->xkey[i+2] = cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])] ^ + cast_sbox7[U8a(t[2])] ^ cast_sbox8[U8b(t[2])]; + key->xkey[i+3] = cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])] ^ + cast_sbox7[U8c(t[2])] ^ cast_sbox8[U8d(t[2])]; + break; + } + switch (i & 12) { + case 0: + key->xkey[i+0] ^= cast_sbox5[U8c(z[0])]; + key->xkey[i+1] ^= cast_sbox6[U8c(z[1])]; + key->xkey[i+2] ^= cast_sbox7[U8b(z[2])]; + key->xkey[i+3] ^= cast_sbox8[U8a(z[3])]; + break; + case 4: + key->xkey[i+0] ^= cast_sbox5[U8a(x[2])]; + key->xkey[i+1] ^= cast_sbox6[U8b(x[3])]; + key->xkey[i+2] ^= cast_sbox7[U8d(x[0])]; + key->xkey[i+3] ^= cast_sbox8[U8d(x[1])]; + break; + case 8: + key->xkey[i+0] ^= cast_sbox5[U8b(z[2])]; + key->xkey[i+1] ^= cast_sbox6[U8a(z[3])]; + key->xkey[i+2] ^= cast_sbox7[U8c(z[0])]; + key->xkey[i+3] ^= cast_sbox8[U8c(z[1])]; + break; + case 12: + key->xkey[i+0] ^= cast_sbox5[U8d(x[0])]; + key->xkey[i+1] ^= cast_sbox6[U8d(x[1])]; + key->xkey[i+2] ^= cast_sbox7[U8a(x[2])]; + key->xkey[i+3] ^= cast_sbox8[U8b(x[3])]; + break; + } + if (i >= 16) { + key->xkey[i+0] &= 31; + key->xkey[i+1] &= 31; + key->xkey[i+2] &= 31; + key->xkey[i+3] &= 31; + } + } + /* Wipe clean */ + for (i = 0; i < 4; i++) { + t[i] = x[i] = z[i] = 0; + } +} + +/* Made in Canada */ + |