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