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
36struct 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
43static 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};
109static 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};
175static 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};
241static 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};
307static 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};
373static 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};
439static 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};
505static 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
580static 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	if (!(c->rr)) {
608		t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
609		t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
610		t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
611		t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
612		t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
613		t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
614		t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
615		t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
616		t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
617		t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
618		t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
619		t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
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	} else {
625		t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
626		t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
627		t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
628		t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
629		t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
630		t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
631		t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
632		t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
633		t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
634		t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
635		t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
636		t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
637	}
638
639	/* c1...c64 <-- (R16,L16).  (Exchange final blocks L16, R16 and
640	 *  concatenate to form the ciphertext.) */
641	dst[0] = cpu_to_be32(r);
642	dst[1] = cpu_to_be32(l);
643}
644
645static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
646{
647	struct cast5_ctx *c = crypto_tfm_ctx(tfm);
648	const __be32 *src = (const __be32 *)inbuf;
649	__be32 *dst = (__be32 *)outbuf;
650	u32 l, r, t;
651	u32 I;
652	u32 *Km;
653	u8 *Kr;
654
655	Km = c->Km;
656	Kr = c->Kr;
657
658	l = be32_to_cpu(src[0]);
659	r = be32_to_cpu(src[1]);
660
661	if (!(c->rr)) {
662		t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
663		t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
664		t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
665		t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
666		t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
667		t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
668		t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
669		t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
670		t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
671		t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
672		t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
673		t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
674		t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
675		t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
676		t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
677		t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
678	} else {
679		t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
680		t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
681		t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]);
682		t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]);
683		t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]);
684		t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]);
685		t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]);
686		t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]);
687		t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]);
688		t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]);
689		t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
690		t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
691	}
692
693	dst[0] = cpu_to_be32(r);
694	dst[1] = cpu_to_be32(l);
695}
696
697static void key_schedule(u32 * x, u32 * z, u32 * k)
698{
699
700#define xi(i)   ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
701#define zi(i)   ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
702
703	z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^
704	    s7[xi(8)];
705	z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^
706	    sb8[xi(10)];
707	z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
708	    s5[xi(9)];
709	z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^
710	    s6[xi(11)];
711	k[0] = s5[zi(8)] ^ s6[zi(9)] ^ s7[zi(7)] ^ sb8[zi(6)] ^ s5[zi(2)];
712	k[1] = s5[zi(10)] ^ s6[zi(11)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
713	    s6[zi(6)];
714	k[2] = s5[zi(12)] ^ s6[zi(13)] ^ s7[zi(3)] ^ sb8[zi(2)] ^
715	    s7[zi(9)];
716	k[3] = s5[zi(14)] ^ s6[zi(15)] ^ s7[zi(1)] ^ sb8[zi(0)] ^
717	    sb8[zi(12)];
718
719	x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^
720	    s7[zi(0)];
721	x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^
722	    sb8[zi(2)];
723	x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
724	    s5[zi(1)];
725	x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^
726	    s6[zi(3)];
727	k[4] = s5[xi(3)] ^ s6[xi(2)] ^ s7[xi(12)] ^ sb8[xi(13)] ^
728	    s5[xi(8)];
729	k[5] = s5[xi(1)] ^ s6[xi(0)] ^ s7[xi(14)] ^ sb8[xi(15)] ^
730	    s6[xi(13)];
731	k[6] = s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(8)] ^ sb8[xi(9)] ^ s7[xi(3)];
732	k[7] = s5[xi(5)] ^ s6[xi(4)] ^ s7[xi(10)] ^ sb8[xi(11)] ^
733	    sb8[xi(7)];
734
735	z[0] = x[0] ^ s5[xi(13)] ^ s6[xi(15)] ^ s7[xi(12)] ^ sb8[xi(14)] ^
736	    s7[xi(8)];
737	z[1] = x[2] ^ s5[zi(0)] ^ s6[zi(2)] ^ s7[zi(1)] ^ sb8[zi(3)] ^
738	    sb8[xi(10)];
739	z[2] = x[3] ^ s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(5)] ^ sb8[zi(4)] ^
740	    s5[xi(9)];
741	z[3] = x[1] ^ s5[zi(10)] ^ s6[zi(9)] ^ s7[zi(11)] ^ sb8[zi(8)] ^
742	    s6[xi(11)];
743	k[8] = s5[zi(3)] ^ s6[zi(2)] ^ s7[zi(12)] ^ sb8[zi(13)] ^
744	    s5[zi(9)];
745	k[9] = s5[zi(1)] ^ s6[zi(0)] ^ s7[zi(14)] ^ sb8[zi(15)] ^
746	    s6[zi(12)];
747	k[10] = s5[zi(7)] ^ s6[zi(6)] ^ s7[zi(8)] ^ sb8[zi(9)] ^ s7[zi(2)];
748	k[11] = s5[zi(5)] ^ s6[zi(4)] ^ s7[zi(10)] ^ sb8[zi(11)] ^
749	    sb8[zi(6)];
750
751	x[0] = z[2] ^ s5[zi(5)] ^ s6[zi(7)] ^ s7[zi(4)] ^ sb8[zi(6)] ^
752	    s7[zi(0)];
753	x[1] = z[0] ^ s5[xi(0)] ^ s6[xi(2)] ^ s7[xi(1)] ^ sb8[xi(3)] ^
754	    sb8[zi(2)];
755	x[2] = z[1] ^ s5[xi(7)] ^ s6[xi(6)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
756	    s5[zi(1)];
757	x[3] = z[3] ^ s5[xi(10)] ^ s6[xi(9)] ^ s7[xi(11)] ^ sb8[xi(8)] ^
758	    s6[zi(3)];
759	k[12] = s5[xi(8)] ^ s6[xi(9)] ^ s7[xi(7)] ^ sb8[xi(6)] ^ s5[xi(3)];
760	k[13] = s5[xi(10)] ^ s6[xi(11)] ^ s7[xi(5)] ^ sb8[xi(4)] ^
761	    s6[xi(7)];
762	k[14] = s5[xi(12)] ^ s6[xi(13)] ^ s7[xi(3)] ^ sb8[xi(2)] ^
763	    s7[xi(8)];
764	k[15] = s5[xi(14)] ^ s6[xi(15)] ^ s7[xi(1)] ^ sb8[xi(0)] ^
765	    sb8[xi(13)];
766
767#undef xi
768#undef zi
769}
770
771
772static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned key_len)
773{
774	struct cast5_ctx *c = crypto_tfm_ctx(tfm);
775	int i;
776	u32 x[4];
777	u32 z[4];
778	u32 k[16];
779	__be32 p_key[4];
780
781	c->rr = key_len <= 10 ? 1 : 0;
782
783	memset(p_key, 0, 16);
784	memcpy(p_key, key, key_len);
785
786
787	x[0] = be32_to_cpu(p_key[0]);
788	x[1] = be32_to_cpu(p_key[1]);
789	x[2] = be32_to_cpu(p_key[2]);
790	x[3] = be32_to_cpu(p_key[3]);
791
792	key_schedule(x, z, k);
793	for (i = 0; i < 16; i++)
794		c->Km[i] = k[i];
795	key_schedule(x, z, k);
796	for (i = 0; i < 16; i++)
797		c->Kr[i] = k[i] & 0x1f;
798	return 0;
799}
800
801static struct crypto_alg alg = {
802	.cra_name 	= "cast5",
803	.cra_flags 	= CRYPTO_ALG_TYPE_CIPHER,
804	.cra_blocksize 	= CAST5_BLOCK_SIZE,
805	.cra_ctxsize 	= sizeof(struct cast5_ctx),
806	.cra_alignmask	= 3,
807	.cra_module 	= THIS_MODULE,
808	.cra_list 	= LIST_HEAD_INIT(alg.cra_list),
809	.cra_u 		= {
810		.cipher = {
811			.cia_min_keysize = CAST5_MIN_KEY_SIZE,
812			.cia_max_keysize = CAST5_MAX_KEY_SIZE,
813			.cia_setkey = cast5_setkey,
814			.cia_encrypt = cast5_encrypt,
815			.cia_decrypt = cast5_decrypt
816		}
817	}
818};
819
820static int __init init(void)
821{
822	return crypto_register_alg(&alg);
823}
824
825static void __exit fini(void)
826{
827	crypto_unregister_alg(&alg);
828}
829
830module_init(init);
831module_exit(fini);
832
833MODULE_LICENSE("GPL");
834MODULE_DESCRIPTION("Cast5 Cipher Algorithm");
835