Home | History | Annotate | Line # | Download | only in cast128
cast128.c revision 1.9.108.1
      1  1.9.108.1      tls /*	$NetBSD: cast128.c,v 1.9.108.1 2014/08/20 00:03:34 tls Exp $	*/
      2        1.6  thorpej /*      $OpenBSD: cast.c,v 1.2 2000/06/06 06:49:47 deraadt Exp $       */
      3        1.1  thorpej 
      4        1.1  thorpej /*
      5        1.6  thorpej  *	CAST-128 in C
      6        1.6  thorpej  *	Written by Steve Reid <sreid (at) sea-to-sky.net>
      7        1.6  thorpej  *	100% Public Domain - no warranty
      8        1.6  thorpej  *	Released 1997.10.11
      9        1.1  thorpej  */
     10        1.4    lukem 
     11        1.4    lukem #include <sys/cdefs.h>
     12  1.9.108.1      tls __KERNEL_RCSID(0, "$NetBSD: cast128.c,v 1.9.108.1 2014/08/20 00:03:34 tls Exp $");
     13        1.1  thorpej 
     14        1.6  thorpej #include <sys/types.h>
     15  1.9.108.1      tls #include <sys/errno.h>
     16  1.9.108.1      tls #include <sys/module.h>
     17  1.9.108.1      tls 
     18        1.1  thorpej #include <crypto/cast128/cast128.h>
     19        1.6  thorpej #include <crypto/cast128/cast128sb.h>
     20        1.1  thorpej 
     21        1.6  thorpej /* Macros to access 8-bit bytes out of a 32-bit word */
     22        1.6  thorpej #define U_INT8_Ta(x) ( (u_int8_t) (x>>24) )
     23        1.6  thorpej #define U_INT8_Tb(x) ( (u_int8_t) ((x>>16)&255) )
     24        1.6  thorpej #define U_INT8_Tc(x) ( (u_int8_t) ((x>>8)&255) )
     25        1.6  thorpej #define U_INT8_Td(x) ( (u_int8_t) ((x)&255) )
     26        1.6  thorpej 
     27        1.6  thorpej /* Circular left shift */
     28        1.6  thorpej #define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
     29        1.6  thorpej 
     30        1.6  thorpej /* CAST-128 uses three different round functions */
     31        1.6  thorpej #define F1(l, r, i) \
     32        1.6  thorpej 	t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
     33        1.6  thorpej 	l ^= ((cast_sbox1[U_INT8_Ta(t)] ^ cast_sbox2[U_INT8_Tb(t)]) - \
     34        1.6  thorpej 	 cast_sbox3[U_INT8_Tc(t)]) + cast_sbox4[U_INT8_Td(t)];
     35        1.6  thorpej #define F2(l, r, i) \
     36        1.6  thorpej 	t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
     37        1.6  thorpej 	l ^= ((cast_sbox1[U_INT8_Ta(t)] - cast_sbox2[U_INT8_Tb(t)]) + \
     38        1.6  thorpej 	 cast_sbox3[U_INT8_Tc(t)]) ^ cast_sbox4[U_INT8_Td(t)];
     39        1.6  thorpej #define F3(l, r, i) \
     40        1.6  thorpej 	t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
     41        1.6  thorpej 	l ^= ((cast_sbox1[U_INT8_Ta(t)] + cast_sbox2[U_INT8_Tb(t)]) ^ \
     42        1.6  thorpej 	 cast_sbox3[U_INT8_Tc(t)]) - cast_sbox4[U_INT8_Td(t)];
     43        1.1  thorpej 
     44        1.1  thorpej 
     45        1.6  thorpej /***** Encryption Function *****/
     46        1.1  thorpej 
     47        1.7  thorpej void cast128_encrypt(const cast128_key* key, const u_int8_t* inblock,
     48        1.7  thorpej     u_int8_t* outblock)
     49        1.1  thorpej {
     50        1.6  thorpej u_int32_t t, l, r;
     51        1.1  thorpej 
     52        1.6  thorpej 	/* Get inblock into l,r */
     53        1.6  thorpej 	l = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
     54        1.6  thorpej 	 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
     55        1.6  thorpej 	r = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
     56        1.6  thorpej 	 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
     57        1.6  thorpej 	/* Do the work */
     58        1.6  thorpej 	F1(l, r,  0);
     59        1.6  thorpej 	F2(r, l,  1);
     60        1.6  thorpej 	F3(l, r,  2);
     61        1.6  thorpej 	F1(r, l,  3);
     62        1.6  thorpej 	F2(l, r,  4);
     63        1.6  thorpej 	F3(r, l,  5);
     64        1.6  thorpej 	F1(l, r,  6);
     65        1.6  thorpej 	F2(r, l,  7);
     66        1.6  thorpej 	F3(l, r,  8);
     67        1.6  thorpej 	F1(r, l,  9);
     68        1.6  thorpej 	F2(l, r, 10);
     69        1.6  thorpej 	F3(r, l, 11);
     70        1.6  thorpej 	/* Only do full 16 rounds if key length > 80 bits */
     71        1.6  thorpej 	if (key->rounds > 12) {
     72        1.6  thorpej 		F1(l, r, 12);
     73        1.6  thorpej 		F2(r, l, 13);
     74        1.6  thorpej 		F3(l, r, 14);
     75        1.6  thorpej 		F1(r, l, 15);
     76        1.6  thorpej 	}
     77        1.6  thorpej 	/* Put l,r into outblock */
     78        1.6  thorpej 	outblock[0] = U_INT8_Ta(r);
     79        1.6  thorpej 	outblock[1] = U_INT8_Tb(r);
     80        1.6  thorpej 	outblock[2] = U_INT8_Tc(r);
     81        1.6  thorpej 	outblock[3] = U_INT8_Td(r);
     82        1.6  thorpej 	outblock[4] = U_INT8_Ta(l);
     83        1.6  thorpej 	outblock[5] = U_INT8_Tb(l);
     84        1.6  thorpej 	outblock[6] = U_INT8_Tc(l);
     85        1.6  thorpej 	outblock[7] = U_INT8_Td(l);
     86        1.6  thorpej 	/* Wipe clean */
     87        1.6  thorpej 	t = l = r = 0;
     88        1.1  thorpej }
     89        1.1  thorpej 
     90        1.1  thorpej 
     91        1.6  thorpej /***** Decryption Function *****/
     92        1.1  thorpej 
     93        1.7  thorpej void cast128_decrypt(const cast128_key* key, const u_int8_t* inblock,
     94        1.7  thorpej     u_int8_t* outblock)
     95        1.6  thorpej {
     96        1.6  thorpej u_int32_t t, l, r;
     97        1.1  thorpej 
     98        1.6  thorpej 	/* Get inblock into l,r */
     99        1.6  thorpej 	r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
    100        1.6  thorpej 	 ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
    101        1.6  thorpej 	l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
    102        1.6  thorpej 	 ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
    103        1.6  thorpej 	/* Do the work */
    104        1.6  thorpej 	/* Only do full 16 rounds if key length > 80 bits */
    105        1.6  thorpej 	if (key->rounds > 12) {
    106        1.6  thorpej 		F1(r, l, 15);
    107        1.6  thorpej 		F3(l, r, 14);
    108        1.6  thorpej 		F2(r, l, 13);
    109        1.6  thorpej 		F1(l, r, 12);
    110        1.6  thorpej 	}
    111        1.6  thorpej 	F3(r, l, 11);
    112        1.6  thorpej 	F2(l, r, 10);
    113        1.6  thorpej 	F1(r, l,  9);
    114        1.6  thorpej 	F3(l, r,  8);
    115        1.6  thorpej 	F2(r, l,  7);
    116        1.6  thorpej 	F1(l, r,  6);
    117        1.6  thorpej 	F3(r, l,  5);
    118        1.6  thorpej 	F2(l, r,  4);
    119        1.6  thorpej 	F1(r, l,  3);
    120        1.6  thorpej 	F3(l, r,  2);
    121        1.6  thorpej 	F2(r, l,  1);
    122        1.6  thorpej 	F1(l, r,  0);
    123        1.6  thorpej 	/* Put l,r into outblock */
    124        1.6  thorpej 	outblock[0] = U_INT8_Ta(l);
    125        1.6  thorpej 	outblock[1] = U_INT8_Tb(l);
    126        1.6  thorpej 	outblock[2] = U_INT8_Tc(l);
    127        1.6  thorpej 	outblock[3] = U_INT8_Td(l);
    128        1.6  thorpej 	outblock[4] = U_INT8_Ta(r);
    129        1.6  thorpej 	outblock[5] = U_INT8_Tb(r);
    130        1.6  thorpej 	outblock[6] = U_INT8_Tc(r);
    131        1.6  thorpej 	outblock[7] = U_INT8_Td(r);
    132        1.6  thorpej 	/* Wipe clean */
    133        1.6  thorpej 	t = l = r = 0;
    134        1.1  thorpej }
    135        1.1  thorpej 
    136        1.1  thorpej 
    137        1.6  thorpej /***** Key Schedual *****/
    138        1.1  thorpej 
    139        1.7  thorpej void cast128_setkey(cast128_key* key, const u_int8_t* rawkey, int keybytes)
    140        1.1  thorpej {
    141        1.9      mrg 	u_int32_t t[4], z[4], x[4];
    142        1.9      mrg 	int i;
    143        1.1  thorpej 
    144        1.6  thorpej 	/* Set number of rounds to 12 or 16, depending on key length */
    145        1.6  thorpej 	key->rounds = (keybytes <= 10 ? 12 : 16);
    146        1.1  thorpej 
    147        1.6  thorpej 	/* Copy key to workspace x */
    148        1.6  thorpej 	for (i = 0; i < 4; i++) {
    149        1.6  thorpej 		x[i] = 0;
    150        1.9      mrg 		t[i] = z[i] = 0;	/* XXX gcc */
    151        1.6  thorpej 		if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24;
    152        1.6  thorpej 		if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16;
    153        1.6  thorpej 		if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8;
    154        1.6  thorpej 		if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3];
    155        1.6  thorpej 	}
    156        1.6  thorpej 	/* Generate 32 subkeys, four at a time */
    157        1.6  thorpej 	for (i = 0; i < 32; i+=4) {
    158        1.6  thorpej 		switch (i & 4) {
    159        1.6  thorpej 		 case 0:
    160        1.6  thorpej 			t[0] = z[0] = x[0] ^ cast_sbox5[U_INT8_Tb(x[3])] ^
    161        1.6  thorpej 			 cast_sbox6[U_INT8_Td(x[3])] ^ cast_sbox7[U_INT8_Ta(x[3])] ^
    162        1.6  thorpej 			 cast_sbox8[U_INT8_Tc(x[3])] ^ cast_sbox7[U_INT8_Ta(x[2])];
    163        1.6  thorpej 			t[1] = z[1] = x[2] ^ cast_sbox5[U_INT8_Ta(z[0])] ^
    164        1.6  thorpej 			 cast_sbox6[U_INT8_Tc(z[0])] ^ cast_sbox7[U_INT8_Tb(z[0])] ^
    165        1.6  thorpej 			 cast_sbox8[U_INT8_Td(z[0])] ^ cast_sbox8[U_INT8_Tc(x[2])];
    166        1.6  thorpej 			t[2] = z[2] = x[3] ^ cast_sbox5[U_INT8_Td(z[1])] ^
    167        1.6  thorpej 			 cast_sbox6[U_INT8_Tc(z[1])] ^ cast_sbox7[U_INT8_Tb(z[1])] ^
    168        1.6  thorpej 			 cast_sbox8[U_INT8_Ta(z[1])] ^ cast_sbox5[U_INT8_Tb(x[2])];
    169        1.6  thorpej 			t[3] = z[3] = x[1] ^ cast_sbox5[U_INT8_Tc(z[2])] ^
    170        1.6  thorpej 			 cast_sbox6[U_INT8_Tb(z[2])] ^ cast_sbox7[U_INT8_Td(z[2])] ^
    171        1.6  thorpej 			 cast_sbox8[U_INT8_Ta(z[2])] ^ cast_sbox6[U_INT8_Td(x[2])];
    172        1.6  thorpej 			break;
    173        1.6  thorpej 		 case 4:
    174        1.6  thorpej 			t[0] = x[0] = z[2] ^ cast_sbox5[U_INT8_Tb(z[1])] ^
    175        1.6  thorpej 			 cast_sbox6[U_INT8_Td(z[1])] ^ cast_sbox7[U_INT8_Ta(z[1])] ^
    176        1.6  thorpej 			 cast_sbox8[U_INT8_Tc(z[1])] ^ cast_sbox7[U_INT8_Ta(z[0])];
    177        1.6  thorpej 			t[1] = x[1] = z[0] ^ cast_sbox5[U_INT8_Ta(x[0])] ^
    178        1.6  thorpej 			 cast_sbox6[U_INT8_Tc(x[0])] ^ cast_sbox7[U_INT8_Tb(x[0])] ^
    179        1.6  thorpej 			 cast_sbox8[U_INT8_Td(x[0])] ^ cast_sbox8[U_INT8_Tc(z[0])];
    180        1.6  thorpej 			t[2] = x[2] = z[1] ^ cast_sbox5[U_INT8_Td(x[1])] ^
    181        1.6  thorpej 			 cast_sbox6[U_INT8_Tc(x[1])] ^ cast_sbox7[U_INT8_Tb(x[1])] ^
    182        1.6  thorpej 			 cast_sbox8[U_INT8_Ta(x[1])] ^ cast_sbox5[U_INT8_Tb(z[0])];
    183        1.6  thorpej 			t[3] = x[3] = z[3] ^ cast_sbox5[U_INT8_Tc(x[2])] ^
    184        1.6  thorpej 			 cast_sbox6[U_INT8_Tb(x[2])] ^ cast_sbox7[U_INT8_Td(x[2])] ^
    185        1.6  thorpej 			 cast_sbox8[U_INT8_Ta(x[2])] ^ cast_sbox6[U_INT8_Td(z[0])];
    186        1.6  thorpej 			break;
    187        1.6  thorpej 		}
    188        1.6  thorpej 		switch (i & 12) {
    189        1.6  thorpej 		 case 0:
    190        1.6  thorpej 		 case 12:
    191        1.6  thorpej 			key->xkey[i+0] = cast_sbox5[U_INT8_Ta(t[2])] ^ cast_sbox6[U_INT8_Tb(t[2])] ^
    192        1.6  thorpej 			 cast_sbox7[U_INT8_Td(t[1])] ^ cast_sbox8[U_INT8_Tc(t[1])];
    193        1.6  thorpej 			key->xkey[i+1] = cast_sbox5[U_INT8_Tc(t[2])] ^ cast_sbox6[U_INT8_Td(t[2])] ^
    194        1.6  thorpej 			 cast_sbox7[U_INT8_Tb(t[1])] ^ cast_sbox8[U_INT8_Ta(t[1])];
    195        1.6  thorpej 			key->xkey[i+2] = cast_sbox5[U_INT8_Ta(t[3])] ^ cast_sbox6[U_INT8_Tb(t[3])] ^
    196        1.6  thorpej 			 cast_sbox7[U_INT8_Td(t[0])] ^ cast_sbox8[U_INT8_Tc(t[0])];
    197        1.6  thorpej 			key->xkey[i+3] = cast_sbox5[U_INT8_Tc(t[3])] ^ cast_sbox6[U_INT8_Td(t[3])] ^
    198        1.6  thorpej 			 cast_sbox7[U_INT8_Tb(t[0])] ^ cast_sbox8[U_INT8_Ta(t[0])];
    199        1.6  thorpej 			break;
    200        1.6  thorpej 		 case 4:
    201        1.6  thorpej 		 case 8:
    202        1.6  thorpej 			key->xkey[i+0] = cast_sbox5[U_INT8_Td(t[0])] ^ cast_sbox6[U_INT8_Tc(t[0])] ^
    203        1.6  thorpej 			 cast_sbox7[U_INT8_Ta(t[3])] ^ cast_sbox8[U_INT8_Tb(t[3])];
    204        1.6  thorpej 			key->xkey[i+1] = cast_sbox5[U_INT8_Tb(t[0])] ^ cast_sbox6[U_INT8_Ta(t[0])] ^
    205        1.6  thorpej 			 cast_sbox7[U_INT8_Tc(t[3])] ^ cast_sbox8[U_INT8_Td(t[3])];
    206        1.6  thorpej 			key->xkey[i+2] = cast_sbox5[U_INT8_Td(t[1])] ^ cast_sbox6[U_INT8_Tc(t[1])] ^
    207        1.6  thorpej 			 cast_sbox7[U_INT8_Ta(t[2])] ^ cast_sbox8[U_INT8_Tb(t[2])];
    208        1.6  thorpej 			key->xkey[i+3] = cast_sbox5[U_INT8_Tb(t[1])] ^ cast_sbox6[U_INT8_Ta(t[1])] ^
    209        1.6  thorpej 			 cast_sbox7[U_INT8_Tc(t[2])] ^ cast_sbox8[U_INT8_Td(t[2])];
    210        1.6  thorpej 			break;
    211        1.6  thorpej 		}
    212        1.6  thorpej 		switch (i & 12) {
    213        1.6  thorpej 		 case 0:
    214        1.6  thorpej 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Tc(z[0])];
    215        1.6  thorpej 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Tc(z[1])];
    216        1.6  thorpej 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Tb(z[2])];
    217        1.6  thorpej 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Ta(z[3])];
    218        1.6  thorpej 			break;
    219        1.6  thorpej 		 case 4:
    220        1.6  thorpej 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Ta(x[2])];
    221        1.6  thorpej 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Tb(x[3])];
    222        1.6  thorpej 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Td(x[0])];
    223        1.6  thorpej 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Td(x[1])];
    224        1.6  thorpej 			break;
    225        1.6  thorpej 		 case 8:
    226        1.6  thorpej 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Tb(z[2])];
    227        1.6  thorpej 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Ta(z[3])];
    228        1.6  thorpej 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Tc(z[0])];
    229        1.6  thorpej 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Tc(z[1])];
    230        1.6  thorpej 			break;
    231        1.6  thorpej 		 case 12:
    232        1.6  thorpej 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Td(x[0])];
    233        1.6  thorpej 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Td(x[1])];
    234        1.6  thorpej 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Ta(x[2])];
    235        1.6  thorpej 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Tb(x[3])];
    236        1.6  thorpej 			break;
    237        1.6  thorpej 		}
    238        1.6  thorpej 		if (i >= 16) {
    239        1.6  thorpej 			key->xkey[i+0] &= 31;
    240        1.6  thorpej 			key->xkey[i+1] &= 31;
    241        1.6  thorpej 			key->xkey[i+2] &= 31;
    242        1.6  thorpej 			key->xkey[i+3] &= 31;
    243        1.6  thorpej 		}
    244        1.6  thorpej 	}
    245        1.6  thorpej 	/* Wipe clean */
    246        1.6  thorpej 	for (i = 0; i < 4; i++) {
    247        1.6  thorpej 		t[i] = x[i] = z[i] = 0;
    248        1.6  thorpej 	}
    249        1.1  thorpej }
    250        1.1  thorpej 
    251        1.6  thorpej /* Made in Canada */
    252  1.9.108.1      tls 
    253  1.9.108.1      tls #if defined(_KERNEL)
    254  1.9.108.1      tls 
    255  1.9.108.1      tls MODULE(MODULE_CLASS_MISC, cast128, NULL);
    256  1.9.108.1      tls 
    257  1.9.108.1      tls static int
    258  1.9.108.1      tls cast128_modcmd(modcmd_t cmd, void *opaque)
    259  1.9.108.1      tls {
    260  1.9.108.1      tls 
    261  1.9.108.1      tls 	switch (cmd) {
    262  1.9.108.1      tls 	case MODULE_CMD_INIT:
    263  1.9.108.1      tls 		return 0;
    264  1.9.108.1      tls 	case MODULE_CMD_FINI:
    265  1.9.108.1      tls 		return 0;
    266  1.9.108.1      tls 	default:
    267  1.9.108.1      tls 		return ENOTTY;
    268  1.9.108.1      tls 	}
    269  1.9.108.1      tls }
    270  1.9.108.1      tls 
    271  1.9.108.1      tls #endif /* defined(KERNEL) */
    272