xref: /openbmc/linux/crypto/cast6_generic.c (revision 05bcf503)
1 /* Kernel cryptographic api.
2  * cast6.c - Cast6 cipher algorithm [rfc2612].
3  *
4  * CAST-256 (*cast6*) is a DES like Substitution-Permutation Network (SPN)
5  * cryptosystem built upon the CAST-128 (*cast5*) [rfc2144] encryption
6  * algorithm.
7  *
8  * Copyright (C) 2003 Kartikey Mahendra Bhatt <kartik_me@hotmail.com>.
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms of GNU General Public License as published by the Free
12  * Software Foundation; either version 2 of the License, or (at your option)
13  * any later version.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18  */
19 
20 
21 #include <asm/byteorder.h>
22 #include <linux/init.h>
23 #include <linux/crypto.h>
24 #include <linux/module.h>
25 #include <linux/errno.h>
26 #include <linux/string.h>
27 #include <linux/types.h>
28 #include <crypto/cast6.h>
29 
30 #define s1 cast6_s1
31 #define s2 cast6_s2
32 #define s3 cast6_s3
33 #define s4 cast6_s4
34 
35 #define F1(D, r, m)  ((I = ((m) + (D))), (I = rol32(I, (r))),   \
36 	(((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]))
37 #define F2(D, r, m)  ((I = ((m) ^ (D))), (I = rol32(I, (r))),   \
38 	(((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]))
39 #define F3(D, r, m)  ((I = ((m) - (D))), (I = rol32(I, (r))),   \
40 	(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]))
41 
42 const u32 cast6_s1[256] = {
43 	0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
44 	0x9c004dd3, 0x6003e540, 0xcf9fc949,
45 	0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
46 	0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
47 	0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3,
48 	0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
49 	0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1,
50 	0xaa54166b, 0x22568e3a, 0xa2d341d0,
51 	0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac,
52 	0x4a97c1d8, 0x527644b7, 0xb5f437a7,
53 	0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
54 	0x90ecf52e, 0x22b0c054, 0xbc8e5935,
55 	0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290,
56 	0xe93b159f, 0xb48ee411, 0x4bff345d,
57 	0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad,
58 	0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
59 	0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
60 	0xc59c5319, 0xb949e354, 0xb04669fe,
61 	0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5,
62 	0x6a390493, 0xe63d37e0, 0x2a54f6b3,
63 	0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
64 	0xf61b1891, 0xbb72275e, 0xaa508167,
65 	0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
66 	0xa2d1936b, 0x2ad286af, 0xaa56d291,
67 	0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d,
68 	0x73e2bb14, 0xa0bebc3c, 0x54623779,
69 	0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e,
70 	0x89fe78e6, 0x3fab0950, 0x325ff6c2,
71 	0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf,
72 	0x380782d5, 0xc7fa5cf6, 0x8ac31511,
73 	0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
74 	0x051ef495, 0xaa573b04, 0x4a805d8d,
75 	0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b,
76 	0x50afd341, 0xa7c13275, 0x915a0bf5,
77 	0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
78 	0xab85c5f3, 0x1b55db94, 0xaad4e324,
79 	0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3,
80 	0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
81 	0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6,
82 	0x22513f1e, 0xaa51a79b, 0x2ad344cc,
83 	0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
84 	0x032268d4, 0xc9600acc, 0xce387e6d,
85 	0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da,
86 	0x4736f464, 0x5ad328d8, 0xb347cc96,
87 	0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc,
88 	0xbfc5fe4a, 0xa70aec10, 0xac39570a,
89 	0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f,
90 	0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
91 	0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4,
92 	0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
93 	0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
94 	0x51c85f4d, 0x56907596, 0xa5bb15e6,
95 	0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
96 	0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
97 	0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf,
98 	0x700b45e1, 0xd5ea50f1, 0x85a92872,
99 	0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198,
100 	0x0cd0ede7, 0x26470db8, 0xf881814c,
101 	0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db,
102 	0xab838653, 0x6e2f1e23, 0x83719c9e,
103 	0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
104 	0xe1e696ff, 0xb141ab08, 0x7cca89b9,
105 	0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
106 	0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
107 };
108 EXPORT_SYMBOL_GPL(cast6_s1);
109 
110 const u32 cast6_s2[256] = {
111 	0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
112 	0xeec5207a, 0x55889c94, 0x72fc0651,
113 	0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
114 	0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
115 	0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086,
116 	0xef944459, 0xba83ccb3, 0xe0c3cdfb,
117 	0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb,
118 	0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
119 	0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f,
120 	0x77e83f4e, 0x79929269, 0x24fa9f7b,
121 	0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
122 	0x0d554b63, 0x5d681121, 0xc866c359,
123 	0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181,
124 	0x39f7627f, 0x361e3084, 0xe4eb573b,
125 	0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c,
126 	0x99847ab4, 0xa0e3df79, 0xba6cf38c,
127 	0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a,
128 	0x8f458c74, 0xd9e0a227, 0x4ec73a34,
129 	0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c,
130 	0x1d804366, 0x721d9bfd, 0xa58684bb,
131 	0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
132 	0x27e19ba5, 0xd5a6c252, 0xe49754bd,
133 	0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9,
134 	0xe0b56714, 0x21f043b7, 0xe5d05860,
135 	0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf,
136 	0x68561be6, 0x83ca6b94, 0x2d6ed23b,
137 	0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c,
138 	0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
139 	0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122,
140 	0xb96726d1, 0x8049a7e8, 0x22b7da7b,
141 	0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
142 	0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
143 	0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53,
144 	0xe3214517, 0xb4542835, 0x9f63293c,
145 	0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6,
146 	0x30a22c95, 0x31a70850, 0x60930f13,
147 	0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6,
148 	0xa02b1741, 0x7cbad9a2, 0x2180036f,
149 	0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676,
150 	0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
151 	0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
152 	0x846a3bae, 0x8ff77888, 0xee5d60f6,
153 	0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54,
154 	0x157fd7fa, 0xef8579cc, 0xd152de58,
155 	0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5,
156 	0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
157 	0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8,
158 	0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
159 	0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc,
160 	0x301e16e6, 0x273be979, 0xb0ffeaa6,
161 	0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
162 	0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
163 	0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e,
164 	0x1a513742, 0xef6828bc, 0x520365d6,
165 	0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb,
166 	0x5eea29cb, 0x145892f5, 0x91584f7f,
167 	0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4,
168 	0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
169 	0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3,
170 	0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
171 	0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
172 	0xa345415e, 0x5c038323, 0x3e5d3bb9,
173 	0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
174 	0x73bfbe70, 0x83877605, 0x4523ecf1
175 };
176 EXPORT_SYMBOL_GPL(cast6_s2);
177 
178 const u32 cast6_s3[256] = {
179 	0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
180 	0x369fe44b, 0x8c1fc644, 0xaececa90,
181 	0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
182 	0xf0ad0548, 0xe13c8d83, 0x927010d5,
183 	0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
184 	0xfade82e0, 0xa067268b, 0x8272792e,
185 	0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
186 	0x825b1bfd, 0x9255c5ed, 0x1257a240,
187 	0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
188 	0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
189 	0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
190 	0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
191 	0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
192 	0x4a012d6e, 0xc5884a28, 0xccc36f71,
193 	0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
194 	0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
195 	0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
196 	0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
197 	0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
198 	0x1eac5790, 0x796fb449, 0x8252dc15,
199 	0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
200 	0xe83ec305, 0x4f91751a, 0x925669c2,
201 	0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
202 	0x927985b2, 0x8276dbcb, 0x02778176,
203 	0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
204 	0x340ce5c8, 0x96bbb682, 0x93b4b148,
205 	0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
206 	0x8437aa88, 0x7d29dc96, 0x2756d3dc,
207 	0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
208 	0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
209 	0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
210 	0xbda8229c, 0x127dadaa, 0x438a074e,
211 	0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
212 	0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
213 	0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
214 	0x76a2e214, 0xb9a40368, 0x925d958f,
215 	0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
216 	0x193cbcfa, 0x27627545, 0x825cf47a,
217 	0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
218 	0x8272a972, 0x9270c4a8, 0x127de50b,
219 	0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
220 	0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
221 	0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
222 	0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
223 	0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
224 	0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
225 	0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
226 	0x7c34671c, 0x02717ef6, 0x4feb5536,
227 	0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
228 	0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
229 	0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
230 	0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
231 	0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
232 	0x856302e0, 0x72dbd92b, 0xee971b69,
233 	0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
234 	0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
235 	0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
236 	0x0ff0443d, 0x606e6dc6, 0x60543a49,
237 	0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
238 	0x68458425, 0x99833be5, 0x600d457d,
239 	0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
240 	0x9c305a00, 0x52bce688, 0x1b03588a,
241 	0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
242 	0xa133c501, 0xe9d3531c, 0xee353783
243 };
244 EXPORT_SYMBOL_GPL(cast6_s3);
245 
246 const u32 cast6_s4[256] = {
247 	0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
248 	0x64ad8c57, 0x85510443, 0xfa020ed1,
249 	0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
250 	0x6497b7b1, 0xf3641f63, 0x241e4adf,
251 	0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30,
252 	0xc0a5374f, 0x1d2d00d9, 0x24147b15,
253 	0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f,
254 	0x0c13fefe, 0x081b08ca, 0x05170121,
255 	0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f,
256 	0x06df4261, 0xbb9e9b8a, 0x7293ea25,
257 	0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
258 	0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
259 	0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061,
260 	0x11b638e1, 0x72500e03, 0xf80eb2bb,
261 	0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400,
262 	0x6920318f, 0x081dbb99, 0xffc304a5,
263 	0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea,
264 	0x9f926f91, 0x9f46222f, 0x3991467d,
265 	0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8,
266 	0x3fb6180c, 0x18f8931e, 0x281658e6,
267 	0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
268 	0x79098b02, 0xe4eabb81, 0x28123b23,
269 	0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9,
270 	0x0014377b, 0x041e8ac8, 0x09114003,
271 	0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de,
272 	0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
273 	0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0,
274 	0x56c8c391, 0x6b65811c, 0x5e146119,
275 	0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d,
276 	0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
277 	0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
278 	0xeca1d7c7, 0x041afa32, 0x1d16625a,
279 	0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb,
280 	0xc70b8b46, 0xd9e66a48, 0x56e55a79,
281 	0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3,
282 	0xedda04eb, 0x17a9be04, 0x2c18f4df,
283 	0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254,
284 	0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
285 	0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2,
286 	0x0418f2c8, 0x001a96a6, 0x0d1526ab,
287 	0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
288 	0x311170a7, 0x3e9b640c, 0xcc3e10d7,
289 	0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1,
290 	0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
291 	0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca,
292 	0xb4be31cd, 0xd8782806, 0x12a3a4e2,
293 	0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5,
294 	0x9711aac5, 0x001d7b95, 0x82e5e7d2,
295 	0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415,
296 	0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
297 	0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
298 	0x0ce454a9, 0xd60acd86, 0x015f1919,
299 	0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe,
300 	0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
301 	0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb,
302 	0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
303 	0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8,
304 	0x296b299e, 0x492fc295, 0x9266beab,
305 	0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee,
306 	0xf65324e6, 0x6afce36c, 0x0316cc04,
307 	0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
308 	0x932bcdf6, 0xb657c34d, 0x4edfd282,
309 	0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
310 	0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
311 };
312 EXPORT_SYMBOL_GPL(cast6_s4);
313 
314 static const u32 Tm[24][8] = {
315 	{ 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
316 		0x84c413be, 0xf39dff5f, 0x6277eb00 } ,
317 	{ 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525,
318 		0xfb9370c6, 0x6a6d5c67, 0xd9474808 } ,
319 	{ 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d,
320 		0x7262cdce, 0xe13cb96f, 0x5016a510 } ,
321 	{ 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35,
322 		0xe9322ad6, 0x580c1677, 0xc6e60218 } ,
323 	{ 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d,
324 		0x600187de, 0xcedb737f, 0x3db55f20 } ,
325 	{ 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945,
326 		0xd6d0e4e6, 0x45aad087, 0xb484bc28 } ,
327 	{ 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d,
328 		0x4da041ee, 0xbc7a2d8f, 0x2b541930 } ,
329 	{ 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355,
330 		0xc46f9ef6, 0x33498a97, 0xa2237638 } ,
331 	{ 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d,
332 		0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } ,
333 	{ 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65,
334 		0xb20e5906, 0x20e844a7, 0x8fc23048 } ,
335 	{ 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d,
336 		0x28ddb60e, 0x97b7a1af, 0x06918d50 } ,
337 	{ 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775,
338 		0x9fad1316, 0x0e86feb7, 0x7d60ea58 } ,
339 	{ 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d,
340 		0x167c701e, 0x85565bbf, 0xf4304760 } ,
341 	{ 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185,
342 		0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } ,
343 	{ 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d,
344 		0x041b2a2e, 0x72f515cf, 0xe1cf0170 } ,
345 	{ 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95,
346 		0x7aea8736, 0xe9c472d7, 0x589e5e78 } ,
347 	{ 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d,
348 		0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } ,
349 	{ 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5,
350 		0x68894146, 0xd7632ce7, 0x463d1888 } ,
351 	{ 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad,
352 		0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } ,
353 	{ 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5,
354 		0x5627fb56, 0xc501e6f7, 0x33dbd298 } ,
355 	{ 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd,
356 		0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } ,
357 	{ 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5,
358 		0x43c6b566, 0xb2a0a107, 0x217a8ca8 } ,
359 	{ 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd,
360 		0xba96126e, 0x296ffe0f, 0x9849e9b0 } ,
361 	{ 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5,
362 		0x31656f76, 0xa03f5b17, 0x0f1946b8 }
363 };
364 
365 static const u8 Tr[4][8] = {
366 	{ 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } ,
367 	{ 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } ,
368 	{ 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } ,
369 	{ 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 }
370 };
371 
372 /* forward octave */
373 static inline void W(u32 *key, unsigned int i)
374 {
375 	u32 I;
376 	key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
377 	key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
378 	key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]);
379 	key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]);
380 	key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]);
381 	key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]);
382 	key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);
383 	key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
384 }
385 
386 int __cast6_setkey(struct cast6_ctx *c, const u8 *in_key,
387 		   unsigned key_len, u32 *flags)
388 {
389 	int i;
390 	u32 key[8];
391 	__be32 p_key[8]; /* padded key */
392 
393 	if (key_len % 4 != 0) {
394 		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
395 		return -EINVAL;
396 	}
397 
398 	memset(p_key, 0, 32);
399 	memcpy(p_key, in_key, key_len);
400 
401 	key[0] = be32_to_cpu(p_key[0]);		/* A */
402 	key[1] = be32_to_cpu(p_key[1]);		/* B */
403 	key[2] = be32_to_cpu(p_key[2]);		/* C */
404 	key[3] = be32_to_cpu(p_key[3]);		/* D */
405 	key[4] = be32_to_cpu(p_key[4]);		/* E */
406 	key[5] = be32_to_cpu(p_key[5]);		/* F */
407 	key[6] = be32_to_cpu(p_key[6]);		/* G */
408 	key[7] = be32_to_cpu(p_key[7]);		/* H */
409 
410 	for (i = 0; i < 12; i++) {
411 		W(key, 2 * i);
412 		W(key, 2 * i + 1);
413 
414 		c->Kr[i][0] = key[0] & 0x1f;
415 		c->Kr[i][1] = key[2] & 0x1f;
416 		c->Kr[i][2] = key[4] & 0x1f;
417 		c->Kr[i][3] = key[6] & 0x1f;
418 
419 		c->Km[i][0] = key[7];
420 		c->Km[i][1] = key[5];
421 		c->Km[i][2] = key[3];
422 		c->Km[i][3] = key[1];
423 	}
424 
425 	return 0;
426 }
427 EXPORT_SYMBOL_GPL(__cast6_setkey);
428 
429 int cast6_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
430 {
431 	return __cast6_setkey(crypto_tfm_ctx(tfm), key, keylen,
432 			      &tfm->crt_flags);
433 }
434 EXPORT_SYMBOL_GPL(cast6_setkey);
435 
436 /*forward quad round*/
437 static inline void Q(u32 *block, u8 *Kr, u32 *Km)
438 {
439 	u32 I;
440 	block[2] ^= F1(block[3], Kr[0], Km[0]);
441 	block[1] ^= F2(block[2], Kr[1], Km[1]);
442 	block[0] ^= F3(block[1], Kr[2], Km[2]);
443 	block[3] ^= F1(block[0], Kr[3], Km[3]);
444 }
445 
446 /*reverse quad round*/
447 static inline void QBAR(u32 *block, u8 *Kr, u32 *Km)
448 {
449 	u32 I;
450 	block[3] ^= F1(block[0], Kr[3], Km[3]);
451 	block[0] ^= F3(block[1], Kr[2], Km[2]);
452 	block[1] ^= F2(block[2], Kr[1], Km[1]);
453 	block[2] ^= F1(block[3], Kr[0], Km[0]);
454 }
455 
456 void __cast6_encrypt(struct cast6_ctx *c, u8 *outbuf, const u8 *inbuf)
457 {
458 	const __be32 *src = (const __be32 *)inbuf;
459 	__be32 *dst = (__be32 *)outbuf;
460 	u32 block[4];
461 	u32 *Km;
462 	u8 *Kr;
463 
464 	block[0] = be32_to_cpu(src[0]);
465 	block[1] = be32_to_cpu(src[1]);
466 	block[2] = be32_to_cpu(src[2]);
467 	block[3] = be32_to_cpu(src[3]);
468 
469 	Km = c->Km[0]; Kr = c->Kr[0]; Q(block, Kr, Km);
470 	Km = c->Km[1]; Kr = c->Kr[1]; Q(block, Kr, Km);
471 	Km = c->Km[2]; Kr = c->Kr[2]; Q(block, Kr, Km);
472 	Km = c->Km[3]; Kr = c->Kr[3]; Q(block, Kr, Km);
473 	Km = c->Km[4]; Kr = c->Kr[4]; Q(block, Kr, Km);
474 	Km = c->Km[5]; Kr = c->Kr[5]; Q(block, Kr, Km);
475 	Km = c->Km[6]; Kr = c->Kr[6]; QBAR(block, Kr, Km);
476 	Km = c->Km[7]; Kr = c->Kr[7]; QBAR(block, Kr, Km);
477 	Km = c->Km[8]; Kr = c->Kr[8]; QBAR(block, Kr, Km);
478 	Km = c->Km[9]; Kr = c->Kr[9]; QBAR(block, Kr, Km);
479 	Km = c->Km[10]; Kr = c->Kr[10]; QBAR(block, Kr, Km);
480 	Km = c->Km[11]; Kr = c->Kr[11]; QBAR(block, Kr, Km);
481 
482 	dst[0] = cpu_to_be32(block[0]);
483 	dst[1] = cpu_to_be32(block[1]);
484 	dst[2] = cpu_to_be32(block[2]);
485 	dst[3] = cpu_to_be32(block[3]);
486 }
487 EXPORT_SYMBOL_GPL(__cast6_encrypt);
488 
489 static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
490 {
491 	__cast6_encrypt(crypto_tfm_ctx(tfm), outbuf, inbuf);
492 }
493 
494 void __cast6_decrypt(struct cast6_ctx *c, u8 *outbuf, const u8 *inbuf)
495 {
496 	const __be32 *src = (const __be32 *)inbuf;
497 	__be32 *dst = (__be32 *)outbuf;
498 	u32 block[4];
499 	u32 *Km;
500 	u8 *Kr;
501 
502 	block[0] = be32_to_cpu(src[0]);
503 	block[1] = be32_to_cpu(src[1]);
504 	block[2] = be32_to_cpu(src[2]);
505 	block[3] = be32_to_cpu(src[3]);
506 
507 	Km = c->Km[11]; Kr = c->Kr[11]; Q(block, Kr, Km);
508 	Km = c->Km[10]; Kr = c->Kr[10]; Q(block, Kr, Km);
509 	Km = c->Km[9]; Kr = c->Kr[9]; Q(block, Kr, Km);
510 	Km = c->Km[8]; Kr = c->Kr[8]; Q(block, Kr, Km);
511 	Km = c->Km[7]; Kr = c->Kr[7]; Q(block, Kr, Km);
512 	Km = c->Km[6]; Kr = c->Kr[6]; Q(block, Kr, Km);
513 	Km = c->Km[5]; Kr = c->Kr[5]; QBAR(block, Kr, Km);
514 	Km = c->Km[4]; Kr = c->Kr[4]; QBAR(block, Kr, Km);
515 	Km = c->Km[3]; Kr = c->Kr[3]; QBAR(block, Kr, Km);
516 	Km = c->Km[2]; Kr = c->Kr[2]; QBAR(block, Kr, Km);
517 	Km = c->Km[1]; Kr = c->Kr[1]; QBAR(block, Kr, Km);
518 	Km = c->Km[0]; Kr = c->Kr[0]; QBAR(block, Kr, Km);
519 
520 	dst[0] = cpu_to_be32(block[0]);
521 	dst[1] = cpu_to_be32(block[1]);
522 	dst[2] = cpu_to_be32(block[2]);
523 	dst[3] = cpu_to_be32(block[3]);
524 }
525 EXPORT_SYMBOL_GPL(__cast6_decrypt);
526 
527 static void cast6_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
528 {
529 	__cast6_decrypt(crypto_tfm_ctx(tfm), outbuf, inbuf);
530 }
531 
532 static struct crypto_alg alg = {
533 	.cra_name = "cast6",
534 	.cra_driver_name = "cast6-generic",
535 	.cra_priority = 100,
536 	.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
537 	.cra_blocksize = CAST6_BLOCK_SIZE,
538 	.cra_ctxsize = sizeof(struct cast6_ctx),
539 	.cra_alignmask = 3,
540 	.cra_module = THIS_MODULE,
541 	.cra_u = {
542 		  .cipher = {
543 			     .cia_min_keysize = CAST6_MIN_KEY_SIZE,
544 			     .cia_max_keysize = CAST6_MAX_KEY_SIZE,
545 			     .cia_setkey = cast6_setkey,
546 			     .cia_encrypt = cast6_encrypt,
547 			     .cia_decrypt = cast6_decrypt}
548 		  }
549 };
550 
551 static int __init cast6_mod_init(void)
552 {
553 	return crypto_register_alg(&alg);
554 }
555 
556 static void __exit cast6_mod_fini(void)
557 {
558 	crypto_unregister_alg(&alg);
559 }
560 
561 module_init(cast6_mod_init);
562 module_exit(cast6_mod_fini);
563 
564 MODULE_LICENSE("GPL");
565 MODULE_DESCRIPTION("Cast6 Cipher Algorithm");
566 MODULE_ALIAS("cast6");
567