crypto: tcrypt - do not attempt to write to readonly variable
[linux-2.6.git] / crypto / cast5.c
1 /* Kernel cryptographic api.
2 * cast5.c - Cast5 cipher algorithm (rfc2144).
3 *
4 * Derived from GnuPG implementation of cast5.
5 *
6 * Major Changes.
7 *       Complete conformance to rfc2144.
8 *       Supports key size from 40 to 128 bits.
9 *
10 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
11 * Copyright (C) 2003 Kartikey Mahendra Bhatt <kartik_me@hotmail.com>.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 */
22
23
24 #include <asm/byteorder.h>
25 #include <linux/init.h>
26 #include <linux/crypto.h>
27 #include <linux/module.h>
28 #include <linux/errno.h>
29 #include <linux/string.h>
30 #include <linux/types.h>
31
32 #define CAST5_BLOCK_SIZE 8
33 #define CAST5_MIN_KEY_SIZE 5
34 #define CAST5_MAX_KEY_SIZE 16
35
36 struct cast5_ctx {
37         u32 Km[16];
38         u8 Kr[16];
39         int rr; /* rr?number of rounds = 16:number of rounds = 12; (rfc 2144) */
40 };
41
42
43 static const u32 s1[256] = {
44         0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
45         0x9c004dd3, 0x6003e540, 0xcf9fc949,
46         0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
47         0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
48         0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3,
49         0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
50         0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1,
51         0xaa54166b, 0x22568e3a, 0xa2d341d0,
52         0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac,
53         0x4a97c1d8, 0x527644b7, 0xb5f437a7,
54         0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
55         0x90ecf52e, 0x22b0c054, 0xbc8e5935,
56         0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290,
57         0xe93b159f, 0xb48ee411, 0x4bff345d,
58         0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad,
59         0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
60         0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
61         0xc59c5319, 0xb949e354, 0xb04669fe,
62         0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5,
63         0x6a390493, 0xe63d37e0, 0x2a54f6b3,
64         0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
65         0xf61b1891, 0xbb72275e, 0xaa508167,
66         0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
67         0xa2d1936b, 0x2ad286af, 0xaa56d291,
68         0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d,
69         0x73e2bb14, 0xa0bebc3c, 0x54623779,
70         0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e,
71         0x89fe78e6, 0x3fab0950, 0x325ff6c2,
72         0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf,
73         0x380782d5, 0xc7fa5cf6, 0x8ac31511,
74         0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
75         0x051ef495, 0xaa573b04, 0x4a805d8d,
76         0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b,
77         0x50afd341, 0xa7c13275, 0x915a0bf5,
78         0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
79         0xab85c5f3, 0x1b55db94, 0xaad4e324,
80         0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3,
81         0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
82         0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6,
83         0x22513f1e, 0xaa51a79b, 0x2ad344cc,
84         0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
85         0x032268d4, 0xc9600acc, 0xce387e6d,
86         0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da,
87         0x4736f464, 0x5ad328d8, 0xb347cc96,
88         0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc,
89         0xbfc5fe4a, 0xa70aec10, 0xac39570a,
90         0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f,
91         0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
92         0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4,
93         0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
94         0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
95         0x51c85f4d, 0x56907596, 0xa5bb15e6,
96         0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
97         0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
98         0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf,
99         0x700b45e1, 0xd5ea50f1, 0x85a92872,
100         0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198,
101         0x0cd0ede7, 0x26470db8, 0xf881814c,
102         0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db,
103         0xab838653, 0x6e2f1e23, 0x83719c9e,
104         0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
105         0xe1e696ff, 0xb141ab08, 0x7cca89b9,
106         0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
107         0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
108 };
109 static const u32 s2[256] = {
110         0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
111         0xeec5207a, 0x55889c94, 0x72fc0651,
112         0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
113         0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
114         0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086,
115         0xef944459, 0xba83ccb3, 0xe0c3cdfb,
116         0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb,
117         0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
118         0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f,
119         0x77e83f4e, 0x79929269, 0x24fa9f7b,
120         0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
121         0x0d554b63, 0x5d681121, 0xc866c359,
122         0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181,
123         0x39f7627f, 0x361e3084, 0xe4eb573b,
124         0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c,
125         0x99847ab4, 0xa0e3df79, 0xba6cf38c,
126         0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a,
127         0x8f458c74, 0xd9e0a227, 0x4ec73a34,
128         0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c,
129         0x1d804366, 0x721d9bfd, 0xa58684bb,
130         0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
131         0x27e19ba5, 0xd5a6c252, 0xe49754bd,
132         0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9,
133         0xe0b56714, 0x21f043b7, 0xe5d05860,
134         0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf,
135         0x68561be6, 0x83ca6b94, 0x2d6ed23b,
136         0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c,
137         0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
138         0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122,
139         0xb96726d1, 0x8049a7e8, 0x22b7da7b,
140         0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
141         0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
142         0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53,
143         0xe3214517, 0xb4542835, 0x9f63293c,
144         0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6,
145         0x30a22c95, 0x31a70850, 0x60930f13,
146         0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6,
147         0xa02b1741, 0x7cbad9a2, 0x2180036f,
148         0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676,
149         0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
150         0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
151         0x846a3bae, 0x8ff77888, 0xee5d60f6,
152         0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54,
153         0x157fd7fa, 0xef8579cc, 0xd152de58,
154         0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5,
155         0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
156         0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8,
157         0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
158         0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc,
159         0x301e16e6, 0x273be979, 0xb0ffeaa6,
160         0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
161         0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
162         0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e,
163         0x1a513742, 0xef6828bc, 0x520365d6,
164         0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb,
165         0x5eea29cb, 0x145892f5, 0x91584f7f,
166         0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4,
167         0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
168         0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3,
169         0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
170         0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
171         0xa345415e, 0x5c038323, 0x3e5d3bb9,
172         0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
173         0x73bfbe70, 0x83877605, 0x4523ecf1
174 };
175 static const u32 s3[256] = {
176         0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
177         0x369fe44b, 0x8c1fc644, 0xaececa90,
178         0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
179         0xf0ad0548, 0xe13c8d83, 0x927010d5,
180         0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
181         0xfade82e0, 0xa067268b, 0x8272792e,
182         0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
183         0x825b1bfd, 0x9255c5ed, 0x1257a240,
184         0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
185         0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
186         0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
187         0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
188         0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
189         0x4a012d6e, 0xc5884a28, 0xccc36f71,
190         0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
191         0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
192         0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
193         0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
194         0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
195         0x1eac5790, 0x796fb449, 0x8252dc15,
196         0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
197         0xe83ec305, 0x4f91751a, 0x925669c2,
198         0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
199         0x927985b2, 0x8276dbcb, 0x02778176,
200         0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
201         0x340ce5c8, 0x96bbb682, 0x93b4b148,
202         0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
203         0x8437aa88, 0x7d29dc96, 0x2756d3dc,
204         0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
205         0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
206         0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
207         0xbda8229c, 0x127dadaa, 0x438a074e,
208         0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
209         0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
210         0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
211         0x76a2e214, 0xb9a40368, 0x925d958f,
212         0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
213         0x193cbcfa, 0x27627545, 0x825cf47a,
214         0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
215         0x8272a972, 0x9270c4a8, 0x127de50b,
216         0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
217         0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
218         0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
219         0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
220         0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
221         0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
222         0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
223         0x7c34671c, 0x02717ef6, 0x4feb5536,
224         0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
225         0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
226         0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
227         0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
228         0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
229         0x856302e0, 0x72dbd92b, 0xee971b69,
230         0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
231         0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
232         0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
233         0x0ff0443d, 0x606e6dc6, 0x60543a49,
234         0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
235         0x68458425, 0x99833be5, 0x600d457d,
236         0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
237         0x9c305a00, 0x52bce688, 0x1b03588a,
238         0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
239         0xa133c501, 0xe9d3531c, 0xee353783
240 };
241 static const u32 s4[256] = {
242         0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
243         0x64ad8c57, 0x85510443, 0xfa020ed1,
244         0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
245         0x6497b7b1, 0xf3641f63, 0x241e4adf,
246         0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30,
247         0xc0a5374f, 0x1d2d00d9, 0x24147b15,
248         0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f,
249         0x0c13fefe, 0x081b08ca, 0x05170121,
250         0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f,
251         0x06df4261, 0xbb9e9b8a, 0x7293ea25,
252         0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
253         0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
254         0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061,
255         0x11b638e1, 0x72500e03, 0xf80eb2bb,
256         0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400,
257         0x6920318f, 0x081dbb99, 0xffc304a5,
258         0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea,
259         0x9f926f91, 0x9f46222f, 0x3991467d,
260         0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8,
261         0x3fb6180c, 0x18f8931e, 0x281658e6,
262         0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
263         0x79098b02, 0xe4eabb81, 0x28123b23,
264         0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9,
265         0x0014377b, 0x041e8ac8, 0x09114003,
266         0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de,
267         0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
268         0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0,
269         0x56c8c391, 0x6b65811c, 0x5e146119,
270         0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d,
271         0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
272         0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
273         0xeca1d7c7, 0x041afa32, 0x1d16625a,
274         0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb,
275         0xc70b8b46, 0xd9e66a48, 0x56e55a79,
276         0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3,
277         0xedda04eb, 0x17a9be04, 0x2c18f4df,
278         0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254,
279         0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
280         0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2,
281         0x0418f2c8, 0x001a96a6, 0x0d1526ab,
282         0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
283         0x311170a7, 0x3e9b640c, 0xcc3e10d7,
284         0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1,
285         0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
286         0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca,
287         0xb4be31cd, 0xd8782806, 0x12a3a4e2,
288         0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5,
289         0x9711aac5, 0x001d7b95, 0x82e5e7d2,
290         0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415,
291         0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
292         0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
293         0x0ce454a9, 0xd60acd86, 0x015f1919,
294         0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe,
295         0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
296         0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb,
297         0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
298         0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8,
299         0x296b299e, 0x492fc295, 0x9266beab,
300         0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee,
301         0xf65324e6, 0x6afce36c, 0x0316cc04,
302         0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
303         0x932bcdf6, 0xb657c34d, 0x4edfd282,
304         0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
305         0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
306 };
307 static const u32 s5[256] = {
308         0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff,
309         0x1dd358f5, 0x44dd9d44, 0x1731167f,
310         0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8,
311         0x386381cb, 0xacf6243a, 0x69befd7a,
312         0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640,
313         0x15b0a848, 0xe68b18cb, 0x4caadeff,
314         0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d,
315         0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
316         0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7,
317         0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
318         0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88,
319         0x8709e6b0, 0xd7e07156, 0x4e29fea7,
320         0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a,
321         0x578535f2, 0x2261be02, 0xd642a0c9,
322         0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8,
323         0xc8adedb3, 0x28a87fc9, 0x3d959981,
324         0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1,
325         0x4fb96976, 0x90c79505, 0xb0a8a774,
326         0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f,
327         0x0ec50966, 0xdfdd55bc, 0x29de0655,
328         0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980,
329         0x524755f4, 0x03b63cc9, 0x0cc844b2,
330         0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449,
331         0x64ee2d7e, 0xcddbb1da, 0x01c94910,
332         0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6,
333         0x50f5b616, 0xf24766e3, 0x8eca36c1,
334         0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9,
335         0x3063fcdf, 0xb6f589de, 0xec2941da,
336         0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401,
337         0xc1bacb7f, 0xe5ff550f, 0xb6083049,
338         0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd,
339         0x9e0885f9, 0x68cb3e47, 0x086c010f,
340         0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3,
341         0xcbb3d550, 0x1793084d, 0xb0d70eba,
342         0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56,
343         0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
344         0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280,
345         0x05687715, 0x646c6bd7, 0x44904db3,
346         0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f,
347         0x2cb6356a, 0x85808573, 0x4991f840,
348         0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8,
349         0xc1092910, 0x8bc95fc6, 0x7d869cf4,
350         0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717,
351         0x7d161bba, 0x9cad9010, 0xaf462ba2,
352         0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e,
353         0x176d486f, 0x097c13ea, 0x631da5c7,
354         0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72,
355         0x6e5dd2f3, 0x20936079, 0x459b80a5,
356         0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572,
357         0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
358         0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e,
359         0x75922283, 0x784d6b17, 0x58ebb16e,
360         0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf,
361         0xaaf47556, 0x5f46b02a, 0x2b092801,
362         0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874,
363         0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
364         0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826,
365         0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
366         0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9,
367         0x17e3fe2a, 0x24b79767, 0xf5a96b20,
368         0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a,
369         0xeeb9491d, 0x34010718, 0xbb30cab8,
370         0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8,
371         0xb1534546, 0x6d47de08, 0xefe9e7d4
372 };
373 static const u32 s6[256] = {
374         0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7,
375         0x016843b4, 0xeced5cbc, 0x325553ac,
376         0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8,
377         0xde5ebe39, 0xf38ff732, 0x8989b138,
378         0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99,
379         0x4e23e33c, 0x79cbd7cc, 0x48a14367,
380         0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d,
381         0x09a8486f, 0xa888614a, 0x2900af98,
382         0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932,
383         0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
384         0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c,
385         0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
386         0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01,
387         0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
388         0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c,
389         0xb88153e2, 0x08a19866, 0x1ae2eac8,
390         0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3,
391         0x9aea3906, 0xefe8c36e, 0xf890cdd9,
392         0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc,
393         0x221db3a6, 0x9a69a02f, 0x68818a54,
394         0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc,
395         0xcf222ebf, 0x25ac6f48, 0xa9a99387,
396         0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1,
397         0xe8a11be9, 0x4980740d, 0xc8087dfc,
398         0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f,
399         0x9528cd89, 0xfd339fed, 0xb87834bf,
400         0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa,
401         0x57f55ec5, 0xe2220abe, 0xd2916ebf,
402         0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff,
403         0xa8dc8af0, 0x7345c106, 0xf41e232f,
404         0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af,
405         0x692573e4, 0xe9a9d848, 0xf3160289,
406         0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063,
407         0x4576698d, 0xb6fad407, 0x592af950,
408         0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8,
409         0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
410         0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d,
411         0x48b9d585, 0xdc049441, 0xc8098f9b,
412         0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6,
413         0x890072d6, 0x28207682, 0xa9a9f7be,
414         0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a,
415         0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
416         0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a,
417         0xb6c85283, 0x3cc2acfb, 0x3fc06976,
418         0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0,
419         0x513021a5, 0x6c5b68b7, 0x822f8aa0,
420         0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9,
421         0x0c5ec241, 0x8809286c, 0xf592d891,
422         0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98,
423         0xb173ecc0, 0xbc60b42a, 0x953498da,
424         0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123,
425         0x257f0c3d, 0x9348af49, 0x361400bc,
426         0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57,
427         0xda41e7f9, 0xc25ad33a, 0x54f4a084,
428         0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5,
429         0xb6f6deaf, 0x3a479c3a, 0x5302da25,
430         0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88,
431         0x44136c76, 0x0404a8c8, 0xb8e5a121,
432         0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913,
433         0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
434         0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1,
435         0xf544edeb, 0xb0e93524, 0xbebb8fbd,
436         0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905,
437         0xa65b1db8, 0x851c97bd, 0xd675cf2f
438 };
439 static const u32 s7[256] = {
440         0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f,
441         0xab9bc912, 0xde6008a1, 0x2028da1f,
442         0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11,
443         0xb232e75c, 0x4b3695f2, 0xb28707de,
444         0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381,
445         0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
446         0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be,
447         0xbaeeadf4, 0x1286becf, 0xb6eacb19,
448         0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66,
449         0x28136086, 0x0bd8dfa8, 0x356d1cf2,
450         0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a,
451         0xeb12ff82, 0xe3486911, 0xd34d7516,
452         0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce,
453         0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
454         0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa,
455         0x4437f107, 0xb6e79962, 0x42d2d816,
456         0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7,
457         0xf9583745, 0xcf19df58, 0xbec3f756,
458         0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511,
459         0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
460         0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f,
461         0xaff60ff4, 0xea2c4e6d, 0x16e39264,
462         0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a,
463         0xb2856e6e, 0x1aec3ca9, 0xbe838688,
464         0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85,
465         0x61fe033c, 0x16746233, 0x3c034c28,
466         0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a,
467         0x1626a49f, 0xeed82b29, 0x1d382fe3,
468         0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c,
469         0xd45230c7, 0x2bd1408b, 0x60c03eb7,
470         0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32,
471         0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
472         0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f,
473         0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
474         0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0,
475         0x79d34217, 0x021a718d, 0x9ac6336a,
476         0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef,
477         0x4eeb8476, 0x488dcf25, 0x36c9d566,
478         0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6,
479         0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
480         0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887,
481         0x2b9f4fd5, 0x625aba82, 0x6a017962,
482         0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22,
483         0xe32dbf9a, 0x058745b9, 0x3453dc1e,
484         0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1,
485         0x19de7eae, 0x053e561a, 0x15ad6f8c,
486         0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0,
487         0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
488         0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108,
489         0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
490         0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f,
491         0x3d321c5d, 0xc3f5e194, 0x4b269301,
492         0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e,
493         0x296693f4, 0x3d1fce6f, 0xc61e45be,
494         0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d,
495         0xb5229301, 0xcfd2a87f, 0x60aeb767,
496         0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b,
497         0x589dd390, 0x5479f8e6, 0x1cb8d647,
498         0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad,
499         0x462e1b78, 0x6580f87e, 0xf3817914,
500         0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc,
501         0x3d40f021, 0xc3c0bdae, 0x4958c24c,
502         0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7,
503         0x94e01be8, 0x90716f4b, 0x954b8aa3
504 };
505 static const u32 sb8[256] = {
506         0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7,
507         0xe6c1121b, 0x0e241600, 0x052ce8b5,
508         0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c,
509         0x76e38111, 0xb12def3a, 0x37ddddfc,
510         0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f,
511         0xb4d137cf, 0xb44e79f0, 0x049eedfd,
512         0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831,
513         0x3f8f95e7, 0x72df191b, 0x7580330d,
514         0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a,
515         0x02e7d1ca, 0x53571dae, 0x7a3182a2,
516         0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022,
517         0xce949ad4, 0xb84769ad, 0x965bd862,
518         0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f,
519         0xc28ec4b8, 0x57e8726e, 0x647a78fc,
520         0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3,
521         0xae63aff2, 0x7e8bd632, 0x70108c0c,
522         0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53,
523         0x06918548, 0x58cb7e07, 0x3b74ef2e,
524         0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2,
525         0x19b47a38, 0x424f7618, 0x35856039,
526         0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd,
527         0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
528         0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c,
529         0x3dd00db3, 0x708f8f34, 0x77d51b42,
530         0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e,
531         0x3e378160, 0x7895cda5, 0x859c15a5,
532         0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e,
533         0x31842e7b, 0x24259fd7, 0xf8bef472,
534         0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c,
535         0xe2506d3d, 0x4f9b12ea, 0xf215f225,
536         0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187,
537         0xea7a6e98, 0x7cd16efc, 0x1436876c,
538         0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899,
539         0x92ecbae6, 0xdd67016d, 0x151682eb,
540         0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e,
541         0xe139673b, 0xefa63fb8, 0x71873054,
542         0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d,
543         0x844a1be5, 0xbae7dfdc, 0x42cbda70,
544         0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428,
545         0x79d130a4, 0x3486ebfb, 0x33d3cddc,
546         0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4,
547         0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
548         0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2,
549         0x37df932b, 0xc4248289, 0xacf3ebc3,
550         0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e,
551         0x5e410fab, 0xb48a2465, 0x2eda7fa4,
552         0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b,
553         0xdb485694, 0x38d7e5b2, 0x57720101,
554         0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282,
555         0x7523d24a, 0xe0779695, 0xf9c17a8f,
556         0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f,
557         0xad1163ed, 0xea7b5965, 0x1a00726e,
558         0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0,
559         0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
560         0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca,
561         0x8951570f, 0xdf09822b, 0xbd691a6c,
562         0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f,
563         0x0d771c2b, 0x67cdb156, 0x350d8384,
564         0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61,
565         0x8360d87b, 0x1fa98b0c, 0x1149382c,
566         0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82,
567         0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
568         0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80,
569         0xeaee6801, 0x8db2a283, 0xea8bf59e
570 };
571
572 #define F1(D, m, r)  ((I = ((m) + (D))), (I = rol32(I, (r))),   \
573     (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
574 #define F2(D, m, r)  ((I = ((m) ^ (D))), (I = rol32(I, (r))),   \
575     (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
576 #define F3(D, m, r)  ((I = ((m) - (D))), (I = rol32(I, (r))),   \
577     (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
578
579
580 static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
581 {
582         struct cast5_ctx *c = crypto_tfm_ctx(tfm);
583         const __be32 *src = (const __be32 *)inbuf;
584         __be32 *dst = (__be32 *)outbuf;
585         u32 l, r, t;
586         u32 I;                  /* used by the Fx macros */
587         u32 *Km;
588         u8 *Kr;
589
590         Km = c->Km;
591         Kr = c->Kr;
592
593         /* (L0,R0) <-- (m1...m64).  (Split the plaintext into left and
594          * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
595          */
596         l = be32_to_cpu(src[0]);
597         r = be32_to_cpu(src[1]);
598
599         /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
600          *  Li = Ri-1;
601          *  Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
602          * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
603          * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
604          * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
605          */
606
607         t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
608         t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
609         t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
610         t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
611         t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
612         t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
613         t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
614         t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
615         t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
616         t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
617         t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
618         t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
619         if (!(c->rr)) {
620                 t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
621                 t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
622                 t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
623                 t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
624         }
625
626         /* c1...c64 <-- (R16,L16).  (Exchange final blocks L16, R16 and
627          *  concatenate to form the ciphertext.) */
628         dst[0] = cpu_to_be32(r);
629         dst[1] = cpu_to_be32(l);
630 }
631
632 static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
633 {
634         struct cast5_ctx *c = crypto_tfm_ctx(tfm);
635         const __be32 *src = (const __be32 *)inbuf;
636         __be32 *dst = (__be32 *)outbuf;
637         u32 l, r, t;
638         u32 I;
639         u32 *Km;
640         u8 *Kr;
641
642         Km = c->Km;
643         Kr = c->Kr;
644
645         l = be32_to_cpu(src[0]);
646         r = be32_to_cpu(src[1]);
647
648         if (!(c->rr)) {
649                 t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
650                 t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
651                 t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
652                 t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
653         }
654         t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
655         t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
656         t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
657         t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
658         t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
659         t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
660         t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
661         t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
662         t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
663         t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
664         t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
665         t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
666
667         dst[0] = cpu_to_be32(r);
668         dst[1] = cpu_to_be32(l);
669 }
670
671 static void key_schedule(u32 *x, u32 *z, u32 *k)
672 {
673
674 #define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
675 #define zi(i)   ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
676
677         z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^
678             s7[xi(8)];
679         z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^
680             sb8[xi(10)];
681         z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
682             s5[xi(9)];
683         z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^
684             s6[xi(11)];
685         k[0] = s5[zi(8)] ^ s6[zi(9)] ^ s7[zi(7)] ^ sb8[zi(6)] ^ s5[zi(2)];
686         k[1] = s5[zi(10)] ^ s6[zi(11)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
687             s6[zi(6)];
688         k[2] = s5[zi(12)] ^ s6[zi(13)] ^ s7[zi(3)] ^ sb8[zi(2)] ^
689             s7[zi(9)];
690         k[3] = s5[zi(14)] ^ s6[zi(15)] ^ s7[zi(1)] ^ sb8[zi(0)] ^
691             sb8[zi(12)];
692
693         x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^
694             s7[zi(0)];
695         x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^
696             sb8[zi(2)];
697         x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
698             s5[zi(1)];
699         x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^
700             s6[zi(3)];
701         k[4] = s5[xi(3)] ^ s6[xi(2)] ^ s7[xi(12)] ^ sb8[xi(13)] ^
702             s5[xi(8)];
703         k[5] = s5[xi(1)] ^ s6[xi(0)] ^ s7[xi(14)] ^ sb8[xi(15)] ^
704             s6[xi(13)];
705         k[6] = s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(8)] ^ sb8[xi(9)] ^ s7[xi(3)];
706         k[7] = s5[xi(5)] ^ s6[xi(4)] ^ s7[xi(10)] ^ sb8[xi(11)] ^
707             sb8[xi(7)];
708
709         z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^
710             s7[xi(8)];
711         z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^
712             sb8[xi(10)];
713         z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
714             s5[xi(9)];
715         z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^
716             s6[xi(11)];
717         k[8] = s5[zi(3)] ^ s6[zi(2)] ^ s7[zi(12)] ^ sb8[zi(13)] ^
718             s5[zi(9)];
719         k[9] = s5[zi(1)] ^ s6[zi(0)] ^ s7[zi(14)] ^ sb8[zi(15)] ^
720             s6[zi(12)];
721         k[10] = s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(8)] ^ sb8[zi(9)] ^ s7[zi(2)];
722         k[11] = s5[zi(5)] ^ s6[zi(4)] ^ s7[zi(10)] ^ sb8[zi(11)] ^
723             sb8[zi(6)];
724
725         x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^
726             s7[zi(0)];
727         x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^
728             sb8[zi(2)];
729         x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
730             s5[zi(1)];
731         x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^
732             s6[zi(3)];
733         k[12] = s5[xi(8)] ^ s6[xi(9)] ^ s7[xi(7)] ^ sb8[xi(6)] ^ s5[xi(3)];
734         k[13] = s5[xi(10)] ^ s6[xi(11)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
735             s6[xi(7)];
736         k[14] = s5[xi(12)] ^ s6[xi(13)] ^ s7[xi(3)] ^ sb8[xi(2)] ^
737             s7[xi(8)];
738         k[15] = s5[xi(14)] ^ s6[xi(15)] ^ s7[xi(1)] ^ sb8[xi(0)] ^
739             sb8[xi(13)];
740
741 #undef xi
742 #undef zi
743 }
744
745
746 static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned key_len)
747 {
748         struct cast5_ctx *c = crypto_tfm_ctx(tfm);
749         int i;
750         u32 x[4];
751         u32 z[4];
752         u32 k[16];
753         __be32 p_key[4];
754
755         c->rr = key_len <= 10 ? 1 : 0;
756
757         memset(p_key, 0, 16);
758         memcpy(p_key, key, key_len);
759
760
761         x[0] = be32_to_cpu(p_key[0]);
762         x[1] = be32_to_cpu(p_key[1]);
763         x[2] = be32_to_cpu(p_key[2]);
764         x[3] = be32_to_cpu(p_key[3]);
765
766         key_schedule(x, z, k);
767         for (i = 0; i < 16; i++)
768                 c->Km[i] = k[i];
769         key_schedule(x, z, k);
770         for (i = 0; i < 16; i++)
771                 c->Kr[i] = k[i] & 0x1f;
772         return 0;
773 }
774
775 static struct crypto_alg alg = {
776         .cra_name       = "cast5",
777         .cra_flags      = CRYPTO_ALG_TYPE_CIPHER,
778         .cra_blocksize  = CAST5_BLOCK_SIZE,
779         .cra_ctxsize    = sizeof(struct cast5_ctx),
780         .cra_alignmask  = 3,
781         .cra_module     = THIS_MODULE,
782         .cra_list       = LIST_HEAD_INIT(alg.cra_list),
783         .cra_u          = {
784                 .cipher = {
785                         .cia_min_keysize = CAST5_MIN_KEY_SIZE,
786                         .cia_max_keysize = CAST5_MAX_KEY_SIZE,
787                         .cia_setkey = cast5_setkey,
788                         .cia_encrypt = cast5_encrypt,
789                         .cia_decrypt = cast5_decrypt
790                 }
791         }
792 };
793
794 static int __init cast5_mod_init(void)
795 {
796         return crypto_register_alg(&alg);
797 }
798
799 static void __exit cast5_mod_fini(void)
800 {
801         crypto_unregister_alg(&alg);
802 }
803
804 module_init(cast5_mod_init);
805 module_exit(cast5_mod_fini);
806
807 MODULE_LICENSE("GPL");
808 MODULE_DESCRIPTION("Cast5 Cipher Algorithm");
809