updates.
[silc.git] / lib / silccrypt / cast.c
1 /* Modified for SILC. -Pekka */\r
2 \r
3 /* This is an independent implementation of the encryption algorithm:   */\r
4 /*                                                                      */\r
5 /*         CAST-256 by Carlisle Adams of Entrust Tecnhologies           */\r
6 /*                                                                      */\r
7 /* which is a candidate algorithm in the Advanced Encryption Standard   */\r
8 /* programme of the US National Institute of Standards and Technology.  */\r
9 /*                                                                      */\r
10 /* Copyright in this implementation is held by Dr B R Gladman but I     */\r
11 /* hereby give permission for its free direct or derivative use subject */\r
12 /* to acknowledgment of its origin and compliance with any conditions   */\r
13 /* that the originators of the algorithm place on its exploitation.     */\r
14 /*                                                                      */\r
15 /* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999     */\r
16 \r
17 /* Timing data for CAST-256 (cast.c)\r
18 \r
19 Core timing without I/O endian conversion:\r
20 \r
21 128 bit key:\r
22 Key Setup:    4333 cycles\r
23 Encrypt:       633 cycles =    40.4 mbits/sec\r
24 Decrypt:       634 cycles =    40.4 mbits/sec\r
25 Mean:          634 cycles =    40.4 mbits/sec\r
26 \r
27 192 bit key:\r
28 Key Setup:    4342 cycles\r
29 Encrypt:       633 cycles =    40.4 mbits/sec\r
30 Decrypt:       633 cycles =    40.4 mbits/sec\r
31 Mean:          633 cycles =    40.4 mbits/sec\r
32 \r
33 256 bit key:\r
34 Key Setup:    4325 cycles\r
35 Encrypt:       639 cycles =    40.1 mbits/sec\r
36 Decrypt:       638 cycles =    40.1 mbits/sec\r
37 Mean:          639 cycles =    40.1 mbits/sec\r
38 \r
39 Full timing with I/O endian conversion:\r
40 \r
41 128 bit key:\r
42 Key Setup:    4294 cycles\r
43 Encrypt:       678 cycles =    37.8 mbits/sec\r
44 Decrypt:       669 cycles =    38.3 mbits/sec\r
45 Mean:          674 cycles =    38.0 mbits/sec\r
46 \r
47 192 bit key:\r
48 Key Setup:    4314 cycles\r
49 Encrypt:       678 cycles =    37.8 mbits/sec\r
50 Decrypt:       670 cycles =    38.2 mbits/sec\r
51 Mean:          674 cycles =    38.0 mbits/sec\r
52 \r
53 256 bit key:\r
54 Key Setup:    4313 cycles\r
55 Encrypt:       678 cycles =    37.8 mbits/sec\r
56 Decrypt:       669 cycles =    38.3 mbits/sec\r
57 Mean:          674 cycles =    38.0 mbits/sec\r
58 \r
59 */\r
60 \r
61 #include "silcincludes.h"\r
62 #include "cast.h"\r
63 \r
64 #define io_swap\r
65     \r
66 /* \r
67  * SILC Crypto API for Cast-256\r
68  */\r
69 \r
70 /* Sets the key for the cipher. */\r
71 \r
72 SILC_CIPHER_API_SET_KEY(cast)\r
73 {\r
74   uint32 k[8];\r
75 \r
76   SILC_GET_WORD_KEY(key, k, keylen);\r
77   cast_set_key((CastContext *)context, k, keylen);\r
78 \r
79   return TRUE;\r
80 }\r
81 \r
82 /* Sets the string as a new key for the cipher. The string is first\r
83    hashed and then used as a new key. */\r
84 \r
85 SILC_CIPHER_API_SET_KEY_WITH_STRING(cast)\r
86 {\r
87   /*  unsigned char key[md5_hash_len];\r
88   SilcMarsContext *ctx = (SilcMarsContext *)context;\r
89 \r
90   make_md5_hash(string, &key);\r
91   memcpy(&ctx->key, mars_set_key(&key, keylen), keylen);\r
92   memset(&key, 'F', sizeoof(key));\r
93   */\r
94 \r
95   return 1;\r
96 }\r
97 \r
98 /* Returns the size of the cipher context. */\r
99 \r
100 SILC_CIPHER_API_CONTEXT_LEN(cast)\r
101 {\r
102   return sizeof(CastContext);\r
103 }\r
104 \r
105 /* Encrypts with the cipher in CBC mode. Source and destination buffers\r
106    maybe one and same. */\r
107 \r
108 SILC_CIPHER_API_ENCRYPT_CBC(cast)\r
109 {\r
110   uint32 tiv[4];\r
111   int i;\r
112 \r
113   SILC_CBC_GET_IV(tiv, iv);\r
114 \r
115   SILC_CBC_ENC_PRE(tiv, src);\r
116   cast_encrypt((CastContext *)context, tiv, tiv);\r
117   SILC_CBC_ENC_POST(tiv, dst, src);\r
118 \r
119   for (i = 16; i < len; i += 16) {\r
120     SILC_CBC_ENC_PRE(tiv, src);\r
121     cast_encrypt((CastContext *)context, tiv, tiv);\r
122     SILC_CBC_ENC_POST(tiv, dst, src);\r
123   }\r
124 \r
125   SILC_CBC_PUT_IV(tiv, iv);\r
126 \r
127   return TRUE;\r
128 }\r
129 \r
130 /* Decrypts with the cipher in CBC mode. Source and destination buffers\r
131    maybe one and same. */\r
132 \r
133 SILC_CIPHER_API_DECRYPT_CBC(cast)\r
134 {\r
135   uint32 tmp[4], tmp2[4], tiv[4];\r
136   int i;\r
137 \r
138   SILC_CBC_GET_IV(tiv, iv);\r
139 \r
140   SILC_CBC_DEC_PRE(tmp, src);\r
141   cast_decrypt((CastContext *)context, tmp, tmp2);\r
142   SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);\r
143 \r
144   for (i = 16; i < len; i += 16) {\r
145     SILC_CBC_DEC_PRE(tmp, src);\r
146     cast_decrypt((CastContext *)context, tmp, tmp2); \r
147     SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);\r
148   }\r
149   \r
150   SILC_CBC_PUT_IV(tiv, iv);\r
151   \r
152   return TRUE;\r
153 }\r
154 \r
155 u4byte s_box[4][256] = \r
156 { {\r
157     0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9C004dd3, \r
158     0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,\r
159     0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059, \r
160     0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,\r
161     0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, \r
162     0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, \r
163     0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159, \r
164     0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,\r
165     0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f,\r
166     0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,\r
167     0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0C50, 0x882240f2, 0x0c6e4f38, \r
168     0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,\r
169     0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, \r
170     0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, \r
171     0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb, \r
172     0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,\r
173     0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, \r
174     0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,\r
175     0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6C2, 0x81383f05, 0x6963c5c8,\r
176     0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,\r
177     0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, \r
178     0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,\r
179     0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426, \r
180     0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, \r
181     0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, \r
182     0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,\r
183     0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad, \r
184     0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, \r
185     0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, \r
186     0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,\r
187     0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153, \r
188     0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, \r
189     0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, \r
190     0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,\r
191     0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1, \r
192     0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,\r
193     0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, \r
194     0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,\r
195     0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814C, 0x474d6ad7, 0x7c0c5e5c, \r
196     0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,\r
197     0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, \r
198     0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, \r
199     0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf\r
200   },\r
201   {\r
202     0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,\r
203     0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, \r
204     0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605, \r
205     0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,\r
206     0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, \r
207     0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, \r
208     0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083, \r
209     0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,\r
210     0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, \r
211     0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, \r
212     0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e, \r
213     0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,\r
214     0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, \r
215     0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, \r
216     0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064, \r
217     0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,\r
218     0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, \r
219     0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, \r
220     0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364, \r
221     0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,\r
222     0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, \r
223     0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, \r
224     0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c, \r
225     0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,\r
226     0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, \r
227     0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, \r
228     0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b, \r
229     0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,\r
230     0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, \r
231     0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, \r
232     0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028, \r
233     0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,\r
234     0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,\r
235     0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, \r
236     0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1, \r
237     0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,\r
238     0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, \r
239     0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, \r
240     0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d, \r
241     0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,\r
242     0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, \r
243     0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, \r
244     0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1\r
245   },\r
246   {\r
247     0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,\r
248     0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, \r
249     0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,\r
250     0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,\r
251     0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,\r
252     0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,\r
253     0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,\r
254     0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,\r
255     0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, \r
256     0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, \r
257     0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e, \r
258     0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,\r
259     0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, \r
260     0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, \r
261     0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e, \r
262     0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,\r
263     0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, \r
264     0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, \r
265     0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240, \r
266     0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,\r
267     0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, \r
268     0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,\r
269     0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788, \r
270     0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,\r
271     0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, \r
272     0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, \r
273     0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f, \r
274     0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,\r
275     0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, \r
276     0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, \r
277     0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9, \r
278     0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,\r
279     0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, \r
280     0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, \r
281     0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2, \r
282     0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,\r
283     0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, \r
284     0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, \r
285     0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d, \r
286     0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,\r
287     0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, \r
288     0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, \r
289     0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783\r
290   },\r
291   { \r
292     0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, \r
293     0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, \r
294     0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd, \r
295     0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,\r
296     0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, \r
297     0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, \r
298     0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801, \r
299     0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,\r
300     0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, \r
301     0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,\r
302     0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3, \r
303     0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,\r
304     0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,\r
305     0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,\r
306     0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16, \r
307     0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,\r
308     0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,\r
309     0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, \r
310     0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002, \r
311     0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,\r
312     0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, \r
313     0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, \r
314     0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff, \r
315     0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,\r
316     0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, \r
317     0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, \r
318     0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec, \r
319     0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,\r
320     0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, \r
321     0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, \r
322     0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,\r
323     0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,\r
324     0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, \r
325     0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, \r
326     0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6, \r
327     0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,\r
328     0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,\r
329     0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, \r
330     0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,\r
331     0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,\r
332     0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,\r
333     0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,\r
334     0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2\r
335   }\r
336 };\r
337 \r
338 #define f1(y,x,kr,km)                           \\r
339     t  = rotl(km + x, kr);                      \\r
340     u  = s_box[0][byte(t,3)];                   \\r
341     u ^= s_box[1][byte(t,2)];                   \\r
342     u -= s_box[2][byte(t,1)];                   \\r
343     u += s_box[3][byte(t,0)];                   \\r
344     y ^= u\r
345 \r
346 #define f2(y,x,kr,km)                           \\r
347     t  = rotl(km ^ x, kr);                      \\r
348     u  = s_box[0][byte(t,3)];                   \\r
349     u -= s_box[1][byte(t,2)];                   \\r
350     u += s_box[2][byte(t,1)];                   \\r
351     u ^= s_box[3][byte(t,0)];                   \\r
352     y ^= u\r
353 \r
354 #define f3(y,x,kr,km)                           \\r
355     t  = rotl(km - x, kr);                      \\r
356     u  = s_box[0][byte(t,3)];                   \\r
357     u += s_box[1][byte(t,2)];                   \\r
358     u ^= s_box[2][byte(t,1)];                   \\r
359     u -= s_box[3][byte(t,0)];                   \\r
360     y ^= u\r
361 \r
362 #define f_rnd(x,n)                              \\r
363     f1(x[2],x[3],l_key[n],    l_key[n + 4]);    \\r
364     f2(x[1],x[2],l_key[n + 1],l_key[n + 5]);    \\r
365     f3(x[0],x[1],l_key[n + 2],l_key[n + 6]);    \\r
366     f1(x[3],x[0],l_key[n + 3],l_key[n + 7])\r
367 \r
368 #define i_rnd(x, n)                             \\r
369     f1(x[3],x[0],l_key[n + 3],l_key[n + 7]);    \\r
370     f3(x[0],x[1],l_key[n + 2],l_key[n + 6]);    \\r
371     f2(x[1],x[2],l_key[n + 1],l_key[n + 5]);    \\r
372     f1(x[2],x[3],l_key[n],    l_key[n + 4])\r
373 \r
374 #define k_rnd(k,tr,tm)                          \\r
375     f1(k[6],k[7],tr[0],tm[0]);                  \\r
376     f2(k[5],k[6],tr[1],tm[1]);                  \\r
377     f3(k[4],k[5],tr[2],tm[2]);                  \\r
378     f1(k[3],k[4],tr[3],tm[3]);                  \\r
379     f2(k[2],k[3],tr[4],tm[4]);                  \\r
380     f3(k[1],k[2],tr[5],tm[5]);                  \\r
381     f1(k[0],k[1],tr[6],tm[6]);                  \\r
382     f2(k[7],k[0],tr[7],tm[7])\r
383 \r
384 /* initialise the key schedule from the user supplied key   */\r
385 \r
386 u4byte *cast_set_key(CastContext *ctx,\r
387                      const u4byte in_key[], const u4byte key_len)\r
388 {   \r
389     u4byte  i, j, t, u, cm, cr, lk[8], tm[8], tr[8];\r
390     u4byte *l_key = ctx->l_key;\r
391 \r
392     for(i = 0; i < key_len / 32; ++i)\r
393 \r
394         lk[i] = io_swap(in_key[i]);\r
395 \r
396     for(; i < 8; ++i)\r
397 \r
398         lk[i] = 0;\r
399 \r
400     cm = 0x5a827999; cr = 19;\r
401 \r
402     for(i = 0; i < 96; i += 8)\r
403     {\r
404         for(j = 0; j < 8; ++j)\r
405         {\r
406             tm[j] = cm; cm += 0x6ed9eba1;\r
407             tr[j] = cr; cr += 17;\r
408         }\r
409 \r
410         k_rnd(lk, tr, tm);\r
411         \r
412         for(j = 0; j < 8; ++j)\r
413         {\r
414             tm[j] = cm; cm += 0x6ed9eba1;\r
415             tr[j] = cr; cr += 17;\r
416         }\r
417 \r
418         k_rnd(lk, tr, tm);\r
419 \r
420         l_key[i + 0] = lk[0]; l_key[i + 1] = lk[2];\r
421         l_key[i + 2] = lk[4]; l_key[i + 3] = lk[6];\r
422         l_key[i + 4] = lk[7]; l_key[i + 5] = lk[5];\r
423         l_key[i + 6] = lk[3]; l_key[i + 7] = lk[1];\r
424     }\r
425 \r
426     return l_key;\r
427 }\r
428 \r
429 /* encrypt a block of text  */\r
430 \r
431 void cast_encrypt(CastContext *ctx,\r
432                   const u4byte in_blk[4], u4byte out_blk[])\r
433 {   \r
434     u4byte  t, u, blk[4];\r
435     u4byte *l_key = ctx->l_key;\r
436 \r
437     blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);\r
438     blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);\r
439 \r
440     f_rnd(blk,  0); f_rnd(blk,  8);\r
441     f_rnd(blk, 16); f_rnd(blk, 24);\r
442     f_rnd(blk, 32); f_rnd(blk, 40);\r
443     i_rnd(blk, 48); i_rnd(blk, 56);\r
444     i_rnd(blk, 64); i_rnd(blk, 72);\r
445     i_rnd(blk, 80); i_rnd(blk, 88);\r
446 \r
447     out_blk[0] = io_swap(blk[0]); out_blk[1] = io_swap(blk[1]);\r
448     out_blk[2] = io_swap(blk[2]); out_blk[3] = io_swap(blk[3]);\r
449 }\r
450 \r
451 /* decrypt a block of text  */\r
452 \r
453 void cast_decrypt(CastContext *ctx,\r
454                   const u4byte in_blk[4], u4byte out_blk[4])\r
455 {   \r
456     u4byte  t, u, blk[4];\r
457     u4byte *l_key = ctx->l_key;\r
458 \r
459     blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);\r
460     blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);\r
461 \r
462     f_rnd(blk, 88); f_rnd(blk, 80);\r
463     f_rnd(blk, 72); f_rnd(blk, 64);\r
464     f_rnd(blk, 56); f_rnd(blk, 48);\r
465     i_rnd(blk, 40); i_rnd(blk, 32);\r
466     i_rnd(blk, 24); i_rnd(blk, 16);\r
467     i_rnd(blk,  8); i_rnd(blk,  0);\r
468 \r
469     out_blk[0] = io_swap(blk[0]); out_blk[1] = io_swap(blk[1]);\r
470     out_blk[2] = io_swap(blk[2]); out_blk[3] = io_swap(blk[3]);\r
471 }\r