kernel/scsi: Fix sense information printing in bootverbose.
[dragonfly.git] / sys / opencrypto / cast.c
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