xref: /dragonfly/sys/opencrypto/cast.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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 
cast_encrypt(cast_key * key,u_int8_t * inblock,u_int8_t * outblock)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 
cast_decrypt(cast_key * key,u_int8_t * inblock,u_int8_t * outblock)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 
cast_setkey(cast_key * key,u_int8_t * rawkey,int keybytes)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