Annotation of sys/crypto/cast.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cast.c,v 1.3 2005/03/24 11:45:28 hshoexer 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 <crypto/cast.h>
12: #include <crypto/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
41: cast_encrypt(cast_key *key, u_int8_t *inblock, u_int8_t *outblock)
42: {
43: u_int32_t t, l, r;
44:
45: /* Get inblock into l,r */
46: l = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
47: ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
48: r = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
49: ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
50: /* Do the work */
51: F1(l, r, 0);
52: F2(r, l, 1);
53: F3(l, r, 2);
54: F1(r, l, 3);
55: F2(l, r, 4);
56: F3(r, l, 5);
57: F1(l, r, 6);
58: F2(r, l, 7);
59: F3(l, r, 8);
60: F1(r, l, 9);
61: F2(l, r, 10);
62: F3(r, l, 11);
63: /* Only do full 16 rounds if key length > 80 bits */
64: if (key->rounds > 12) {
65: F1(l, r, 12);
66: F2(r, l, 13);
67: F3(l, r, 14);
68: F1(r, l, 15);
69: }
70: /* Put l,r into outblock */
71: outblock[0] = U_INT8_Ta(r);
72: outblock[1] = U_INT8_Tb(r);
73: outblock[2] = U_INT8_Tc(r);
74: outblock[3] = U_INT8_Td(r);
75: outblock[4] = U_INT8_Ta(l);
76: outblock[5] = U_INT8_Tb(l);
77: outblock[6] = U_INT8_Tc(l);
78: outblock[7] = U_INT8_Td(l);
79: /* Wipe clean */
80: t = l = r = 0;
81: }
82:
83:
84: /***** Decryption Function *****/
85:
86: void
87: cast_decrypt(cast_key *key, u_int8_t *inblock, u_int8_t *outblock)
88: {
89: u_int32_t t, l, r;
90:
91: /* Get inblock into l,r */
92: r = ((u_int32_t)inblock[0] << 24) | ((u_int32_t)inblock[1] << 16) |
93: ((u_int32_t)inblock[2] << 8) | (u_int32_t)inblock[3];
94: l = ((u_int32_t)inblock[4] << 24) | ((u_int32_t)inblock[5] << 16) |
95: ((u_int32_t)inblock[6] << 8) | (u_int32_t)inblock[7];
96: /* Do the work */
97: /* Only do full 16 rounds if key length > 80 bits */
98: if (key->rounds > 12) {
99: F1(r, l, 15);
100: F3(l, r, 14);
101: F2(r, l, 13);
102: F1(l, r, 12);
103: }
104: F3(r, l, 11);
105: F2(l, r, 10);
106: F1(r, l, 9);
107: F3(l, r, 8);
108: F2(r, l, 7);
109: F1(l, r, 6);
110: F3(r, l, 5);
111: F2(l, r, 4);
112: F1(r, l, 3);
113: F3(l, r, 2);
114: F2(r, l, 1);
115: F1(l, r, 0);
116: /* Put l,r into outblock */
117: outblock[0] = U_INT8_Ta(l);
118: outblock[1] = U_INT8_Tb(l);
119: outblock[2] = U_INT8_Tc(l);
120: outblock[3] = U_INT8_Td(l);
121: outblock[4] = U_INT8_Ta(r);
122: outblock[5] = U_INT8_Tb(r);
123: outblock[6] = U_INT8_Tc(r);
124: outblock[7] = U_INT8_Td(r);
125: /* Wipe clean */
126: t = l = r = 0;
127: }
128:
129:
130: /***** Key Schedule *****/
131:
132: void
133: cast_setkey(cast_key *key, u_int8_t *rawkey, int keybytes)
134: {
135: u_int32_t t[4], z[4], x[4];
136: int i;
137:
138: /* Set number of rounds to 12 or 16, depending on key length */
139: key->rounds = (keybytes <= 10 ? 12 : 16);
140:
141: /* Copy key to workspace x */
142: for (i = 0; i < 4; i++) {
143: x[i] = 0;
144: if ((i*4+0) < keybytes) x[i] = (u_int32_t)rawkey[i*4+0] << 24;
145: if ((i*4+1) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+1] << 16;
146: if ((i*4+2) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+2] << 8;
147: if ((i*4+3) < keybytes) x[i] |= (u_int32_t)rawkey[i*4+3];
148: }
149: /* Generate 32 subkeys, four at a time */
150: for (i = 0; i < 32; i+=4) {
151: switch (i & 4) {
152: case 0:
153: t[0] = z[0] = x[0] ^ cast_sbox5[U_INT8_Tb(x[3])] ^
154: cast_sbox6[U_INT8_Td(x[3])] ^
155: cast_sbox7[U_INT8_Ta(x[3])] ^
156: cast_sbox8[U_INT8_Tc(x[3])] ^
157: cast_sbox7[U_INT8_Ta(x[2])];
158: t[1] = z[1] = x[2] ^ cast_sbox5[U_INT8_Ta(z[0])] ^
159: cast_sbox6[U_INT8_Tc(z[0])] ^
160: cast_sbox7[U_INT8_Tb(z[0])] ^
161: cast_sbox8[U_INT8_Td(z[0])] ^
162: cast_sbox8[U_INT8_Tc(x[2])];
163: t[2] = z[2] = x[3] ^ cast_sbox5[U_INT8_Td(z[1])] ^
164: cast_sbox6[U_INT8_Tc(z[1])] ^
165: cast_sbox7[U_INT8_Tb(z[1])] ^
166: cast_sbox8[U_INT8_Ta(z[1])] ^
167: cast_sbox5[U_INT8_Tb(x[2])];
168: t[3] = z[3] = x[1] ^ cast_sbox5[U_INT8_Tc(z[2])] ^
169: cast_sbox6[U_INT8_Tb(z[2])] ^
170: cast_sbox7[U_INT8_Td(z[2])] ^
171: cast_sbox8[U_INT8_Ta(z[2])] ^
172: cast_sbox6[U_INT8_Td(x[2])];
173: break;
174: case 4:
175: t[0] = x[0] = z[2] ^ cast_sbox5[U_INT8_Tb(z[1])] ^
176: cast_sbox6[U_INT8_Td(z[1])] ^
177: cast_sbox7[U_INT8_Ta(z[1])] ^
178: cast_sbox8[U_INT8_Tc(z[1])] ^
179: cast_sbox7[U_INT8_Ta(z[0])];
180: t[1] = x[1] = z[0] ^ cast_sbox5[U_INT8_Ta(x[0])] ^
181: cast_sbox6[U_INT8_Tc(x[0])] ^
182: cast_sbox7[U_INT8_Tb(x[0])] ^
183: cast_sbox8[U_INT8_Td(x[0])] ^
184: cast_sbox8[U_INT8_Tc(z[0])];
185: t[2] = x[2] = z[1] ^ cast_sbox5[U_INT8_Td(x[1])] ^
186: cast_sbox6[U_INT8_Tc(x[1])] ^
187: cast_sbox7[U_INT8_Tb(x[1])] ^
188: cast_sbox8[U_INT8_Ta(x[1])] ^
189: cast_sbox5[U_INT8_Tb(z[0])];
190: t[3] = x[3] = z[3] ^ cast_sbox5[U_INT8_Tc(x[2])] ^
191: cast_sbox6[U_INT8_Tb(x[2])] ^
192: cast_sbox7[U_INT8_Td(x[2])] ^
193: cast_sbox8[U_INT8_Ta(x[2])] ^
194: cast_sbox6[U_INT8_Td(z[0])];
195: break;
196: }
197: switch (i & 12) {
198: case 0:
199: case 12:
200: key->xkey[i+0] = cast_sbox5[U_INT8_Ta(t[2])] ^
201: cast_sbox6[U_INT8_Tb(t[2])] ^
202: cast_sbox7[U_INT8_Td(t[1])] ^
203: cast_sbox8[U_INT8_Tc(t[1])];
204: key->xkey[i+1] = cast_sbox5[U_INT8_Tc(t[2])] ^
205: cast_sbox6[U_INT8_Td(t[2])] ^
206: cast_sbox7[U_INT8_Tb(t[1])] ^
207: cast_sbox8[U_INT8_Ta(t[1])];
208: key->xkey[i+2] = cast_sbox5[U_INT8_Ta(t[3])] ^
209: cast_sbox6[U_INT8_Tb(t[3])] ^
210: cast_sbox7[U_INT8_Td(t[0])] ^
211: cast_sbox8[U_INT8_Tc(t[0])];
212: key->xkey[i+3] = cast_sbox5[U_INT8_Tc(t[3])] ^
213: cast_sbox6[U_INT8_Td(t[3])] ^
214: cast_sbox7[U_INT8_Tb(t[0])] ^
215: cast_sbox8[U_INT8_Ta(t[0])];
216: break;
217: case 4:
218: case 8:
219: key->xkey[i+0] = cast_sbox5[U_INT8_Td(t[0])] ^
220: cast_sbox6[U_INT8_Tc(t[0])] ^
221: cast_sbox7[U_INT8_Ta(t[3])] ^
222: cast_sbox8[U_INT8_Tb(t[3])];
223: key->xkey[i+1] = cast_sbox5[U_INT8_Tb(t[0])] ^
224: cast_sbox6[U_INT8_Ta(t[0])] ^
225: cast_sbox7[U_INT8_Tc(t[3])] ^
226: cast_sbox8[U_INT8_Td(t[3])];
227: key->xkey[i+2] = cast_sbox5[U_INT8_Td(t[1])] ^
228: cast_sbox6[U_INT8_Tc(t[1])] ^
229: cast_sbox7[U_INT8_Ta(t[2])] ^
230: cast_sbox8[U_INT8_Tb(t[2])];
231: key->xkey[i+3] = cast_sbox5[U_INT8_Tb(t[1])] ^
232: cast_sbox6[U_INT8_Ta(t[1])] ^
233: cast_sbox7[U_INT8_Tc(t[2])] ^
234: cast_sbox8[U_INT8_Td(t[2])];
235: break;
236: }
237: switch (i & 12) {
238: case 0:
239: key->xkey[i+0] ^= cast_sbox5[U_INT8_Tc(z[0])];
240: key->xkey[i+1] ^= cast_sbox6[U_INT8_Tc(z[1])];
241: key->xkey[i+2] ^= cast_sbox7[U_INT8_Tb(z[2])];
242: key->xkey[i+3] ^= cast_sbox8[U_INT8_Ta(z[3])];
243: break;
244: case 4:
245: key->xkey[i+0] ^= cast_sbox5[U_INT8_Ta(x[2])];
246: key->xkey[i+1] ^= cast_sbox6[U_INT8_Tb(x[3])];
247: key->xkey[i+2] ^= cast_sbox7[U_INT8_Td(x[0])];
248: key->xkey[i+3] ^= cast_sbox8[U_INT8_Td(x[1])];
249: break;
250: case 8:
251: key->xkey[i+0] ^= cast_sbox5[U_INT8_Tb(z[2])];
252: key->xkey[i+1] ^= cast_sbox6[U_INT8_Ta(z[3])];
253: key->xkey[i+2] ^= cast_sbox7[U_INT8_Tc(z[0])];
254: key->xkey[i+3] ^= cast_sbox8[U_INT8_Tc(z[1])];
255: break;
256: case 12:
257: key->xkey[i+0] ^= cast_sbox5[U_INT8_Td(x[0])];
258: key->xkey[i+1] ^= cast_sbox6[U_INT8_Td(x[1])];
259: key->xkey[i+2] ^= cast_sbox7[U_INT8_Ta(x[2])];
260: key->xkey[i+3] ^= cast_sbox8[U_INT8_Tb(x[3])];
261: break;
262: }
263: if (i >= 16) {
264: key->xkey[i+0] &= 31;
265: key->xkey[i+1] &= 31;
266: key->xkey[i+2] &= 31;
267: key->xkey[i+3] &= 31;
268: }
269: }
270: /* Wipe clean */
271: for (i = 0; i < 4; i++) {
272: t[i] = x[i] = z[i] = 0;
273: }
274: }
275:
276: /* Made in Canada */
CVSweb