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