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