xref: /openbsd/sys/crypto/cast.c (revision 582ae63f)
1 /*      $OpenBSD: cast.c,v 1.4 2012/04/25 04:12:27 matthew Exp $       */
2 
3 /*
4  *	CAST-128 in C
5  *	Written by Steve Reid <sreid@sea-to-sky.net>
6  *	100% Public Domain - no warranty
7  *	Released 1997.10.11
8  */
9 
10 #include <sys/types.h>
11 #include <sys/systm.h>
12 #include <crypto/cast.h>
13 #include <crypto/castsb.h>
14 
15 /* Macros to access 8-bit bytes out of a 32-bit word */
16 #define U_INT8_Ta(x) ( (u_int8_t) (x>>24) )
17 #define U_INT8_Tb(x) ( (u_int8_t) ((x>>16)&255) )
18 #define U_INT8_Tc(x) ( (u_int8_t) ((x>>8)&255) )
19 #define U_INT8_Td(x) ( (u_int8_t) ((x)&255) )
20 
21 /* Circular left shift */
22 #define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
23 
24 /* CAST-128 uses three different round functions */
25 #define F1(l, r, i) \
26 	t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
27 	l ^= ((cast_sbox1[U_INT8_Ta(t)] ^ cast_sbox2[U_INT8_Tb(t)]) - \
28 	 cast_sbox3[U_INT8_Tc(t)]) + cast_sbox4[U_INT8_Td(t)];
29 #define F2(l, r, i) \
30 	t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
31 	l ^= ((cast_sbox1[U_INT8_Ta(t)] - cast_sbox2[U_INT8_Tb(t)]) + \
32 	 cast_sbox3[U_INT8_Tc(t)]) ^ cast_sbox4[U_INT8_Td(t)];
33 #define F3(l, r, i) \
34 	t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
35 	l ^= ((cast_sbox1[U_INT8_Ta(t)] + cast_sbox2[U_INT8_Tb(t)]) ^ \
36 	 cast_sbox3[U_INT8_Tc(t)]) - cast_sbox4[U_INT8_Td(t)];
37 
38 
39 /***** Encryption Function *****/
40 
41 void
cast_encrypt(cast_key * key,u_int8_t * inblock,u_int8_t * outblock)42 cast_encrypt(cast_key *key, u_int8_t *inblock, u_int8_t *outblock)
43 {
44 	u_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 
87 void
cast_decrypt(cast_key * key,u_int8_t * inblock,u_int8_t * outblock)88 cast_decrypt(cast_key *key, u_int8_t *inblock, u_int8_t *outblock)
89 {
90 	u_int32_t t, l, r;
91 
92 	/* Get inblock into l,r */
93 	r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
94 	    ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
95 	l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
96 	    ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
97 	/* Do the work */
98 	/* Only do full 16 rounds if key length > 80 bits */
99 	if (key->rounds > 12) {
100 		F1(r, l, 15);
101 		F3(l, r, 14);
102 		F2(r, l, 13);
103 		F1(l, r, 12);
104 	}
105 	F3(r, l, 11);
106 	F2(l, r, 10);
107 	F1(r, l,  9);
108 	F3(l, r,  8);
109 	F2(r, l,  7);
110 	F1(l, r,  6);
111 	F3(r, l,  5);
112 	F2(l, r,  4);
113 	F1(r, l,  3);
114 	F3(l, r,  2);
115 	F2(r, l,  1);
116 	F1(l, r,  0);
117 	/* Put l,r into outblock */
118 	outblock[0] = U_INT8_Ta(l);
119 	outblock[1] = U_INT8_Tb(l);
120 	outblock[2] = U_INT8_Tc(l);
121 	outblock[3] = U_INT8_Td(l);
122 	outblock[4] = U_INT8_Ta(r);
123 	outblock[5] = U_INT8_Tb(r);
124 	outblock[6] = U_INT8_Tc(r);
125 	outblock[7] = U_INT8_Td(r);
126 	/* Wipe clean */
127 	t = l = r = 0;
128 }
129 
130 
131 /***** Key Schedule *****/
132 
133 void
cast_setkey(cast_key * key,u_int8_t * rawkey,int keybytes)134 cast_setkey(cast_key *key, u_int8_t *rawkey, int keybytes)
135 {
136 	u_int32_t t[4], z[4], x[4];
137 	int i;
138 
139 	/* Set number of rounds to 12 or 16, depending on key length */
140 	key->rounds = (keybytes <= 10 ? 12 : 16);
141 
142 	/* Copy key to workspace x */
143 	for (i = 0; i < 4; i++) {
144 		x[i] = 0;
145 		if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24;
146 		if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16;
147 		if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8;
148 		if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3];
149 	}
150 	/* Generate 32 subkeys, four at a time */
151 	for (i = 0; i < 32; i+=4) {
152 		switch (i & 4) {
153 		case 0:
154 			t[0] = z[0] = x[0] ^ cast_sbox5[U_INT8_Tb(x[3])] ^
155 			    cast_sbox6[U_INT8_Td(x[3])] ^
156 			    cast_sbox7[U_INT8_Ta(x[3])] ^
157 			    cast_sbox8[U_INT8_Tc(x[3])] ^
158 			    cast_sbox7[U_INT8_Ta(x[2])];
159 			t[1] = z[1] = x[2] ^ cast_sbox5[U_INT8_Ta(z[0])] ^
160 			    cast_sbox6[U_INT8_Tc(z[0])] ^
161 			    cast_sbox7[U_INT8_Tb(z[0])] ^
162 			    cast_sbox8[U_INT8_Td(z[0])] ^
163 			    cast_sbox8[U_INT8_Tc(x[2])];
164 			t[2] = z[2] = x[3] ^ cast_sbox5[U_INT8_Td(z[1])] ^
165 			    cast_sbox6[U_INT8_Tc(z[1])] ^
166 			    cast_sbox7[U_INT8_Tb(z[1])] ^
167 			    cast_sbox8[U_INT8_Ta(z[1])] ^
168 			    cast_sbox5[U_INT8_Tb(x[2])];
169 			t[3] = z[3] = x[1] ^ cast_sbox5[U_INT8_Tc(z[2])] ^
170 			    cast_sbox6[U_INT8_Tb(z[2])] ^
171 			    cast_sbox7[U_INT8_Td(z[2])] ^
172 			    cast_sbox8[U_INT8_Ta(z[2])] ^
173 			    cast_sbox6[U_INT8_Td(x[2])];
174 			break;
175 		 case 4:
176 			t[0] = x[0] = z[2] ^ cast_sbox5[U_INT8_Tb(z[1])] ^
177 			    cast_sbox6[U_INT8_Td(z[1])] ^
178 			    cast_sbox7[U_INT8_Ta(z[1])] ^
179 			    cast_sbox8[U_INT8_Tc(z[1])] ^
180 			    cast_sbox7[U_INT8_Ta(z[0])];
181 			t[1] = x[1] = z[0] ^ cast_sbox5[U_INT8_Ta(x[0])] ^
182 			    cast_sbox6[U_INT8_Tc(x[0])] ^
183 			    cast_sbox7[U_INT8_Tb(x[0])] ^
184 			    cast_sbox8[U_INT8_Td(x[0])] ^
185 			    cast_sbox8[U_INT8_Tc(z[0])];
186 			t[2] = x[2] = z[1] ^ cast_sbox5[U_INT8_Td(x[1])] ^
187 			    cast_sbox6[U_INT8_Tc(x[1])] ^
188 			    cast_sbox7[U_INT8_Tb(x[1])] ^
189 			    cast_sbox8[U_INT8_Ta(x[1])] ^
190 			    cast_sbox5[U_INT8_Tb(z[0])];
191 			t[3] = x[3] = z[3] ^ cast_sbox5[U_INT8_Tc(x[2])] ^
192 			    cast_sbox6[U_INT8_Tb(x[2])] ^
193 			    cast_sbox7[U_INT8_Td(x[2])] ^
194 			    cast_sbox8[U_INT8_Ta(x[2])] ^
195 			    cast_sbox6[U_INT8_Td(z[0])];
196 			break;
197 		}
198 		switch (i & 12) {
199 		case 0:
200 		case 12:
201 			key->xkey[i+0] = cast_sbox5[U_INT8_Ta(t[2])] ^
202 			    cast_sbox6[U_INT8_Tb(t[2])] ^
203 			    cast_sbox7[U_INT8_Td(t[1])] ^
204 			    cast_sbox8[U_INT8_Tc(t[1])];
205 			key->xkey[i+1] = cast_sbox5[U_INT8_Tc(t[2])] ^
206 			    cast_sbox6[U_INT8_Td(t[2])] ^
207 			    cast_sbox7[U_INT8_Tb(t[1])] ^
208 			    cast_sbox8[U_INT8_Ta(t[1])];
209 			key->xkey[i+2] = cast_sbox5[U_INT8_Ta(t[3])] ^
210 			    cast_sbox6[U_INT8_Tb(t[3])] ^
211 			    cast_sbox7[U_INT8_Td(t[0])] ^
212 			    cast_sbox8[U_INT8_Tc(t[0])];
213 			key->xkey[i+3] = cast_sbox5[U_INT8_Tc(t[3])] ^
214 			    cast_sbox6[U_INT8_Td(t[3])] ^
215 			    cast_sbox7[U_INT8_Tb(t[0])] ^
216 			    cast_sbox8[U_INT8_Ta(t[0])];
217 			break;
218 		case 4:
219 		case 8:
220 			key->xkey[i+0] = cast_sbox5[U_INT8_Td(t[0])] ^
221 			    cast_sbox6[U_INT8_Tc(t[0])] ^
222 			    cast_sbox7[U_INT8_Ta(t[3])] ^
223 			    cast_sbox8[U_INT8_Tb(t[3])];
224 			key->xkey[i+1] = cast_sbox5[U_INT8_Tb(t[0])] ^
225 			    cast_sbox6[U_INT8_Ta(t[0])] ^
226 			    cast_sbox7[U_INT8_Tc(t[3])] ^
227 			    cast_sbox8[U_INT8_Td(t[3])];
228 			key->xkey[i+2] = cast_sbox5[U_INT8_Td(t[1])] ^
229 			    cast_sbox6[U_INT8_Tc(t[1])] ^
230 			    cast_sbox7[U_INT8_Ta(t[2])] ^
231 			    cast_sbox8[U_INT8_Tb(t[2])];
232 			key->xkey[i+3] = cast_sbox5[U_INT8_Tb(t[1])] ^
233 			    cast_sbox6[U_INT8_Ta(t[1])] ^
234 			    cast_sbox7[U_INT8_Tc(t[2])] ^
235 			    cast_sbox8[U_INT8_Td(t[2])];
236 			break;
237 		}
238 		switch (i & 12) {
239 		case 0:
240 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Tc(z[0])];
241 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Tc(z[1])];
242 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Tb(z[2])];
243 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Ta(z[3])];
244 			break;
245 		case 4:
246 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Ta(x[2])];
247 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Tb(x[3])];
248 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Td(x[0])];
249 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Td(x[1])];
250 			break;
251 		case 8:
252 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Tb(z[2])];
253 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Ta(z[3])];
254 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Tc(z[0])];
255 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Tc(z[1])];
256 			break;
257 		case 12:
258 			key->xkey[i+0] ^= cast_sbox5[U_INT8_Td(x[0])];
259 			key->xkey[i+1] ^= cast_sbox6[U_INT8_Td(x[1])];
260 			key->xkey[i+2] ^= cast_sbox7[U_INT8_Ta(x[2])];
261 			key->xkey[i+3] ^= cast_sbox8[U_INT8_Tb(x[3])];
262 			break;
263 		}
264 		if (i >= 16) {
265 			key->xkey[i+0] &= 31;
266 			key->xkey[i+1] &= 31;
267 			key->xkey[i+2] &= 31;
268 			key->xkey[i+3] &= 31;
269 		}
270 	}
271 	/* Wipe clean */
272 	explicit_bzero(t, sizeof(t));
273 	explicit_bzero(x, sizeof(x));
274 	explicit_bzero(z, sizeof(z));
275 }
276 
277 /* Made in Canada */
278