xref: /openbmc/linux/crypto/anubis.c (revision 1da177e4)
1 /*
2  * Cryptographic API.
3  *
4  * Anubis Algorithm
5  *
6  * The Anubis algorithm was developed by Paulo S. L. M. Barreto and
7  * Vincent Rijmen.
8  *
9  * See
10  *
11  *	P.S.L.M. Barreto, V. Rijmen,
12  *	``The Anubis block cipher,''
13  *	NESSIE submission, 2000.
14  *
15  * This software implements the "tweaked" version of Anubis.
16  * Only the S-box and (consequently) the rounds constants have been
17  * changed.
18  *
19  * The original authors have disclaimed all copyright interest in this
20  * code and thus put it in the public domain. The subsequent authors
21  * have put this under the GNU General Public License.
22  *
23  * By Aaron Grothe ajgrothe@yahoo.com, October 28, 2004
24  *
25  * This program is free software; you can redistribute it and/or modify
26  * it under the terms of the GNU General Public License as published by
27  * the Free Software Foundation; either version 2 of the License, or
28  * (at your option) any later version.
29  *
30  */
31 
32 #include <linux/init.h>
33 #include <linux/module.h>
34 #include <linux/mm.h>
35 #include <asm/scatterlist.h>
36 #include <linux/crypto.h>
37 
38 #define ANUBIS_MIN_KEY_SIZE	16
39 #define ANUBIS_MAX_KEY_SIZE	40
40 #define ANUBIS_BLOCK_SIZE	16
41 #define ANUBIS_MAX_N		10
42 #define ANUBIS_MAX_ROUNDS	(8 + ANUBIS_MAX_N)
43 
44 struct anubis_ctx {
45 	int key_len; // in bits
46 	int R;
47 	u32 E[ANUBIS_MAX_ROUNDS + 1][4];
48 	u32 D[ANUBIS_MAX_ROUNDS + 1][4];
49 };
50 
51 static const u32 T0[256] = {
52 	0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U,
53 	0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U,
54 	0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U,
55 	0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U,
56 	0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU,
57 	0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U,
58 	0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U,
59 	0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U,
60 	0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU,
61 	0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U,
62 	0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U,
63 	0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU,
64 	0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U,
65 	0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U,
66 	0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U,
67 	0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U,
68 	0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U,
69 	0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U,
70 	0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U,
71 	0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U,
72 	0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U,
73 	0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U,
74 	0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U,
75 	0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U,
76 	0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU,
77 	0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU,
78 	0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU,
79 	0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U,
80 	0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU,
81 	0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU,
82 	0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U,
83 	0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U,
84 	0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U,
85 	0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U,
86 	0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U,
87 	0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U,
88 	0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU,
89 	0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU,
90 	0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU,
91 	0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU,
92 	0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU,
93 	0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU,
94 	0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU,
95 	0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U,
96 	0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU,
97 	0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U,
98 	0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU,
99 	0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU,
100 	0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U,
101 	0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U,
102 	0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U,
103 	0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU,
104 	0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU,
105 	0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U,
106 	0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U,
107 	0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U,
108 	0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U,
109 	0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU,
110 	0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU,
111 	0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U,
112 	0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU,
113 	0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU,
114 	0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU,
115 	0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U,
116 };
117 
118 static const u32 T1[256] = {
119 	0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU,
120 	0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U,
121 	0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U,
122 	0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU,
123 	0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U,
124 	0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U,
125 	0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU,
126 	0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U,
127 	0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U,
128 	0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U,
129 	0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU,
130 	0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U,
131 	0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U,
132 	0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U,
133 	0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U,
134 	0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU,
135 	0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U,
136 	0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U,
137 	0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU,
138 	0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU,
139 	0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U,
140 	0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U,
141 	0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U,
142 	0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U,
143 	0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U,
144 	0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU,
145 	0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U,
146 	0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U,
147 	0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U,
148 	0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU,
149 	0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U,
150 	0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U,
151 	0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU,
152 	0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U,
153 	0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU,
154 	0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU,
155 	0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU,
156 	0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U,
157 	0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU,
158 	0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU,
159 	0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU,
160 	0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U,
161 	0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U,
162 	0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U,
163 	0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U,
164 	0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U,
165 	0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U,
166 	0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU,
167 	0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U,
168 	0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U,
169 	0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U,
170 	0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U,
171 	0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U,
172 	0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU,
173 	0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U,
174 	0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U,
175 	0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U,
176 	0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U,
177 	0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU,
178 	0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU,
179 	0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U,
180 	0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU,
181 	0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U,
182 	0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U,
183 };
184 
185 static const u32 T2[256] = {
186 	0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U,
187 	0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU,
188 	0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U,
189 	0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U,
190 	0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU,
191 	0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U,
192 	0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU,
193 	0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U,
194 	0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU,
195 	0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU,
196 	0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U,
197 	0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U,
198 	0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U,
199 	0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU,
200 	0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U,
201 	0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U,
202 	0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U,
203 	0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U,
204 	0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU,
205 	0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU,
206 	0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U,
207 	0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU,
208 	0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU,
209 	0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U,
210 	0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU,
211 	0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U,
212 	0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U,
213 	0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU,
214 	0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U,
215 	0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U,
216 	0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU,
217 	0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U,
218 	0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU,
219 	0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U,
220 	0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU,
221 	0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U,
222 	0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U,
223 	0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U,
224 	0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U,
225 	0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U,
226 	0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U,
227 	0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U,
228 	0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U,
229 	0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU,
230 	0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU,
231 	0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU,
232 	0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU,
233 	0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U,
234 	0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U,
235 	0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U,
236 	0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U,
237 	0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU,
238 	0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU,
239 	0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U,
240 	0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U,
241 	0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU,
242 	0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U,
243 	0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU,
244 	0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U,
245 	0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U,
246 	0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU,
247 	0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U,
248 	0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU,
249 	0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U,
250 };
251 
252 static const u32 T3[256] = {
253 	0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U,
254 	0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU,
255 	0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU,
256 	0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU,
257 	0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U,
258 	0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U,
259 	0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U,
260 	0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU,
261 	0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU,
262 	0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU,
263 	0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U,
264 	0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U,
265 	0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U,
266 	0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU,
267 	0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU,
268 	0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU,
269 	0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU,
270 	0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU,
271 	0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U,
272 	0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU,
273 	0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U,
274 	0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U,
275 	0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U,
276 	0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U,
277 	0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U,
278 	0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU,
279 	0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU,
280 	0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U,
281 	0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U,
282 	0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U,
283 	0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U,
284 	0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU,
285 	0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U,
286 	0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU,
287 	0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U,
288 	0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U,
289 	0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU,
290 	0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U,
291 	0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U,
292 	0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU,
293 	0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U,
294 	0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U,
295 	0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU,
296 	0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU,
297 	0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U,
298 	0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU,
299 	0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U,
300 	0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU,
301 	0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U,
302 	0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U,
303 	0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U,
304 	0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U,
305 	0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U,
306 	0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU,
307 	0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU,
308 	0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U,
309 	0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U,
310 	0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U,
311 	0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U,
312 	0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U,
313 	0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU,
314 	0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U,
315 	0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU,
316 	0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U,
317 };
318 
319 static const u32 T4[256] = {
320 	0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U,
321 	0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU,
322 	0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU,
323 	0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU,
324 	0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U,
325 	0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U,
326 	0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U,
327 	0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU,
328 	0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU,
329 	0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU,
330 	0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U,
331 	0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U,
332 	0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U,
333 	0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU,
334 	0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU,
335 	0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU,
336 	0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU,
337 	0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU,
338 	0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U,
339 	0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU,
340 	0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U,
341 	0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U,
342 	0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U,
343 	0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U,
344 	0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U,
345 	0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU,
346 	0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU,
347 	0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U,
348 	0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U,
349 	0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U,
350 	0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U,
351 	0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU,
352 	0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U,
353 	0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU,
354 	0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U,
355 	0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U,
356 	0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU,
357 	0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U,
358 	0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U,
359 	0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU,
360 	0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U,
361 	0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U,
362 	0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU,
363 	0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU,
364 	0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U,
365 	0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU,
366 	0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U,
367 	0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU,
368 	0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U,
369 	0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U,
370 	0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U,
371 	0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U,
372 	0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U,
373 	0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU,
374 	0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU,
375 	0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U,
376 	0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U,
377 	0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U,
378 	0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U,
379 	0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U,
380 	0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU,
381 	0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U,
382 	0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU,
383 	0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U,
384 };
385 
386 static const u32 T5[256] = {
387 	0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U,
388 	0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U,
389 	0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U,
390 	0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U,
391 	0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U,
392 	0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U,
393 	0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U,
394 	0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U,
395 	0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U,
396 	0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U,
397 	0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U,
398 	0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U,
399 	0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U,
400 	0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U,
401 	0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U,
402 	0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U,
403 	0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U,
404 	0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U,
405 	0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U,
406 	0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U,
407 	0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U,
408 	0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U,
409 	0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U,
410 	0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U,
411 	0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU,
412 	0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU,
413 	0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU,
414 	0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU,
415 	0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU,
416 	0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU,
417 	0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU,
418 	0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU,
419 	0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU,
420 	0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU,
421 	0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU,
422 	0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU,
423 	0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU,
424 	0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU,
425 	0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU,
426 	0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU,
427 	0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U,
428 	0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U,
429 	0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U,
430 	0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U,
431 	0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U,
432 	0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U,
433 	0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U,
434 	0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U,
435 	0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U,
436 	0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U,
437 	0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U,
438 	0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U,
439 	0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U,
440 	0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U,
441 	0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U,
442 	0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U,
443 	0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU,
444 	0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU,
445 	0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU,
446 	0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU,
447 	0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU,
448 	0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU,
449 	0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU,
450 	0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU,
451 };
452 
453 static const u32 rc[] = {
454 	0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU,
455 	0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU,
456 	0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U,
457 	0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU,
458 	0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U,
459 };
460 
461 static int anubis_setkey(void *ctx_arg, const u8 *in_key,
462 			 unsigned int key_len, u32 *flags)
463 {
464 
465 	int N, R, i, pos, r;
466 	u32 kappa[ANUBIS_MAX_N];
467 	u32 inter[ANUBIS_MAX_N];
468 
469 	struct anubis_ctx *ctx = ctx_arg;
470 
471 	switch (key_len)
472 	{
473 		case 16: case 20: case 24: case 28:
474 		case 32: case 36: case 40:
475 			break;
476 		default:
477 			*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
478 			return - EINVAL;
479 	}
480 
481 	ctx->key_len = key_len * 8;
482 	N = ctx->key_len >> 5;
483 	ctx->R = R = 8 + N;
484 
485 	/* * map cipher key to initial key state (mu): */
486 		for (i = 0, pos = 0; i < N; i++, pos += 4) {
487 		kappa[i] =
488 			(in_key[pos    ] << 24) ^
489 			(in_key[pos + 1] << 16) ^
490 			(in_key[pos + 2] <<  8) ^
491 			(in_key[pos + 3]      );
492 	}
493 
494 	/*
495 	 * generate R + 1 round keys:
496 	 */
497 	for (r = 0; r <= R; r++) {
498 		u32 K0, K1, K2, K3;
499 		/*
500 		 * generate r-th round key K^r:
501 		 */
502 		K0 = T4[(kappa[N - 1] >> 24)       ];
503 		K1 = T4[(kappa[N - 1] >> 16) & 0xff];
504 		K2 = T4[(kappa[N - 1] >>  8) & 0xff];
505 		K3 = T4[(kappa[N - 1]      ) & 0xff];
506 		for (i = N - 2; i >= 0; i--) {
507 			K0 = T4[(kappa[i] >> 24)       ] ^
508 				(T5[(K0 >> 24)       ] & 0xff000000U) ^
509 				(T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^
510 				(T5[(K0 >>  8) & 0xff] & 0x0000ff00U) ^
511 				(T5[(K0      ) & 0xff] & 0x000000ffU);
512 			K1 = T4[(kappa[i] >> 16) & 0xff] ^
513 				(T5[(K1 >> 24)       ] & 0xff000000U) ^
514 				(T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^
515 				(T5[(K1 >>  8) & 0xff] & 0x0000ff00U) ^
516 				(T5[(K1      ) & 0xff] & 0x000000ffU);
517 			K2 = T4[(kappa[i] >>  8) & 0xff] ^
518 				(T5[(K2 >> 24)       ] & 0xff000000U) ^
519 				(T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^
520 				(T5[(K2 >>  8) & 0xff] & 0x0000ff00U) ^
521 				(T5[(K2      ) & 0xff] & 0x000000ffU);
522 			K3 = T4[(kappa[i]      ) & 0xff] ^
523 				(T5[(K3 >> 24)       ] & 0xff000000U) ^
524 				(T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^
525 				(T5[(K3 >>  8) & 0xff] & 0x0000ff00U) ^
526 				(T5[(K3      ) & 0xff] & 0x000000ffU);
527 		}
528 
529 		ctx->E[r][0] = K0;
530 		ctx->E[r][1] = K1;
531 		ctx->E[r][2] = K2;
532 		ctx->E[r][3] = K3;
533 
534 		/*
535 		 * compute kappa^{r+1} from kappa^r:
536 		 */
537 		if (r == R) {
538 			break;
539 		}
540 		for (i = 0; i < N; i++) {
541 			int j = i;
542 			inter[i]  = T0[(kappa[j--] >> 24)       ];
543 			if (j < 0) j = N - 1;
544 			inter[i] ^= T1[(kappa[j--] >> 16) & 0xff];
545 			if (j < 0) j = N - 1;
546 			inter[i] ^= T2[(kappa[j--] >>  8) & 0xff];
547 			if (j < 0) j = N - 1;
548 			inter[i] ^= T3[(kappa[j  ]      ) & 0xff];
549 		}
550 		kappa[0] = inter[0] ^ rc[r];
551 		for (i = 1; i < N; i++) {
552 			kappa[i] = inter[i];
553 		}
554 	}
555 
556 	/*
557 	 * generate inverse key schedule: K'^0 = K^R, K'^R =
558 	 * 				  K^0, K'^r = theta(K^{R-r}):
559 	 */
560 	for (i = 0; i < 4; i++) {
561 		ctx->D[0][i] = ctx->E[R][i];
562 		ctx->D[R][i] = ctx->E[0][i];
563 	}
564 	for (r = 1; r < R; r++) {
565 		for (i = 0; i < 4; i++) {
566 			u32 v = ctx->E[R - r][i];
567 			ctx->D[r][i] =
568 				T0[T4[(v >> 24)       ] & 0xff] ^
569 				T1[T4[(v >> 16) & 0xff] & 0xff] ^
570 				T2[T4[(v >>  8) & 0xff] & 0xff] ^
571 				T3[T4[(v      ) & 0xff] & 0xff];
572 		}
573 	}
574 
575 	return 0;
576 }
577 
578 static void anubis_crypt(u32 roundKey[ANUBIS_MAX_ROUNDS + 1][4],
579 		u8 *ciphertext, const u8 *plaintext, const int R)
580 {
581 	int i, pos, r;
582 	u32 state[4];
583 	u32 inter[4];
584 
585 	/*
586 	 * map plaintext block to cipher state (mu)
587 	 * and add initial round key (sigma[K^0]):
588 	 */
589 	for (i = 0, pos = 0; i < 4; i++, pos += 4) {
590 		state[i] =
591 			(plaintext[pos    ] << 24) ^
592 			(plaintext[pos + 1] << 16) ^
593 			(plaintext[pos + 2] <<  8) ^
594 			(plaintext[pos + 3]      ) ^
595 			roundKey[0][i];
596 	}
597 
598 	/*
599 	 * R - 1 full rounds:
600 	 */
601 
602 	for (r = 1; r < R; r++) {
603 		inter[0] =
604 			T0[(state[0] >> 24)       ] ^
605 			T1[(state[1] >> 24)       ] ^
606 			T2[(state[2] >> 24)       ] ^
607 			T3[(state[3] >> 24)       ] ^
608 			roundKey[r][0];
609 		inter[1] =
610 			T0[(state[0] >> 16) & 0xff] ^
611 			T1[(state[1] >> 16) & 0xff] ^
612 			T2[(state[2] >> 16) & 0xff] ^
613 			T3[(state[3] >> 16) & 0xff] ^
614 			roundKey[r][1];
615 		inter[2] =
616 			T0[(state[0] >>  8) & 0xff] ^
617 			T1[(state[1] >>  8) & 0xff] ^
618 			T2[(state[2] >>  8) & 0xff] ^
619 			T3[(state[3] >>  8) & 0xff] ^
620 			roundKey[r][2];
621 		inter[3] =
622 			T0[(state[0]      ) & 0xff] ^
623 			T1[(state[1]      ) & 0xff] ^
624 			T2[(state[2]      ) & 0xff] ^
625 			T3[(state[3]      ) & 0xff] ^
626 			roundKey[r][3];
627 		state[0] = inter[0];
628 		state[1] = inter[1];
629 		state[2] = inter[2];
630 		state[3] = inter[3];
631 	}
632 
633 	/*
634 	 * last round:
635 	 */
636 
637 	inter[0] =
638 		(T0[(state[0] >> 24)       ] & 0xff000000U) ^
639 		(T1[(state[1] >> 24)       ] & 0x00ff0000U) ^
640 		(T2[(state[2] >> 24)       ] & 0x0000ff00U) ^
641 		(T3[(state[3] >> 24)       ] & 0x000000ffU) ^
642 		roundKey[R][0];
643 	inter[1] =
644 		(T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^
645 		(T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^
646 		(T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^
647 		(T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^
648 		roundKey[R][1];
649 	inter[2] =
650 		(T0[(state[0] >>  8) & 0xff] & 0xff000000U) ^
651 		(T1[(state[1] >>  8) & 0xff] & 0x00ff0000U) ^
652 		(T2[(state[2] >>  8) & 0xff] & 0x0000ff00U) ^
653 		(T3[(state[3] >>  8) & 0xff] & 0x000000ffU) ^
654 		roundKey[R][2];
655 	inter[3] =
656 		(T0[(state[0]      ) & 0xff] & 0xff000000U) ^
657 		(T1[(state[1]      ) & 0xff] & 0x00ff0000U) ^
658 		(T2[(state[2]      ) & 0xff] & 0x0000ff00U) ^
659 		(T3[(state[3]      ) & 0xff] & 0x000000ffU) ^
660 		roundKey[R][3];
661 
662 	/*
663 	 * map cipher state to ciphertext block (mu^{-1}):
664 	 */
665 
666 	for (i = 0, pos = 0; i < 4; i++, pos += 4) {
667 		u32 w = inter[i];
668 		ciphertext[pos    ] = (u8)(w >> 24);
669 		ciphertext[pos + 1] = (u8)(w >> 16);
670 		ciphertext[pos + 2] = (u8)(w >>  8);
671 		ciphertext[pos + 3] = (u8)(w      );
672 	}
673 }
674 
675 static void anubis_encrypt(void *ctx_arg, u8 *dst, const u8 *src)
676 {
677 	struct anubis_ctx *ctx = ctx_arg;
678 	anubis_crypt(ctx->E, dst, src, ctx->R);
679 }
680 
681 static void anubis_decrypt(void *ctx_arg, u8 *dst, const u8 *src)
682 {
683 	struct anubis_ctx *ctx = ctx_arg;
684 	anubis_crypt(ctx->D, dst, src, ctx->R);
685 }
686 
687 static struct crypto_alg anubis_alg = {
688 	.cra_name		=	"anubis",
689 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
690 	.cra_blocksize		=	ANUBIS_BLOCK_SIZE,
691 	.cra_ctxsize		=	sizeof (struct anubis_ctx),
692 	.cra_module		=	THIS_MODULE,
693 	.cra_list		=	LIST_HEAD_INIT(anubis_alg.cra_list),
694 	.cra_u			=	{ .cipher = {
695 	.cia_min_keysize	=	ANUBIS_MIN_KEY_SIZE,
696 	.cia_max_keysize	=	ANUBIS_MAX_KEY_SIZE,
697 	.cia_setkey		= 	anubis_setkey,
698 	.cia_encrypt		=	anubis_encrypt,
699 	.cia_decrypt		=	anubis_decrypt } }
700 };
701 
702 static int __init init(void)
703 {
704 	int ret = 0;
705 
706 	ret = crypto_register_alg(&anubis_alg);
707 	return ret;
708 }
709 
710 static void __exit fini(void)
711 {
712 	crypto_unregister_alg(&anubis_alg);
713 }
714 
715 module_init(init);
716 module_exit(fini);
717 
718 MODULE_LICENSE("GPL");
719 MODULE_DESCRIPTION("Anubis Cryptographic Algorithm");
720