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