blob: 08eef58c1d3dd2328cc8819537f37df06f202cfc [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 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
Herbert Xu06ace7a2005-10-30 21:25:15 +110024#include <asm/byteorder.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/init.h>
26#include <linux/crypto.h>
27#include <linux/module.h>
28#include <linux/errno.h>
29#include <linux/string.h>
Herbert Xu06ace7a2005-10-30 21:25:15 +110030#include <linux/types.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
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
Herbert Xu6c2bb982006-05-16 22:09:29 +1000580static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000582 struct cast5_ctx *c = crypto_tfm_ctx(tfm);
Herbert Xu06ace7a2005-10-30 21:25:15 +1100583 const __be32 *src = (const __be32 *)inbuf;
584 __be32 *dst = (__be32 *)outbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 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 */
Herbert Xu06ace7a2005-10-30 21:25:15 +1100596 l = be32_to_cpu(src[0]);
597 r = be32_to_cpu(src[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
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.) */
Herbert Xu06ace7a2005-10-30 21:25:15 +1100641 dst[0] = cpu_to_be32(r);
642 dst[1] = cpu_to_be32(l);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643}
644
Herbert Xu6c2bb982006-05-16 22:09:29 +1000645static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000647 struct cast5_ctx *c = crypto_tfm_ctx(tfm);
Herbert Xu06ace7a2005-10-30 21:25:15 +1100648 const __be32 *src = (const __be32 *)inbuf;
649 __be32 *dst = (__be32 *)outbuf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 u32 l, r, t;
651 u32 I;
652 u32 *Km;
653 u8 *Kr;
654
655 Km = c->Km;
656 Kr = c->Kr;
657
Herbert Xu06ace7a2005-10-30 21:25:15 +1100658 l = be32_to_cpu(src[0]);
659 r = be32_to_cpu(src[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
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
Herbert Xu06ace7a2005-10-30 21:25:15 +1100693 dst[0] = cpu_to_be32(r);
694 dst[1] = cpu_to_be32(l);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695}
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
Herbert Xu6c2bb982006-05-16 22:09:29 +1000772static int cast5_setkey(struct crypto_tfm *tfm, const u8 *key,
773 unsigned key_len, u32 *flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774{
Herbert Xu6c2bb982006-05-16 22:09:29 +1000775 struct cast5_ctx *c = crypto_tfm_ctx(tfm);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 int i;
777 u32 x[4];
778 u32 z[4];
779 u32 k[16];
Herbert Xu06ace7a2005-10-30 21:25:15 +1100780 __be32 p_key[4];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
782 if (key_len < 5 || key_len > 16) {
783 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
784 return -EINVAL;
785 }
786
787 c->rr = key_len <= 10 ? 1 : 0;
788
789 memset(p_key, 0, 16);
790 memcpy(p_key, key, key_len);
791
792
Herbert Xu06ace7a2005-10-30 21:25:15 +1100793 x[0] = be32_to_cpu(p_key[0]);
794 x[1] = be32_to_cpu(p_key[1]);
795 x[2] = be32_to_cpu(p_key[2]);
796 x[3] = be32_to_cpu(p_key[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
798 key_schedule(x, z, k);
799 for (i = 0; i < 16; i++)
800 c->Km[i] = k[i];
801 key_schedule(x, z, k);
802 for (i = 0; i < 16; i++)
803 c->Kr[i] = k[i] & 0x1f;
804 return 0;
805}
806
807static struct crypto_alg alg = {
808 .cra_name = "cast5",
809 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
810 .cra_blocksize = CAST5_BLOCK_SIZE,
811 .cra_ctxsize = sizeof(struct cast5_ctx),
Herbert Xua429d262006-01-07 16:38:15 +1100812 .cra_alignmask = 3,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 .cra_module = THIS_MODULE,
814 .cra_list = LIST_HEAD_INIT(alg.cra_list),
815 .cra_u = {
816 .cipher = {
817 .cia_min_keysize = CAST5_MIN_KEY_SIZE,
818 .cia_max_keysize = CAST5_MAX_KEY_SIZE,
819 .cia_setkey = cast5_setkey,
820 .cia_encrypt = cast5_encrypt,
821 .cia_decrypt = cast5_decrypt
822 }
823 }
824};
825
826static int __init init(void)
827{
828 return crypto_register_alg(&alg);
829}
830
831static void __exit fini(void)
832{
833 crypto_unregister_alg(&alg);
834}
835
836module_init(init);
837module_exit(fini);
838
839MODULE_LICENSE("GPL");
840MODULE_DESCRIPTION("Cast5 Cipher Algorithm");
841