blob: 3eb08107342331e582318c8ba5c2e0fd5626c40e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* 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
31struct cast6_ctx {
32 u32 Km[12][4];
33 u8 Kr[12][4];
34};
35
36#define F1(D,r,m) ( (I = ((m) + (D))), (I=rol32(I,(r))), \
37 (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
38#define F2(D,r,m) ( (I = ((m) ^ (D))), (I=rol32(I,(r))), \
39 (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
40#define F3(D,r,m) ( (I = ((m) - (D))), (I=rol32(I,(r))), \
41 (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
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};
109
110static const u32 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
177static const u32 s3[256] = {
178 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff,
179 0x369fe44b, 0x8c1fc644, 0xaececa90,
180 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806,
181 0xf0ad0548, 0xe13c8d83, 0x927010d5,
182 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820,
183 0xfade82e0, 0xa067268b, 0x8272792e,
184 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee,
185 0x825b1bfd, 0x9255c5ed, 0x1257a240,
186 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf,
187 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
188 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1,
189 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
190 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c,
191 0x4a012d6e, 0xc5884a28, 0xccc36f71,
192 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850,
193 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
194 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e,
195 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
196 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0,
197 0x1eac5790, 0x796fb449, 0x8252dc15,
198 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403,
199 0xe83ec305, 0x4f91751a, 0x925669c2,
200 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574,
201 0x927985b2, 0x8276dbcb, 0x02778176,
202 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83,
203 0x340ce5c8, 0x96bbb682, 0x93b4b148,
204 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20,
205 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
206 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e,
207 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
208 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9,
209 0xbda8229c, 0x127dadaa, 0x438a074e,
210 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff,
211 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
212 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a,
213 0x76a2e214, 0xb9a40368, 0x925d958f,
214 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623,
215 0x193cbcfa, 0x27627545, 0x825cf47a,
216 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7,
217 0x8272a972, 0x9270c4a8, 0x127de50b,
218 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb,
219 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
220 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11,
221 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
222 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c,
223 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
224 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40,
225 0x7c34671c, 0x02717ef6, 0x4feb5536,
226 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1,
227 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
228 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33,
229 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
230 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff,
231 0x856302e0, 0x72dbd92b, 0xee971b69,
232 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2,
233 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
234 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38,
235 0x0ff0443d, 0x606e6dc6, 0x60543a49,
236 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f,
237 0x68458425, 0x99833be5, 0x600d457d,
238 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31,
239 0x9c305a00, 0x52bce688, 0x1b03588a,
240 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636,
241 0xa133c501, 0xe9d3531c, 0xee353783
242};
243
244static const u32 s4[256] = {
245 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb,
246 0x64ad8c57, 0x85510443, 0xfa020ed1,
247 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43,
248 0x6497b7b1, 0xf3641f63, 0x241e4adf,
249 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30,
250 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
251 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f,
252 0x0c13fefe, 0x081b08ca, 0x05170121,
253 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f,
254 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
255 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400,
256 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
257 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061,
258 0x11b638e1, 0x72500e03, 0xf80eb2bb,
259 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400,
260 0x6920318f, 0x081dbb99, 0xffc304a5,
261 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea,
262 0x9f926f91, 0x9f46222f, 0x3991467d,
263 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8,
264 0x3fb6180c, 0x18f8931e, 0x281658e6,
265 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25,
266 0x79098b02, 0xe4eabb81, 0x28123b23,
267 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9,
268 0x0014377b, 0x041e8ac8, 0x09114003,
269 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de,
270 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
271 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0,
272 0x56c8c391, 0x6b65811c, 0x5e146119,
273 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d,
274 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
275 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a,
276 0xeca1d7c7, 0x041afa32, 0x1d16625a,
277 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb,
278 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
279 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3,
280 0xedda04eb, 0x17a9be04, 0x2c18f4df,
281 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254,
282 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
283 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2,
284 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
285 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86,
286 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
287 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1,
288 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
289 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca,
290 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
291 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5,
292 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
293 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415,
294 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
295 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7,
296 0x0ce454a9, 0xd60acd86, 0x015f1919,
297 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe,
298 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
299 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb,
300 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
301 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8,
302 0x296b299e, 0x492fc295, 0x9266beab,
303 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee,
304 0xf65324e6, 0x6afce36c, 0x0316cc04,
305 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979,
306 0x932bcdf6, 0xb657c34d, 0x4edfd282,
307 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0,
308 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
309};
310
311static const u32 Tm[24][8] = {
312 { 0x5a827999, 0xc95c653a, 0x383650db, 0xa7103c7c, 0x15ea281d,
313 0x84c413be, 0xf39dff5f, 0x6277eb00 } ,
314 { 0xd151d6a1, 0x402bc242, 0xaf05ade3, 0x1ddf9984, 0x8cb98525,
315 0xfb9370c6, 0x6a6d5c67, 0xd9474808 } ,
316 { 0x482133a9, 0xb6fb1f4a, 0x25d50aeb, 0x94aef68c, 0x0388e22d,
317 0x7262cdce, 0xe13cb96f, 0x5016a510 } ,
318 { 0xbef090b1, 0x2dca7c52, 0x9ca467f3, 0x0b7e5394, 0x7a583f35,
319 0xe9322ad6, 0x580c1677, 0xc6e60218 } ,
320 { 0x35bfedb9, 0xa499d95a, 0x1373c4fb, 0x824db09c, 0xf1279c3d,
321 0x600187de, 0xcedb737f, 0x3db55f20 } ,
322 { 0xac8f4ac1, 0x1b693662, 0x8a432203, 0xf91d0da4, 0x67f6f945,
323 0xd6d0e4e6, 0x45aad087, 0xb484bc28 } ,
324 { 0x235ea7c9, 0x9238936a, 0x01127f0b, 0x6fec6aac, 0xdec6564d,
325 0x4da041ee, 0xbc7a2d8f, 0x2b541930 } ,
326 { 0x9a2e04d1, 0x0907f072, 0x77e1dc13, 0xe6bbc7b4, 0x5595b355,
327 0xc46f9ef6, 0x33498a97, 0xa2237638 } ,
328 { 0x10fd61d9, 0x7fd74d7a, 0xeeb1391b, 0x5d8b24bc, 0xcc65105d,
329 0x3b3efbfe, 0xaa18e79f, 0x18f2d340 } ,
330 { 0x87ccbee1, 0xf6a6aa82, 0x65809623, 0xd45a81c4, 0x43346d65,
331 0xb20e5906, 0x20e844a7, 0x8fc23048 } ,
332 { 0xfe9c1be9, 0x6d76078a, 0xdc4ff32b, 0x4b29decc, 0xba03ca6d,
333 0x28ddb60e, 0x97b7a1af, 0x06918d50 } ,
334 { 0x756b78f1, 0xe4456492, 0x531f5033, 0xc1f93bd4, 0x30d32775,
335 0x9fad1316, 0x0e86feb7, 0x7d60ea58 } ,
336 { 0xec3ad5f9, 0x5b14c19a, 0xc9eead3b, 0x38c898dc, 0xa7a2847d,
337 0x167c701e, 0x85565bbf, 0xf4304760 } ,
338 { 0x630a3301, 0xd1e41ea2, 0x40be0a43, 0xaf97f5e4, 0x1e71e185,
339 0x8d4bcd26, 0xfc25b8c7, 0x6affa468 } ,
340 { 0xd9d99009, 0x48b37baa, 0xb78d674b, 0x266752ec, 0x95413e8d,
341 0x041b2a2e, 0x72f515cf, 0xe1cf0170 } ,
342 { 0x50a8ed11, 0xbf82d8b2, 0x2e5cc453, 0x9d36aff4, 0x0c109b95,
343 0x7aea8736, 0xe9c472d7, 0x589e5e78 } ,
344 { 0xc7784a19, 0x365235ba, 0xa52c215b, 0x14060cfc, 0x82dff89d,
345 0xf1b9e43e, 0x6093cfdf, 0xcf6dbb80 } ,
346 { 0x3e47a721, 0xad2192c2, 0x1bfb7e63, 0x8ad56a04, 0xf9af55a5,
347 0x68894146, 0xd7632ce7, 0x463d1888 } ,
348 { 0xb5170429, 0x23f0efca, 0x92cadb6b, 0x01a4c70c, 0x707eb2ad,
349 0xdf589e4e, 0x4e3289ef, 0xbd0c7590 } ,
350 { 0x2be66131, 0x9ac04cd2, 0x099a3873, 0x78742414, 0xe74e0fb5,
351 0x5627fb56, 0xc501e6f7, 0x33dbd298 } ,
352 { 0xa2b5be39, 0x118fa9da, 0x8069957b, 0xef43811c, 0x5e1d6cbd,
353 0xccf7585e, 0x3bd143ff, 0xaaab2fa0 } ,
354 { 0x19851b41, 0x885f06e2, 0xf738f283, 0x6612de24, 0xd4ecc9c5,
355 0x43c6b566, 0xb2a0a107, 0x217a8ca8 } ,
356 { 0x90547849, 0xff2e63ea, 0x6e084f8b, 0xdce23b2c, 0x4bbc26cd,
357 0xba96126e, 0x296ffe0f, 0x9849e9b0 } ,
358 { 0x0723d551, 0x75fdc0f2, 0xe4d7ac93, 0x53b19834, 0xc28b83d5,
359 0x31656f76, 0xa03f5b17, 0x0f1946b8 }
360};
361
362static const u8 Tr[4][8] = {
363 { 0x13, 0x04, 0x15, 0x06, 0x17, 0x08, 0x19, 0x0a } ,
364 { 0x1b, 0x0c, 0x1d, 0x0e, 0x1f, 0x10, 0x01, 0x12 } ,
365 { 0x03, 0x14, 0x05, 0x16, 0x07, 0x18, 0x09, 0x1a } ,
366 { 0x0b, 0x1c, 0x0d, 0x1e, 0x0f, 0x00, 0x11, 0x02 }
367};
368
369/* forward octave */
370static inline void W(u32 *key, unsigned int i) {
371 u32 I;
372 key[6] ^= F1(key[7], Tr[i % 4][0], Tm[i][0]);
373 key[5] ^= F2(key[6], Tr[i % 4][1], Tm[i][1]);
374 key[4] ^= F3(key[5], Tr[i % 4][2], Tm[i][2]);
375 key[3] ^= F1(key[4], Tr[i % 4][3], Tm[i][3]);
376 key[2] ^= F2(key[3], Tr[i % 4][4], Tm[i][4]);
377 key[1] ^= F3(key[2], Tr[i % 4][5], Tm[i][5]);
378 key[0] ^= F1(key[1], Tr[i % 4][6], Tm[i][6]);
379 key[7] ^= F2(key[0], Tr[i % 4][7], Tm[i][7]);
380}
381
382static int
383cast6_setkey(void *ctx, const u8 * in_key, unsigned key_len, u32 * flags)
384{
385 int i;
386 u32 key[8];
387 u8 p_key[32]; /* padded key */
388 struct cast6_ctx *c = (struct cast6_ctx *) ctx;
389
390 if (key_len < 16 || key_len > 32 || key_len % 4 != 0) {
391 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
392 return -EINVAL;
393 }
394
395 memset (p_key, 0, 32);
396 memcpy (p_key, in_key, key_len);
397
398 key[0] = p_key[0] << 24 | p_key[1] << 16 | p_key[2] << 8 | p_key[3]; /* A */
399 key[1] = p_key[4] << 24 | p_key[5] << 16 | p_key[6] << 8 | p_key[7]; /* B */
400 key[2] = p_key[8] << 24 | p_key[9] << 16 | p_key[10] << 8 | p_key[11]; /* C */
401 key[3] = p_key[12] << 24 | p_key[13] << 16 | p_key[14] << 8 | p_key[15]; /* D */
402 key[4] = p_key[16] << 24 | p_key[17] << 16 | p_key[18] << 8 | p_key[19]; /* E */
403 key[5] = p_key[20] << 24 | p_key[21] << 16 | p_key[22] << 8 | p_key[23]; /* F */
404 key[6] = p_key[24] << 24 | p_key[25] << 16 | p_key[26] << 8 | p_key[27]; /* G */
405 key[7] = p_key[28] << 24 | p_key[29] << 16 | p_key[30] << 8 | p_key[31]; /* H */
406
407
408
409 for (i = 0; i < 12; i++) {
410 W (key, 2 * i);
411 W (key, 2 * i + 1);
412
413 c->Kr[i][0] = key[0] & 0x1f;
414 c->Kr[i][1] = key[2] & 0x1f;
415 c->Kr[i][2] = key[4] & 0x1f;
416 c->Kr[i][3] = key[6] & 0x1f;
417
418 c->Km[i][0] = key[7];
419 c->Km[i][1] = key[5];
420 c->Km[i][2] = key[3];
421 c->Km[i][3] = key[1];
422 }
423
424 return 0;
425}
426
427/*forward quad round*/
428static inline void Q (u32 * block, u8 * Kr, u32 * Km) {
429 u32 I;
430 block[2] ^= F1(block[3], Kr[0], Km[0]);
431 block[1] ^= F2(block[2], Kr[1], Km[1]);
432 block[0] ^= F3(block[1], Kr[2], Km[2]);
433 block[3] ^= F1(block[0], Kr[3], Km[3]);
434}
435
436/*reverse quad round*/
437static inline void QBAR (u32 * block, u8 * Kr, u32 * Km) {
438 u32 I;
439 block[3] ^= F1(block[0], Kr[3], Km[3]);
440 block[0] ^= F3(block[1], Kr[2], Km[2]);
441 block[1] ^= F2(block[2], Kr[1], Km[1]);
442 block[2] ^= F1(block[3], Kr[0], Km[0]);
443}
444
445static void cast6_encrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
446 struct cast6_ctx * c = (struct cast6_ctx *)ctx;
447 u32 block[4];
448 u32 * Km;
449 u8 * Kr;
450
451 block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
452 block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
453 block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
454 block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
455
456 Km = c->Km[0]; Kr = c->Kr[0]; Q (block, Kr, Km);
457 Km = c->Km[1]; Kr = c->Kr[1]; Q (block, Kr, Km);
458 Km = c->Km[2]; Kr = c->Kr[2]; Q (block, Kr, Km);
459 Km = c->Km[3]; Kr = c->Kr[3]; Q (block, Kr, Km);
460 Km = c->Km[4]; Kr = c->Kr[4]; Q (block, Kr, Km);
461 Km = c->Km[5]; Kr = c->Kr[5]; Q (block, Kr, Km);
462 Km = c->Km[6]; Kr = c->Kr[6]; QBAR (block, Kr, Km);
463 Km = c->Km[7]; Kr = c->Kr[7]; QBAR (block, Kr, Km);
464 Km = c->Km[8]; Kr = c->Kr[8]; QBAR (block, Kr, Km);
465 Km = c->Km[9]; Kr = c->Kr[9]; QBAR (block, Kr, Km);
466 Km = c->Km[10]; Kr = c->Kr[10]; QBAR (block, Kr, Km);
467 Km = c->Km[11]; Kr = c->Kr[11]; QBAR (block, Kr, Km);
468
469 outbuf[0] = (block[0] >> 24) & 0xff;
470 outbuf[1] = (block[0] >> 16) & 0xff;
471 outbuf[2] = (block[0] >> 8) & 0xff;
472 outbuf[3] = block[0] & 0xff;
473 outbuf[4] = (block[1] >> 24) & 0xff;
474 outbuf[5] = (block[1] >> 16) & 0xff;
475 outbuf[6] = (block[1] >> 8) & 0xff;
476 outbuf[7] = block[1] & 0xff;
477 outbuf[8] = (block[2] >> 24) & 0xff;
478 outbuf[9] = (block[2] >> 16) & 0xff;
479 outbuf[10] = (block[2] >> 8) & 0xff;
480 outbuf[11] = block[2] & 0xff;
481 outbuf[12] = (block[3] >> 24) & 0xff;
482 outbuf[13] = (block[3] >> 16) & 0xff;
483 outbuf[14] = (block[3] >> 8) & 0xff;
484 outbuf[15] = block[3] & 0xff;
485}
486
487static void cast6_decrypt (void * ctx, u8 * outbuf, const u8 * inbuf) {
488 struct cast6_ctx * c = (struct cast6_ctx *)ctx;
489 u32 block[4];
490 u32 * Km;
491 u8 * Kr;
492
493 block[0] = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
494 block[1] = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
495 block[2] = inbuf[8] << 24 | inbuf[9] << 16 | inbuf[10] << 8 | inbuf[11];
496 block[3] = inbuf[12] << 24 | inbuf[13] << 16 | inbuf[14] << 8 | inbuf[15];
497
498 Km = c->Km[11]; Kr = c->Kr[11]; Q (block, Kr, Km);
499 Km = c->Km[10]; Kr = c->Kr[10]; Q (block, Kr, Km);
500 Km = c->Km[9]; Kr = c->Kr[9]; Q (block, Kr, Km);
501 Km = c->Km[8]; Kr = c->Kr[8]; Q (block, Kr, Km);
502 Km = c->Km[7]; Kr = c->Kr[7]; Q (block, Kr, Km);
503 Km = c->Km[6]; Kr = c->Kr[6]; Q (block, Kr, Km);
504 Km = c->Km[5]; Kr = c->Kr[5]; QBAR (block, Kr, Km);
505 Km = c->Km[4]; Kr = c->Kr[4]; QBAR (block, Kr, Km);
506 Km = c->Km[3]; Kr = c->Kr[3]; QBAR (block, Kr, Km);
507 Km = c->Km[2]; Kr = c->Kr[2]; QBAR (block, Kr, Km);
508 Km = c->Km[1]; Kr = c->Kr[1]; QBAR (block, Kr, Km);
509 Km = c->Km[0]; Kr = c->Kr[0]; QBAR (block, Kr, Km);
510
511 outbuf[0] = (block[0] >> 24) & 0xff;
512 outbuf[1] = (block[0] >> 16) & 0xff;
513 outbuf[2] = (block[0] >> 8) & 0xff;
514 outbuf[3] = block[0] & 0xff;
515 outbuf[4] = (block[1] >> 24) & 0xff;
516 outbuf[5] = (block[1] >> 16) & 0xff;
517 outbuf[6] = (block[1] >> 8) & 0xff;
518 outbuf[7] = block[1] & 0xff;
519 outbuf[8] = (block[2] >> 24) & 0xff;
520 outbuf[9] = (block[2] >> 16) & 0xff;
521 outbuf[10] = (block[2] >> 8) & 0xff;
522 outbuf[11] = block[2] & 0xff;
523 outbuf[12] = (block[3] >> 24) & 0xff;
524 outbuf[13] = (block[3] >> 16) & 0xff;
525 outbuf[14] = (block[3] >> 8) & 0xff;
526 outbuf[15] = block[3] & 0xff;
527}
528
529static struct crypto_alg alg = {
530 .cra_name = "cast6",
531 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
532 .cra_blocksize = CAST6_BLOCK_SIZE,
533 .cra_ctxsize = sizeof(struct cast6_ctx),
534 .cra_module = THIS_MODULE,
535 .cra_list = LIST_HEAD_INIT(alg.cra_list),
536 .cra_u = {
537 .cipher = {
538 .cia_min_keysize = CAST6_MIN_KEY_SIZE,
539 .cia_max_keysize = CAST6_MAX_KEY_SIZE,
540 .cia_setkey = cast6_setkey,
541 .cia_encrypt = cast6_encrypt,
542 .cia_decrypt = cast6_decrypt}
543 }
544};
545
546static int __init init(void)
547{
548 return crypto_register_alg(&alg);
549}
550
551static void __exit fini(void)
552{
553 crypto_unregister_alg(&alg);
554}
555
556module_init(init);
557module_exit(fini);
558
559MODULE_LICENSE("GPL");
560MODULE_DESCRIPTION("Cast6 Cipher Algorithm");