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 <linux/init.h>
22 #include <linux/crypto.h>
23 #include <linux/module.h>
24 #include <linux/errno.h>
25 #include <linux/string.h>
26
27 #define CAST6_BLOCK_SIZE 16
28 #define CAST6_MIN_KEY_SIZE 16
29 #define CAST6_MAX_KEY_SIZE 32
30
31 struct cast6_ctx {
32 u32 Km[12][4];
33 u8 Kr[12][4];
34 };
35
36 #define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
37
38 #define F1(D,r,m) ( (I = ((m) + (D))), (I=rol((r),I)), \
39 (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
40 #define F2(D,r,m) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
41 (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
42 #define F3(D,r,m) ( (I = ((m) - (D))), (I=rol((r),I)), \
43 (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
44
45 static const u32 s1[256] = {
46 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f,
47 0x9c004dd3, 0x6003e540, 0xcf9fc949,
48 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0,
49 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
50 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3,
51 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
52 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1,
53 0xaa54166b, 0x22568e3a, 0xa2d341d0,
54 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac,
55 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
56 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0,
57 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
58 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290,
59 0xe93b159f, 0xb48ee411, 0x4bff345d,
60 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad,
61 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
62 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f,
63 0xc59c5319, 0xb949e354, 0xb04669fe,
64 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5,
65 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
66 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5,
67 0xf61b1891, 0xbb72275e, 0xaa508167,
68 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427,
69 0xa2d1936b, 0x2ad286af, 0xaa56d291,
70 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d,
71 0x73e2bb14, 0xa0bebc3c, 0x54623779,
72 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e,
73 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
74 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf,
75 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
76 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241,
77 0x051ef495, 0xaa573b04, 0x4a805d8d,
78 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b,
79 0x50afd341, 0xa7c13275, 0x915a0bf5,
80 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265,
81 0xab85c5f3, 0x1b55db94, 0xaad4e324,
82 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3,
83 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
84 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6,
85 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
86 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6,
87 0x032268d4, 0xc9600acc, 0xce387e6d,
88 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da,
89 0x4736f464, 0x5ad328d8, 0xb347cc96,
90 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc,
91 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
92 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f,
93 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
94 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4,
95 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
96 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af,
97 0x51c85f4d, 0x56907596, 0xa5bb15e6,
98 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a,
99 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
100 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf,
101 0x700b45e1, 0xd5ea50f1, 0x85a92872,
102 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198,
103 0x0cd0ede7, 0x26470db8, 0xf881814c,
104 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db,
105 0xab838653, 0x6e2f1e23, 0x83719c9e,
106 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c,
107 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
108 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c,
109 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
110 };
111
112 static const u32 s2[256] = {
113 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a,
114 0xeec5207a, 0x55889c94, 0x72fc0651,
115 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef,
116 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
117 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086,
118 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
119 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb,
120 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
121 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f,
122 0x77e83f4e, 0x79929269, 0x24fa9f7b,
123 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154,
124 0x0d554b63, 0x5d681121, 0xc866c359,
125 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181,
126 0x39f7627f, 0x361e3084, 0xe4eb573b,
127 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c,
128 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
129 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a,
130 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
131 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c,
132 0x1d804366, 0x721d9bfd, 0xa58684bb,
133 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1,
134 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
135 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9,
136 0xe0b56714, 0x21f043b7, 0xe5d05860,
137 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf,
138 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
139 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c,
140 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
141 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122,
142 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
143 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402,
144 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
145 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53,
146 0xe3214517, 0xb4542835, 0x9f63293c,
147 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6,
148 0x30a22c95, 0x31a70850, 0x60930f13,
149 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6,
150 0xa02b1741, 0x7cbad9a2, 0x2180036f,
151 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676,
152 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
153 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb,
154 0x846a3bae, 0x8ff77888, 0xee5d60f6,
155 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54,
156 0x157fd7fa, 0xef8579cc, 0xd152de58,
157 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5,
158 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
159 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8,
160 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
161 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc,
162 0x301e16e6, 0x273be979, 0xb0ffeaa6,
163 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a,
164 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
165 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e,
166 0x1a513742, 0xef6828bc, 0x520365d6,
167 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb,
168 0x5eea29cb, 0x145892f5, 0x91584f7f,
169 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4,
170 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
171 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3,
172 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
173 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589,
174 0xa345415e, 0x5c038323, 0x3e5d3bb9,
175 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539,
176 0x73bfbe70, 0x83877605, 0x4523ecf1
177 };
178
179 static const u32 s3[256] = {
180 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
181 0x369fe44b, 0x8c1fc644, 0xaececa90,
182 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
183 0xf0ad0548, 0xe13c8d83, 0x927010d5,
184 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
185 0xfade82e0, 0xa067268b, 0x8272792e,
186 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
187 0x825b1bfd, 0x9255c5ed, 0x1257a240,
188 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
189 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
190 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
191 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
192 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
193 0x4a012d6e, 0xc5884a28, 0xccc36f71,
194 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
195 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
196 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
197 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
198 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
199 0x1eac5790, 0x796fb449, 0x8252dc15,
200 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
201 0xe83ec305, 0x4f91751a, 0x925669c2,
202 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
203 0x927985b2, 0x8276dbcb, 0x02778176,
204 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
205 0x340ce5c8, 0x96bbb682, 0x93b4b148,
206 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
207 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
208 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
209 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
210 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
211 0xbda8229c, 0x127dadaa, 0x438a074e,
212 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
213 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
214 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
215 0x76a2e214, 0xb9a40368, 0x925d958f,
216 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
217 0x193cbcfa, 0x27627545, 0x825cf47a,
218 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
219 0x8272a972, 0x9270c4a8, 0x127de50b,
220 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
221 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
222 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
223 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
224 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
225 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
226 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
227 0x7c34671c, 0x02717ef6, 0x4feb5536,
228 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
229 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
230 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
231 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
232 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
233 0x856302e0, 0x72dbd92b, 0xee971b69,
234 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
235 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
236 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
237 0x0ff0443d, 0x606e6dc6, 0x60543a49,
238 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
239 0x68458425, 0x99833be5, 0x600d457d,
240 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
241 0x9c305a00, 0x52bce688, 0x1b03588a,
242 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
243 0xa133c501, 0xe9d3531c, 0xee353783
244 };
245
246 static const u32 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
313 static const u32 Tm[24][8] = {
314 { 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
315 0x84c413be, 0xf39dff5f, 0x6277eb00 } ,
316 { 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525,
317 0xfb9370c6, 0x6a6d5c67, 0xd9474808 } ,
318 { 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d,
319 0x7262cdce, 0xe13cb96f, 0x5016a510 } ,
320 { 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35,
321 0xe9322ad6, 0x580c1677, 0xc6e60218 } ,
322 { 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d,
323 0x600187de, 0xcedb737f, 0x3db55f20 } ,
324 { 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945,
325 0xd6d0e4e6, 0x45aad087, 0xb484bc28 } ,
326 { 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d,
327 0x4da041ee, 0xbc7a2d8f, 0x2b541930 } ,
328 { 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355,
329 0xc46f9ef6, 0x33498a97, 0xa2237638 } ,
330 { 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d,
331 0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } ,
332 { 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65,
333 0xb20e5906, 0x20e844a7, 0x8fc23048 } ,
334 { 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d,
335 0x28ddb60e, 0x97b7a1af, 0x06918d50 } ,
336 { 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775,
337 0x9fad1316, 0x0e86feb7, 0x7d60ea58 } ,
338 { 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d,
339 0x167c701e, 0x85565bbf, 0xf4304760 } ,
340 { 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185,
341 0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } ,
342 { 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d,
343 0x041b2a2e, 0x72f515cf, 0xe1cf0170 } ,
344 { 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95,
345 0x7aea8736, 0xe9c472d7, 0x589e5e78 } ,
346 { 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d,
347 0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } ,
348 { 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5,
349 0x68894146, 0xd7632ce7, 0x463d1888 } ,
350 { 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad,
351 0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } ,
352 { 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5,
353 0x5627fb56, 0xc501e6f7, 0x33dbd298 } ,
354 { 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd,
355 0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } ,
356 { 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5,
357 0x43c6b566, 0xb2a0a107, 0x217a8ca8 } ,
358 { 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd,
359 0xba96126e, 0x296ffe0f, 0x9849e9b0 } ,
360 { 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5,
361 0x31656f76, 0xa03f5b17, 0x0f1946b8 }
362 };
363
364 static const u8 Tr[4][8] = {
365 { 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } ,
366 { 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } ,
367 { 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } ,
368 { 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 }
369 };
370
371 /* forward octave */
W(u32 * key,unsigned int i)372 static inline void W(u32 *key, unsigned int i) {
373 u32 I;
374 key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
375 key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
376 key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]);
377 key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]);
378 key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]);
379 key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]);
380 key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);
381 key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
382 }
383
384 static int
cast6_setkey(void * ctx,const u8 * in_key,unsigned key_len,u32 * flags)385 cast6_setkey(void *ctx, const u8 * in_key, unsigned key_len, u32 * flags)
386 {
387 int i;
388 u32 key[8];
389 u8 p_key[32]; /* padded key */
390 struct cast6_ctx *c = (struct cast6_ctx *) ctx;
391
392 if (key_len < 16 || key_len > 32 || key_len % 4 != 0) {
393 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
394 return -EINVAL;
395 }
396
397 memset (p_key, 0, 32);
398 memcpy (p_key, in_key, key_len);
399
400 key[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3]; /* A */
401 key[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7]; /* B */
402 key[2] = p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11]; /* C */
403 key[3] = p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15]; /* D */
404 key[4] = p_key[16] << 24 | p_key[17] << 16 | p_key[18] << 8 | p_key[19]; /* E */
405 key[5] = p_key[20] << 24 | p_key[21] << 16 | p_key[22] << 8 | p_key[23]; /* F */
406 key[6] = p_key[24] << 24 | p_key[25] << 16 | p_key[26] << 8 | p_key[27]; /* G */
407 key[7] = p_key[28] << 24 | p_key[29] << 16 | p_key[30] << 8 | p_key[31]; /* H */
408
409
410
411 for (i = 0; i < 12; i++) {
412 W (key, 2 * i);
413 W (key, 2 * i + 1);
414
415 c->Kr[i][0] = key[0] & 0x1f;
416 c->Kr[i][1] = key[2] & 0x1f;
417 c->Kr[i][2] = key[4] & 0x1f;
418 c->Kr[i][3] = key[6] & 0x1f;
419
420 c->Km[i][0] = key[7];
421 c->Km[i][1] = key[5];
422 c->Km[i][2] = key[3];
423 c->Km[i][3] = key[1];
424 }
425
426 return 0;
427 }
428
429 /*forward quad round*/
Q(u32 * block,u8 * Kr,u32 * Km)430 static inline void Q (u32 * block, u8 * Kr, u32 * Km) {
431 u32 I;
432 block[2] ^= F1(block[3], Kr[0], Km[0]);
433 block[1] ^= F2(block[2], Kr[1], Km[1]);
434 block[0] ^= F3(block[1], Kr[2], Km[2]);
435 block[3] ^= F1(block[0], Kr[3], Km[3]);
436 }
437
438 /*reverse quad round*/
QBAR(u32 * block,u8 * Kr,u32 * Km)439 static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) {
440 u32 I;
441 block[3] ^= F1(block[0], Kr[3], Km[3]);
442 block[0] ^= F3(block[1], Kr[2], Km[2]);
443 block[1] ^= F2(block[2], Kr[1], Km[1]);
444 block[2] ^= F1(block[3], Kr[0], Km[0]);
445 }
446
cast6_encrypt(void * ctx,u8 * outbuf,const u8 * inbuf)447 static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
448 struct cast6_ctx * c = (struct cast6_ctx *)ctx;
449 u32 block[4];
450 u32 * Km;
451 u8 * Kr;
452
453 block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
454 block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
455 block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
456 block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
457
458 Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km);
459 Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km);
460 Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km);
461 Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km);
462 Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km);
463 Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km);
464 Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km);
465 Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km);
466 Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km);
467 Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km);
468 Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km);
469 Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km);
470
471 outbuf[0] = (block[0] >> 24) & 0xff;
472 outbuf[1] = (block[0] >> 16) & 0xff;
473 outbuf[2] = (block[0] >> 8) & 0xff;
474 outbuf[3] = block[0] & 0xff;
475 outbuf[4] = (block[1] >> 24) & 0xff;
476 outbuf[5] = (block[1] >> 16) & 0xff;
477 outbuf[6] = (block[1] >> 8) & 0xff;
478 outbuf[7] = block[1] & 0xff;
479 outbuf[8] = (block[2] >> 24) & 0xff;
480 outbuf[9] = (block[2] >> 16) & 0xff;
481 outbuf[10] = (block[2] >> 8) & 0xff;
482 outbuf[11] = block[2] & 0xff;
483 outbuf[12] = (block[3] >> 24) & 0xff;
484 outbuf[13] = (block[3] >> 16) & 0xff;
485 outbuf[14] = (block[3] >> 8) & 0xff;
486 outbuf[15] = block[3] & 0xff;
487 }
488
cast6_decrypt(void * ctx,u8 * outbuf,const u8 * inbuf)489 static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
490 struct cast6_ctx * c = (struct cast6_ctx *)ctx;
491 u32 block[4];
492 u32 * Km;
493 u8 * Kr;
494
495 block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
496 block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
497 block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
498 block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
499
500 Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km);
501 Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km);
502 Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km);
503 Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km);
504 Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km);
505 Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km);
506 Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km);
507 Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km);
508 Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km);
509 Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km);
510 Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km);
511 Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km);
512
513 outbuf[0] = (block[0] >> 24) & 0xff;
514 outbuf[1] = (block[0] >> 16) & 0xff;
515 outbuf[2] = (block[0] >> 8) & 0xff;
516 outbuf[3] = block[0] & 0xff;
517 outbuf[4] = (block[1] >> 24) & 0xff;
518 outbuf[5] = (block[1] >> 16) & 0xff;
519 outbuf[6] = (block[1] >> 8) & 0xff;
520 outbuf[7] = block[1] & 0xff;
521 outbuf[8] = (block[2] >> 24) & 0xff;
522 outbuf[9] = (block[2] >> 16) & 0xff;
523 outbuf[10] = (block[2] >> 8) & 0xff;
524 outbuf[11] = block[2] & 0xff;
525 outbuf[12] = (block[3] >> 24) & 0xff;
526 outbuf[13] = (block[3] >> 16) & 0xff;
527 outbuf[14] = (block[3] >> 8) & 0xff;
528 outbuf[15] = block[3] & 0xff;
529 }
530
531 static struct crypto_alg alg = {
532 .cra_name = "cast6",
533 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
534 .cra_blocksize = CAST6_BLOCK_SIZE,
535 .cra_ctxsize = sizeof(struct cast6_ctx),
536 .cra_module = THIS_MODULE,
537 .cra_list = LIST_HEAD_INIT(alg.cra_list),
538 .cra_u = {
539 .cipher = {
540 .cia_min_keysize = CAST6_MIN_KEY_SIZE,
541 .cia_max_keysize = CAST6_MAX_KEY_SIZE,
542 .cia_setkey = cast6_setkey,
543 .cia_encrypt = cast6_encrypt,
544 .cia_decrypt = cast6_decrypt}
545 }
546 };
547
init(void)548 static int __init init(void)
549 {
550 return crypto_register_alg(&alg);
551 }
552
fini(void)553 static void __exit fini(void)
554 {
555 crypto_unregister_alg(&alg);
556 }
557
558 module_init(init);
559 module_exit(fini);
560
561 MODULE_LICENSE("GPL");
562 MODULE_DESCRIPTION("Cast6 Cipher Algorithm");
563