]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - crypto/cast6_generic.c
Merge branch 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[karo-tx-linux.git] / crypto / cast6_generic.c
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");