diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /crypto/serpent.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'crypto/serpent.c')
-rw-r--r-- | crypto/serpent.c | 593 |
1 files changed, 593 insertions, 0 deletions
diff --git a/crypto/serpent.c b/crypto/serpent.c new file mode 100644 index 000000000000..7d152e89016f --- /dev/null +++ b/crypto/serpent.c | |||
@@ -0,0 +1,593 @@ | |||
1 | /* | ||
2 | * Cryptographic API. | ||
3 | * | ||
4 | * Serpent Cipher Algorithm. | ||
5 | * | ||
6 | * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no> | ||
7 | * 2003 Herbert Valerio Riedel <hvr@gnu.org> | ||
8 | * | ||
9 | * Added tnepres support: Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004 | ||
10 | * Based on code by hvr | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <asm/byteorder.h> | ||
22 | #include <linux/crypto.h> | ||
23 | |||
24 | /* Key is padded to the maximum of 256 bits before round key generation. | ||
25 | * Any key length <= 256 bits (32 bytes) is allowed by the algorithm. | ||
26 | */ | ||
27 | |||
28 | #define SERPENT_MIN_KEY_SIZE 0 | ||
29 | #define SERPENT_MAX_KEY_SIZE 32 | ||
30 | #define SERPENT_EXPKEY_WORDS 132 | ||
31 | #define SERPENT_BLOCK_SIZE 16 | ||
32 | |||
33 | #define PHI 0x9e3779b9UL | ||
34 | |||
35 | #define keyiter(a,b,c,d,i,j) \ | ||
36 | b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b,11); k[j] = b; | ||
37 | |||
38 | #define loadkeys(x0,x1,x2,x3,i) \ | ||
39 | x0=k[i]; x1=k[i+1]; x2=k[i+2]; x3=k[i+3]; | ||
40 | |||
41 | #define storekeys(x0,x1,x2,x3,i) \ | ||
42 | k[i]=x0; k[i+1]=x1; k[i+2]=x2; k[i+3]=x3; | ||
43 | |||
44 | #define K(x0,x1,x2,x3,i) \ | ||
45 | x3 ^= k[4*(i)+3]; x2 ^= k[4*(i)+2]; \ | ||
46 | x1 ^= k[4*(i)+1]; x0 ^= k[4*(i)+0]; | ||
47 | |||
48 | #define LK(x0,x1,x2,x3,x4,i) \ | ||
49 | x0=rol32(x0,13);\ | ||
50 | x2=rol32(x2,3); x1 ^= x0; x4 = x0 << 3; \ | ||
51 | x3 ^= x2; x1 ^= x2; \ | ||
52 | x1=rol32(x1,1); x3 ^= x4; \ | ||
53 | x3=rol32(x3,7); x4 = x1; \ | ||
54 | x0 ^= x1; x4 <<= 7; x2 ^= x3; \ | ||
55 | x0 ^= x3; x2 ^= x4; x3 ^= k[4*i+3]; \ | ||
56 | x1 ^= k[4*i+1]; x0=rol32(x0,5); x2=rol32(x2,22);\ | ||
57 | x0 ^= k[4*i+0]; x2 ^= k[4*i+2]; | ||
58 | |||
59 | #define KL(x0,x1,x2,x3,x4,i) \ | ||
60 | x0 ^= k[4*i+0]; x1 ^= k[4*i+1]; x2 ^= k[4*i+2]; \ | ||
61 | x3 ^= k[4*i+3]; x0=ror32(x0,5); x2=ror32(x2,22);\ | ||
62 | x4 = x1; x2 ^= x3; x0 ^= x3; \ | ||
63 | x4 <<= 7; x0 ^= x1; x1=ror32(x1,1); \ | ||
64 | x2 ^= x4; x3=ror32(x3,7); x4 = x0 << 3; \ | ||
65 | x1 ^= x0; x3 ^= x4; x0=ror32(x0,13);\ | ||
66 | x1 ^= x2; x3 ^= x2; x2=ror32(x2,3); | ||
67 | |||
68 | #define S0(x0,x1,x2,x3,x4) \ | ||
69 | x4 = x3; \ | ||
70 | x3 |= x0; x0 ^= x4; x4 ^= x2; \ | ||
71 | x4 =~ x4; x3 ^= x1; x1 &= x0; \ | ||
72 | x1 ^= x4; x2 ^= x0; x0 ^= x3; \ | ||
73 | x4 |= x0; x0 ^= x2; x2 &= x1; \ | ||
74 | x3 ^= x2; x1 =~ x1; x2 ^= x4; \ | ||
75 | x1 ^= x2; | ||
76 | |||
77 | #define S1(x0,x1,x2,x3,x4) \ | ||
78 | x4 = x1; \ | ||
79 | x1 ^= x0; x0 ^= x3; x3 =~ x3; \ | ||
80 | x4 &= x1; x0 |= x1; x3 ^= x2; \ | ||
81 | x0 ^= x3; x1 ^= x3; x3 ^= x4; \ | ||
82 | x1 |= x4; x4 ^= x2; x2 &= x0; \ | ||
83 | x2 ^= x1; x1 |= x0; x0 =~ x0; \ | ||
84 | x0 ^= x2; x4 ^= x1; | ||
85 | |||
86 | #define S2(x0,x1,x2,x3,x4) \ | ||
87 | x3 =~ x3; \ | ||
88 | x1 ^= x0; x4 = x0; x0 &= x2; \ | ||
89 | x0 ^= x3; x3 |= x4; x2 ^= x1; \ | ||
90 | x3 ^= x1; x1 &= x0; x0 ^= x2; \ | ||
91 | x2 &= x3; x3 |= x1; x0 =~ x0; \ | ||
92 | x3 ^= x0; x4 ^= x0; x0 ^= x2; \ | ||
93 | x1 |= x2; | ||
94 | |||
95 | #define S3(x0,x1,x2,x3,x4) \ | ||
96 | x4 = x1; \ | ||
97 | x1 ^= x3; x3 |= x0; x4 &= x0; \ | ||
98 | x0 ^= x2; x2 ^= x1; x1 &= x3; \ | ||
99 | x2 ^= x3; x0 |= x4; x4 ^= x3; \ | ||
100 | x1 ^= x0; x0 &= x3; x3 &= x4; \ | ||
101 | x3 ^= x2; x4 |= x1; x2 &= x1; \ | ||
102 | x4 ^= x3; x0 ^= x3; x3 ^= x2; | ||
103 | |||
104 | #define S4(x0,x1,x2,x3,x4) \ | ||
105 | x4 = x3; \ | ||
106 | x3 &= x0; x0 ^= x4; \ | ||
107 | x3 ^= x2; x2 |= x4; x0 ^= x1; \ | ||
108 | x4 ^= x3; x2 |= x0; \ | ||
109 | x2 ^= x1; x1 &= x0; \ | ||
110 | x1 ^= x4; x4 &= x2; x2 ^= x3; \ | ||
111 | x4 ^= x0; x3 |= x1; x1 =~ x1; \ | ||
112 | x3 ^= x0; | ||
113 | |||
114 | #define S5(x0,x1,x2,x3,x4) \ | ||
115 | x4 = x1; x1 |= x0; \ | ||
116 | x2 ^= x1; x3 =~ x3; x4 ^= x0; \ | ||
117 | x0 ^= x2; x1 &= x4; x4 |= x3; \ | ||
118 | x4 ^= x0; x0 &= x3; x1 ^= x3; \ | ||
119 | x3 ^= x2; x0 ^= x1; x2 &= x4; \ | ||
120 | x1 ^= x2; x2 &= x0; \ | ||
121 | x3 ^= x2; | ||
122 | |||
123 | #define S6(x0,x1,x2,x3,x4) \ | ||
124 | x4 = x1; \ | ||
125 | x3 ^= x0; x1 ^= x2; x2 ^= x0; \ | ||
126 | x0 &= x3; x1 |= x3; x4 =~ x4; \ | ||
127 | x0 ^= x1; x1 ^= x2; \ | ||
128 | x3 ^= x4; x4 ^= x0; x2 &= x0; \ | ||
129 | x4 ^= x1; x2 ^= x3; x3 &= x1; \ | ||
130 | x3 ^= x0; x1 ^= x2; | ||
131 | |||
132 | #define S7(x0,x1,x2,x3,x4) \ | ||
133 | x1 =~ x1; \ | ||
134 | x4 = x1; x0 =~ x0; x1 &= x2; \ | ||
135 | x1 ^= x3; x3 |= x4; x4 ^= x2; \ | ||
136 | x2 ^= x3; x3 ^= x0; x0 |= x1; \ | ||
137 | x2 &= x0; x0 ^= x4; x4 ^= x3; \ | ||
138 | x3 &= x0; x4 ^= x1; \ | ||
139 | x2 ^= x4; x3 ^= x1; x4 |= x0; \ | ||
140 | x4 ^= x1; | ||
141 | |||
142 | #define SI0(x0,x1,x2,x3,x4) \ | ||
143 | x4 = x3; x1 ^= x0; \ | ||
144 | x3 |= x1; x4 ^= x1; x0 =~ x0; \ | ||
145 | x2 ^= x3; x3 ^= x0; x0 &= x1; \ | ||
146 | x0 ^= x2; x2 &= x3; x3 ^= x4; \ | ||
147 | x2 ^= x3; x1 ^= x3; x3 &= x0; \ | ||
148 | x1 ^= x0; x0 ^= x2; x4 ^= x3; | ||
149 | |||
150 | #define SI1(x0,x1,x2,x3,x4) \ | ||
151 | x1 ^= x3; x4 = x0; \ | ||
152 | x0 ^= x2; x2 =~ x2; x4 |= x1; \ | ||
153 | x4 ^= x3; x3 &= x1; x1 ^= x2; \ | ||
154 | x2 &= x4; x4 ^= x1; x1 |= x3; \ | ||
155 | x3 ^= x0; x2 ^= x0; x0 |= x4; \ | ||
156 | x2 ^= x4; x1 ^= x0; \ | ||
157 | x4 ^= x1; | ||
158 | |||
159 | #define SI2(x0,x1,x2,x3,x4) \ | ||
160 | x2 ^= x1; x4 = x3; x3 =~ x3; \ | ||
161 | x3 |= x2; x2 ^= x4; x4 ^= x0; \ | ||
162 | x3 ^= x1; x1 |= x2; x2 ^= x0; \ | ||
163 | x1 ^= x4; x4 |= x3; x2 ^= x3; \ | ||
164 | x4 ^= x2; x2 &= x1; \ | ||
165 | x2 ^= x3; x3 ^= x4; x4 ^= x0; | ||
166 | |||
167 | #define SI3(x0,x1,x2,x3,x4) \ | ||
168 | x2 ^= x1; \ | ||
169 | x4 = x1; x1 &= x2; \ | ||
170 | x1 ^= x0; x0 |= x4; x4 ^= x3; \ | ||
171 | x0 ^= x3; x3 |= x1; x1 ^= x2; \ | ||
172 | x1 ^= x3; x0 ^= x2; x2 ^= x3; \ | ||
173 | x3 &= x1; x1 ^= x0; x0 &= x2; \ | ||
174 | x4 ^= x3; x3 ^= x0; x0 ^= x1; | ||
175 | |||
176 | #define SI4(x0,x1,x2,x3,x4) \ | ||
177 | x2 ^= x3; x4 = x0; x0 &= x1; \ | ||
178 | x0 ^= x2; x2 |= x3; x4 =~ x4; \ | ||
179 | x1 ^= x0; x0 ^= x2; x2 &= x4; \ | ||
180 | x2 ^= x0; x0 |= x4; \ | ||
181 | x0 ^= x3; x3 &= x2; \ | ||
182 | x4 ^= x3; x3 ^= x1; x1 &= x0; \ | ||
183 | x4 ^= x1; x0 ^= x3; | ||
184 | |||
185 | #define SI5(x0,x1,x2,x3,x4) \ | ||
186 | x4 = x1; x1 |= x2; \ | ||
187 | x2 ^= x4; x1 ^= x3; x3 &= x4; \ | ||
188 | x2 ^= x3; x3 |= x0; x0 =~ x0; \ | ||
189 | x3 ^= x2; x2 |= x0; x4 ^= x1; \ | ||
190 | x2 ^= x4; x4 &= x0; x0 ^= x1; \ | ||
191 | x1 ^= x3; x0 &= x2; x2 ^= x3; \ | ||
192 | x0 ^= x2; x2 ^= x4; x4 ^= x3; | ||
193 | |||
194 | #define SI6(x0,x1,x2,x3,x4) \ | ||
195 | x0 ^= x2; \ | ||
196 | x4 = x0; x0 &= x3; x2 ^= x3; \ | ||
197 | x0 ^= x2; x3 ^= x1; x2 |= x4; \ | ||
198 | x2 ^= x3; x3 &= x0; x0 =~ x0; \ | ||
199 | x3 ^= x1; x1 &= x2; x4 ^= x0; \ | ||
200 | x3 ^= x4; x4 ^= x2; x0 ^= x1; \ | ||
201 | x2 ^= x0; | ||
202 | |||
203 | #define SI7(x0,x1,x2,x3,x4) \ | ||
204 | x4 = x3; x3 &= x0; x0 ^= x2; \ | ||
205 | x2 |= x4; x4 ^= x1; x0 =~ x0; \ | ||
206 | x1 |= x3; x4 ^= x0; x0 &= x2; \ | ||
207 | x0 ^= x1; x1 &= x2; x3 ^= x2; \ | ||
208 | x4 ^= x3; x2 &= x3; x3 |= x0; \ | ||
209 | x1 ^= x4; x3 ^= x4; x4 &= x0; \ | ||
210 | x4 ^= x2; | ||
211 | |||
212 | struct serpent_ctx { | ||
213 | u8 iv[SERPENT_BLOCK_SIZE]; | ||
214 | u32 expkey[SERPENT_EXPKEY_WORDS]; | ||
215 | }; | ||
216 | |||
217 | |||
218 | static int serpent_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | ||
219 | { | ||
220 | u32 *k = ((struct serpent_ctx *)ctx)->expkey; | ||
221 | u8 *k8 = (u8 *)k; | ||
222 | u32 r0,r1,r2,r3,r4; | ||
223 | int i; | ||
224 | |||
225 | if ((keylen < SERPENT_MIN_KEY_SIZE) | ||
226 | || (keylen > SERPENT_MAX_KEY_SIZE)) | ||
227 | { | ||
228 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
229 | return -EINVAL; | ||
230 | } | ||
231 | |||
232 | /* Copy key, add padding */ | ||
233 | |||
234 | for (i = 0; i < keylen; ++i) | ||
235 | k8[i] = key[i]; | ||
236 | if (i < SERPENT_MAX_KEY_SIZE) | ||
237 | k8[i++] = 1; | ||
238 | while (i < SERPENT_MAX_KEY_SIZE) | ||
239 | k8[i++] = 0; | ||
240 | |||
241 | /* Expand key using polynomial */ | ||
242 | |||
243 | r0 = le32_to_cpu(k[3]); | ||
244 | r1 = le32_to_cpu(k[4]); | ||
245 | r2 = le32_to_cpu(k[5]); | ||
246 | r3 = le32_to_cpu(k[6]); | ||
247 | r4 = le32_to_cpu(k[7]); | ||
248 | |||
249 | keyiter(le32_to_cpu(k[0]),r0,r4,r2,0,0); | ||
250 | keyiter(le32_to_cpu(k[1]),r1,r0,r3,1,1); | ||
251 | keyiter(le32_to_cpu(k[2]),r2,r1,r4,2,2); | ||
252 | keyiter(le32_to_cpu(k[3]),r3,r2,r0,3,3); | ||
253 | keyiter(le32_to_cpu(k[4]),r4,r3,r1,4,4); | ||
254 | keyiter(le32_to_cpu(k[5]),r0,r4,r2,5,5); | ||
255 | keyiter(le32_to_cpu(k[6]),r1,r0,r3,6,6); | ||
256 | keyiter(le32_to_cpu(k[7]),r2,r1,r4,7,7); | ||
257 | |||
258 | keyiter(k[ 0],r3,r2,r0, 8, 8); keyiter(k[ 1],r4,r3,r1, 9, 9); | ||
259 | keyiter(k[ 2],r0,r4,r2, 10, 10); keyiter(k[ 3],r1,r0,r3, 11, 11); | ||
260 | keyiter(k[ 4],r2,r1,r4, 12, 12); keyiter(k[ 5],r3,r2,r0, 13, 13); | ||
261 | keyiter(k[ 6],r4,r3,r1, 14, 14); keyiter(k[ 7],r0,r4,r2, 15, 15); | ||
262 | keyiter(k[ 8],r1,r0,r3, 16, 16); keyiter(k[ 9],r2,r1,r4, 17, 17); | ||
263 | keyiter(k[ 10],r3,r2,r0, 18, 18); keyiter(k[ 11],r4,r3,r1, 19, 19); | ||
264 | keyiter(k[ 12],r0,r4,r2, 20, 20); keyiter(k[ 13],r1,r0,r3, 21, 21); | ||
265 | keyiter(k[ 14],r2,r1,r4, 22, 22); keyiter(k[ 15],r3,r2,r0, 23, 23); | ||
266 | keyiter(k[ 16],r4,r3,r1, 24, 24); keyiter(k[ 17],r0,r4,r2, 25, 25); | ||
267 | keyiter(k[ 18],r1,r0,r3, 26, 26); keyiter(k[ 19],r2,r1,r4, 27, 27); | ||
268 | keyiter(k[ 20],r3,r2,r0, 28, 28); keyiter(k[ 21],r4,r3,r1, 29, 29); | ||
269 | keyiter(k[ 22],r0,r4,r2, 30, 30); keyiter(k[ 23],r1,r0,r3, 31, 31); | ||
270 | |||
271 | k += 50; | ||
272 | |||
273 | keyiter(k[-26],r2,r1,r4, 32,-18); keyiter(k[-25],r3,r2,r0, 33,-17); | ||
274 | keyiter(k[-24],r4,r3,r1, 34,-16); keyiter(k[-23],r0,r4,r2, 35,-15); | ||
275 | keyiter(k[-22],r1,r0,r3, 36,-14); keyiter(k[-21],r2,r1,r4, 37,-13); | ||
276 | keyiter(k[-20],r3,r2,r0, 38,-12); keyiter(k[-19],r4,r3,r1, 39,-11); | ||
277 | keyiter(k[-18],r0,r4,r2, 40,-10); keyiter(k[-17],r1,r0,r3, 41, -9); | ||
278 | keyiter(k[-16],r2,r1,r4, 42, -8); keyiter(k[-15],r3,r2,r0, 43, -7); | ||
279 | keyiter(k[-14],r4,r3,r1, 44, -6); keyiter(k[-13],r0,r4,r2, 45, -5); | ||
280 | keyiter(k[-12],r1,r0,r3, 46, -4); keyiter(k[-11],r2,r1,r4, 47, -3); | ||
281 | keyiter(k[-10],r3,r2,r0, 48, -2); keyiter(k[ -9],r4,r3,r1, 49, -1); | ||
282 | keyiter(k[ -8],r0,r4,r2, 50, 0); keyiter(k[ -7],r1,r0,r3, 51, 1); | ||
283 | keyiter(k[ -6],r2,r1,r4, 52, 2); keyiter(k[ -5],r3,r2,r0, 53, 3); | ||
284 | keyiter(k[ -4],r4,r3,r1, 54, 4); keyiter(k[ -3],r0,r4,r2, 55, 5); | ||
285 | keyiter(k[ -2],r1,r0,r3, 56, 6); keyiter(k[ -1],r2,r1,r4, 57, 7); | ||
286 | keyiter(k[ 0],r3,r2,r0, 58, 8); keyiter(k[ 1],r4,r3,r1, 59, 9); | ||
287 | keyiter(k[ 2],r0,r4,r2, 60, 10); keyiter(k[ 3],r1,r0,r3, 61, 11); | ||
288 | keyiter(k[ 4],r2,r1,r4, 62, 12); keyiter(k[ 5],r3,r2,r0, 63, 13); | ||
289 | keyiter(k[ 6],r4,r3,r1, 64, 14); keyiter(k[ 7],r0,r4,r2, 65, 15); | ||
290 | keyiter(k[ 8],r1,r0,r3, 66, 16); keyiter(k[ 9],r2,r1,r4, 67, 17); | ||
291 | keyiter(k[ 10],r3,r2,r0, 68, 18); keyiter(k[ 11],r4,r3,r1, 69, 19); | ||
292 | keyiter(k[ 12],r0,r4,r2, 70, 20); keyiter(k[ 13],r1,r0,r3, 71, 21); | ||
293 | keyiter(k[ 14],r2,r1,r4, 72, 22); keyiter(k[ 15],r3,r2,r0, 73, 23); | ||
294 | keyiter(k[ 16],r4,r3,r1, 74, 24); keyiter(k[ 17],r0,r4,r2, 75, 25); | ||
295 | keyiter(k[ 18],r1,r0,r3, 76, 26); keyiter(k[ 19],r2,r1,r4, 77, 27); | ||
296 | keyiter(k[ 20],r3,r2,r0, 78, 28); keyiter(k[ 21],r4,r3,r1, 79, 29); | ||
297 | keyiter(k[ 22],r0,r4,r2, 80, 30); keyiter(k[ 23],r1,r0,r3, 81, 31); | ||
298 | |||
299 | k += 50; | ||
300 | |||
301 | keyiter(k[-26],r2,r1,r4, 82,-18); keyiter(k[-25],r3,r2,r0, 83,-17); | ||
302 | keyiter(k[-24],r4,r3,r1, 84,-16); keyiter(k[-23],r0,r4,r2, 85,-15); | ||
303 | keyiter(k[-22],r1,r0,r3, 86,-14); keyiter(k[-21],r2,r1,r4, 87,-13); | ||
304 | keyiter(k[-20],r3,r2,r0, 88,-12); keyiter(k[-19],r4,r3,r1, 89,-11); | ||
305 | keyiter(k[-18],r0,r4,r2, 90,-10); keyiter(k[-17],r1,r0,r3, 91, -9); | ||
306 | keyiter(k[-16],r2,r1,r4, 92, -8); keyiter(k[-15],r3,r2,r0, 93, -7); | ||
307 | keyiter(k[-14],r4,r3,r1, 94, -6); keyiter(k[-13],r0,r4,r2, 95, -5); | ||
308 | keyiter(k[-12],r1,r0,r3, 96, -4); keyiter(k[-11],r2,r1,r4, 97, -3); | ||
309 | keyiter(k[-10],r3,r2,r0, 98, -2); keyiter(k[ -9],r4,r3,r1, 99, -1); | ||
310 | keyiter(k[ -8],r0,r4,r2,100, 0); keyiter(k[ -7],r1,r0,r3,101, 1); | ||
311 | keyiter(k[ -6],r2,r1,r4,102, 2); keyiter(k[ -5],r3,r2,r0,103, 3); | ||
312 | keyiter(k[ -4],r4,r3,r1,104, 4); keyiter(k[ -3],r0,r4,r2,105, 5); | ||
313 | keyiter(k[ -2],r1,r0,r3,106, 6); keyiter(k[ -1],r2,r1,r4,107, 7); | ||
314 | keyiter(k[ 0],r3,r2,r0,108, 8); keyiter(k[ 1],r4,r3,r1,109, 9); | ||
315 | keyiter(k[ 2],r0,r4,r2,110, 10); keyiter(k[ 3],r1,r0,r3,111, 11); | ||
316 | keyiter(k[ 4],r2,r1,r4,112, 12); keyiter(k[ 5],r3,r2,r0,113, 13); | ||
317 | keyiter(k[ 6],r4,r3,r1,114, 14); keyiter(k[ 7],r0,r4,r2,115, 15); | ||
318 | keyiter(k[ 8],r1,r0,r3,116, 16); keyiter(k[ 9],r2,r1,r4,117, 17); | ||
319 | keyiter(k[ 10],r3,r2,r0,118, 18); keyiter(k[ 11],r4,r3,r1,119, 19); | ||
320 | keyiter(k[ 12],r0,r4,r2,120, 20); keyiter(k[ 13],r1,r0,r3,121, 21); | ||
321 | keyiter(k[ 14],r2,r1,r4,122, 22); keyiter(k[ 15],r3,r2,r0,123, 23); | ||
322 | keyiter(k[ 16],r4,r3,r1,124, 24); keyiter(k[ 17],r0,r4,r2,125, 25); | ||
323 | keyiter(k[ 18],r1,r0,r3,126, 26); keyiter(k[ 19],r2,r1,r4,127, 27); | ||
324 | keyiter(k[ 20],r3,r2,r0,128, 28); keyiter(k[ 21],r4,r3,r1,129, 29); | ||
325 | keyiter(k[ 22],r0,r4,r2,130, 30); keyiter(k[ 23],r1,r0,r3,131, 31); | ||
326 | |||
327 | /* Apply S-boxes */ | ||
328 | |||
329 | S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 28); loadkeys(r1,r2,r4,r3, 24); | ||
330 | S4(r1,r2,r4,r3,r0); storekeys(r2,r4,r3,r0, 24); loadkeys(r2,r4,r3,r0, 20); | ||
331 | S5(r2,r4,r3,r0,r1); storekeys(r1,r2,r4,r0, 20); loadkeys(r1,r2,r4,r0, 16); | ||
332 | S6(r1,r2,r4,r0,r3); storekeys(r4,r3,r2,r0, 16); loadkeys(r4,r3,r2,r0, 12); | ||
333 | S7(r4,r3,r2,r0,r1); storekeys(r1,r2,r0,r4, 12); loadkeys(r1,r2,r0,r4, 8); | ||
334 | S0(r1,r2,r0,r4,r3); storekeys(r0,r2,r4,r1, 8); loadkeys(r0,r2,r4,r1, 4); | ||
335 | S1(r0,r2,r4,r1,r3); storekeys(r3,r4,r1,r0, 4); loadkeys(r3,r4,r1,r0, 0); | ||
336 | S2(r3,r4,r1,r0,r2); storekeys(r2,r4,r3,r0, 0); loadkeys(r2,r4,r3,r0, -4); | ||
337 | S3(r2,r4,r3,r0,r1); storekeys(r0,r1,r4,r2, -4); loadkeys(r0,r1,r4,r2, -8); | ||
338 | S4(r0,r1,r4,r2,r3); storekeys(r1,r4,r2,r3, -8); loadkeys(r1,r4,r2,r3,-12); | ||
339 | S5(r1,r4,r2,r3,r0); storekeys(r0,r1,r4,r3,-12); loadkeys(r0,r1,r4,r3,-16); | ||
340 | S6(r0,r1,r4,r3,r2); storekeys(r4,r2,r1,r3,-16); loadkeys(r4,r2,r1,r3,-20); | ||
341 | S7(r4,r2,r1,r3,r0); storekeys(r0,r1,r3,r4,-20); loadkeys(r0,r1,r3,r4,-24); | ||
342 | S0(r0,r1,r3,r4,r2); storekeys(r3,r1,r4,r0,-24); loadkeys(r3,r1,r4,r0,-28); | ||
343 | k -= 50; | ||
344 | S1(r3,r1,r4,r0,r2); storekeys(r2,r4,r0,r3, 22); loadkeys(r2,r4,r0,r3, 18); | ||
345 | S2(r2,r4,r0,r3,r1); storekeys(r1,r4,r2,r3, 18); loadkeys(r1,r4,r2,r3, 14); | ||
346 | S3(r1,r4,r2,r3,r0); storekeys(r3,r0,r4,r1, 14); loadkeys(r3,r0,r4,r1, 10); | ||
347 | S4(r3,r0,r4,r1,r2); storekeys(r0,r4,r1,r2, 10); loadkeys(r0,r4,r1,r2, 6); | ||
348 | S5(r0,r4,r1,r2,r3); storekeys(r3,r0,r4,r2, 6); loadkeys(r3,r0,r4,r2, 2); | ||
349 | S6(r3,r0,r4,r2,r1); storekeys(r4,r1,r0,r2, 2); loadkeys(r4,r1,r0,r2, -2); | ||
350 | S7(r4,r1,r0,r2,r3); storekeys(r3,r0,r2,r4, -2); loadkeys(r3,r0,r2,r4, -6); | ||
351 | S0(r3,r0,r2,r4,r1); storekeys(r2,r0,r4,r3, -6); loadkeys(r2,r0,r4,r3,-10); | ||
352 | S1(r2,r0,r4,r3,r1); storekeys(r1,r4,r3,r2,-10); loadkeys(r1,r4,r3,r2,-14); | ||
353 | S2(r1,r4,r3,r2,r0); storekeys(r0,r4,r1,r2,-14); loadkeys(r0,r4,r1,r2,-18); | ||
354 | S3(r0,r4,r1,r2,r3); storekeys(r2,r3,r4,r0,-18); loadkeys(r2,r3,r4,r0,-22); | ||
355 | k -= 50; | ||
356 | S4(r2,r3,r4,r0,r1); storekeys(r3,r4,r0,r1, 28); loadkeys(r3,r4,r0,r1, 24); | ||
357 | S5(r3,r4,r0,r1,r2); storekeys(r2,r3,r4,r1, 24); loadkeys(r2,r3,r4,r1, 20); | ||
358 | S6(r2,r3,r4,r1,r0); storekeys(r4,r0,r3,r1, 20); loadkeys(r4,r0,r3,r1, 16); | ||
359 | S7(r4,r0,r3,r1,r2); storekeys(r2,r3,r1,r4, 16); loadkeys(r2,r3,r1,r4, 12); | ||
360 | S0(r2,r3,r1,r4,r0); storekeys(r1,r3,r4,r2, 12); loadkeys(r1,r3,r4,r2, 8); | ||
361 | S1(r1,r3,r4,r2,r0); storekeys(r0,r4,r2,r1, 8); loadkeys(r0,r4,r2,r1, 4); | ||
362 | S2(r0,r4,r2,r1,r3); storekeys(r3,r4,r0,r1, 4); loadkeys(r3,r4,r0,r1, 0); | ||
363 | S3(r3,r4,r0,r1,r2); storekeys(r1,r2,r4,r3, 0); | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static void serpent_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
369 | { | ||
370 | const u32 | ||
371 | *k = ((struct serpent_ctx *)ctx)->expkey, | ||
372 | *s = (const u32 *)src; | ||
373 | u32 *d = (u32 *)dst, | ||
374 | r0, r1, r2, r3, r4; | ||
375 | |||
376 | /* | ||
377 | * Note: The conversions between u8* and u32* might cause trouble | ||
378 | * on architectures with stricter alignment rules than x86 | ||
379 | */ | ||
380 | |||
381 | r0 = le32_to_cpu(s[0]); | ||
382 | r1 = le32_to_cpu(s[1]); | ||
383 | r2 = le32_to_cpu(s[2]); | ||
384 | r3 = le32_to_cpu(s[3]); | ||
385 | |||
386 | K(r0,r1,r2,r3,0); | ||
387 | S0(r0,r1,r2,r3,r4); LK(r2,r1,r3,r0,r4,1); | ||
388 | S1(r2,r1,r3,r0,r4); LK(r4,r3,r0,r2,r1,2); | ||
389 | S2(r4,r3,r0,r2,r1); LK(r1,r3,r4,r2,r0,3); | ||
390 | S3(r1,r3,r4,r2,r0); LK(r2,r0,r3,r1,r4,4); | ||
391 | S4(r2,r0,r3,r1,r4); LK(r0,r3,r1,r4,r2,5); | ||
392 | S5(r0,r3,r1,r4,r2); LK(r2,r0,r3,r4,r1,6); | ||
393 | S6(r2,r0,r3,r4,r1); LK(r3,r1,r0,r4,r2,7); | ||
394 | S7(r3,r1,r0,r4,r2); LK(r2,r0,r4,r3,r1,8); | ||
395 | S0(r2,r0,r4,r3,r1); LK(r4,r0,r3,r2,r1,9); | ||
396 | S1(r4,r0,r3,r2,r1); LK(r1,r3,r2,r4,r0,10); | ||
397 | S2(r1,r3,r2,r4,r0); LK(r0,r3,r1,r4,r2,11); | ||
398 | S3(r0,r3,r1,r4,r2); LK(r4,r2,r3,r0,r1,12); | ||
399 | S4(r4,r2,r3,r0,r1); LK(r2,r3,r0,r1,r4,13); | ||
400 | S5(r2,r3,r0,r1,r4); LK(r4,r2,r3,r1,r0,14); | ||
401 | S6(r4,r2,r3,r1,r0); LK(r3,r0,r2,r1,r4,15); | ||
402 | S7(r3,r0,r2,r1,r4); LK(r4,r2,r1,r3,r0,16); | ||
403 | S0(r4,r2,r1,r3,r0); LK(r1,r2,r3,r4,r0,17); | ||
404 | S1(r1,r2,r3,r4,r0); LK(r0,r3,r4,r1,r2,18); | ||
405 | S2(r0,r3,r4,r1,r2); LK(r2,r3,r0,r1,r4,19); | ||
406 | S3(r2,r3,r0,r1,r4); LK(r1,r4,r3,r2,r0,20); | ||
407 | S4(r1,r4,r3,r2,r0); LK(r4,r3,r2,r0,r1,21); | ||
408 | S5(r4,r3,r2,r0,r1); LK(r1,r4,r3,r0,r2,22); | ||
409 | S6(r1,r4,r3,r0,r2); LK(r3,r2,r4,r0,r1,23); | ||
410 | S7(r3,r2,r4,r0,r1); LK(r1,r4,r0,r3,r2,24); | ||
411 | S0(r1,r4,r0,r3,r2); LK(r0,r4,r3,r1,r2,25); | ||
412 | S1(r0,r4,r3,r1,r2); LK(r2,r3,r1,r0,r4,26); | ||
413 | S2(r2,r3,r1,r0,r4); LK(r4,r3,r2,r0,r1,27); | ||
414 | S3(r4,r3,r2,r0,r1); LK(r0,r1,r3,r4,r2,28); | ||
415 | S4(r0,r1,r3,r4,r2); LK(r1,r3,r4,r2,r0,29); | ||
416 | S5(r1,r3,r4,r2,r0); LK(r0,r1,r3,r2,r4,30); | ||
417 | S6(r0,r1,r3,r2,r4); LK(r3,r4,r1,r2,r0,31); | ||
418 | S7(r3,r4,r1,r2,r0); K(r0,r1,r2,r3,32); | ||
419 | |||
420 | d[0] = cpu_to_le32(r0); | ||
421 | d[1] = cpu_to_le32(r1); | ||
422 | d[2] = cpu_to_le32(r2); | ||
423 | d[3] = cpu_to_le32(r3); | ||
424 | } | ||
425 | |||
426 | static void serpent_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
427 | { | ||
428 | const u32 | ||
429 | *k = ((struct serpent_ctx *)ctx)->expkey, | ||
430 | *s = (const u32 *)src; | ||
431 | u32 *d = (u32 *)dst, | ||
432 | r0, r1, r2, r3, r4; | ||
433 | |||
434 | r0 = le32_to_cpu(s[0]); | ||
435 | r1 = le32_to_cpu(s[1]); | ||
436 | r2 = le32_to_cpu(s[2]); | ||
437 | r3 = le32_to_cpu(s[3]); | ||
438 | |||
439 | K(r0,r1,r2,r3,32); | ||
440 | SI7(r0,r1,r2,r3,r4); KL(r1,r3,r0,r4,r2,31); | ||
441 | SI6(r1,r3,r0,r4,r2); KL(r0,r2,r4,r1,r3,30); | ||
442 | SI5(r0,r2,r4,r1,r3); KL(r2,r3,r0,r4,r1,29); | ||
443 | SI4(r2,r3,r0,r4,r1); KL(r2,r0,r1,r4,r3,28); | ||
444 | SI3(r2,r0,r1,r4,r3); KL(r1,r2,r3,r4,r0,27); | ||
445 | SI2(r1,r2,r3,r4,r0); KL(r2,r0,r4,r3,r1,26); | ||
446 | SI1(r2,r0,r4,r3,r1); KL(r1,r0,r4,r3,r2,25); | ||
447 | SI0(r1,r0,r4,r3,r2); KL(r4,r2,r0,r1,r3,24); | ||
448 | SI7(r4,r2,r0,r1,r3); KL(r2,r1,r4,r3,r0,23); | ||
449 | SI6(r2,r1,r4,r3,r0); KL(r4,r0,r3,r2,r1,22); | ||
450 | SI5(r4,r0,r3,r2,r1); KL(r0,r1,r4,r3,r2,21); | ||
451 | SI4(r0,r1,r4,r3,r2); KL(r0,r4,r2,r3,r1,20); | ||
452 | SI3(r0,r4,r2,r3,r1); KL(r2,r0,r1,r3,r4,19); | ||
453 | SI2(r2,r0,r1,r3,r4); KL(r0,r4,r3,r1,r2,18); | ||
454 | SI1(r0,r4,r3,r1,r2); KL(r2,r4,r3,r1,r0,17); | ||
455 | SI0(r2,r4,r3,r1,r0); KL(r3,r0,r4,r2,r1,16); | ||
456 | SI7(r3,r0,r4,r2,r1); KL(r0,r2,r3,r1,r4,15); | ||
457 | SI6(r0,r2,r3,r1,r4); KL(r3,r4,r1,r0,r2,14); | ||
458 | SI5(r3,r4,r1,r0,r2); KL(r4,r2,r3,r1,r0,13); | ||
459 | SI4(r4,r2,r3,r1,r0); KL(r4,r3,r0,r1,r2,12); | ||
460 | SI3(r4,r3,r0,r1,r2); KL(r0,r4,r2,r1,r3,11); | ||
461 | SI2(r0,r4,r2,r1,r3); KL(r4,r3,r1,r2,r0,10); | ||
462 | SI1(r4,r3,r1,r2,r0); KL(r0,r3,r1,r2,r4,9); | ||
463 | SI0(r0,r3,r1,r2,r4); KL(r1,r4,r3,r0,r2,8); | ||
464 | SI7(r1,r4,r3,r0,r2); KL(r4,r0,r1,r2,r3,7); | ||
465 | SI6(r4,r0,r1,r2,r3); KL(r1,r3,r2,r4,r0,6); | ||
466 | SI5(r1,r3,r2,r4,r0); KL(r3,r0,r1,r2,r4,5); | ||
467 | SI4(r3,r0,r1,r2,r4); KL(r3,r1,r4,r2,r0,4); | ||
468 | SI3(r3,r1,r4,r2,r0); KL(r4,r3,r0,r2,r1,3); | ||
469 | SI2(r4,r3,r0,r2,r1); KL(r3,r1,r2,r0,r4,2); | ||
470 | SI1(r3,r1,r2,r0,r4); KL(r4,r1,r2,r0,r3,1); | ||
471 | SI0(r4,r1,r2,r0,r3); K(r2,r3,r1,r4,0); | ||
472 | |||
473 | d[0] = cpu_to_le32(r2); | ||
474 | d[1] = cpu_to_le32(r3); | ||
475 | d[2] = cpu_to_le32(r1); | ||
476 | d[3] = cpu_to_le32(r4); | ||
477 | } | ||
478 | |||
479 | static struct crypto_alg serpent_alg = { | ||
480 | .cra_name = "serpent", | ||
481 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
482 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
483 | .cra_ctxsize = sizeof(struct serpent_ctx), | ||
484 | .cra_module = THIS_MODULE, | ||
485 | .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list), | ||
486 | .cra_u = { .cipher = { | ||
487 | .cia_min_keysize = SERPENT_MIN_KEY_SIZE, | ||
488 | .cia_max_keysize = SERPENT_MAX_KEY_SIZE, | ||
489 | .cia_setkey = serpent_setkey, | ||
490 | .cia_encrypt = serpent_encrypt, | ||
491 | .cia_decrypt = serpent_decrypt } } | ||
492 | }; | ||
493 | |||
494 | static int tnepres_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) | ||
495 | { | ||
496 | u8 rev_key[SERPENT_MAX_KEY_SIZE]; | ||
497 | int i; | ||
498 | |||
499 | if ((keylen < SERPENT_MIN_KEY_SIZE) | ||
500 | || (keylen > SERPENT_MAX_KEY_SIZE)) { | ||
501 | *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | |||
505 | for (i = 0; i < keylen; ++i) | ||
506 | rev_key[keylen - i - 1] = key[i]; | ||
507 | |||
508 | return serpent_setkey(ctx, rev_key, keylen, flags); | ||
509 | } | ||
510 | |||
511 | static void tnepres_encrypt(void *ctx, u8 *dst, const u8 *src) | ||
512 | { | ||
513 | const u32 * const s = (const u32 * const)src; | ||
514 | u32 * const d = (u32 * const)dst; | ||
515 | |||
516 | u32 rs[4], rd[4]; | ||
517 | |||
518 | rs[0] = swab32(s[3]); | ||
519 | rs[1] = swab32(s[2]); | ||
520 | rs[2] = swab32(s[1]); | ||
521 | rs[3] = swab32(s[0]); | ||
522 | |||
523 | serpent_encrypt(ctx, (u8 *)rd, (u8 *)rs); | ||
524 | |||
525 | d[0] = swab32(rd[3]); | ||
526 | d[1] = swab32(rd[2]); | ||
527 | d[2] = swab32(rd[1]); | ||
528 | d[3] = swab32(rd[0]); | ||
529 | } | ||
530 | |||
531 | static void tnepres_decrypt(void *ctx, u8 *dst, const u8 *src) | ||
532 | { | ||
533 | const u32 * const s = (const u32 * const)src; | ||
534 | u32 * const d = (u32 * const)dst; | ||
535 | |||
536 | u32 rs[4], rd[4]; | ||
537 | |||
538 | rs[0] = swab32(s[3]); | ||
539 | rs[1] = swab32(s[2]); | ||
540 | rs[2] = swab32(s[1]); | ||
541 | rs[3] = swab32(s[0]); | ||
542 | |||
543 | serpent_decrypt(ctx, (u8 *)rd, (u8 *)rs); | ||
544 | |||
545 | d[0] = swab32(rd[3]); | ||
546 | d[1] = swab32(rd[2]); | ||
547 | d[2] = swab32(rd[1]); | ||
548 | d[3] = swab32(rd[0]); | ||
549 | } | ||
550 | |||
551 | static struct crypto_alg tnepres_alg = { | ||
552 | .cra_name = "tnepres", | ||
553 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
554 | .cra_blocksize = SERPENT_BLOCK_SIZE, | ||
555 | .cra_ctxsize = sizeof(struct serpent_ctx), | ||
556 | .cra_module = THIS_MODULE, | ||
557 | .cra_list = LIST_HEAD_INIT(serpent_alg.cra_list), | ||
558 | .cra_u = { .cipher = { | ||
559 | .cia_min_keysize = SERPENT_MIN_KEY_SIZE, | ||
560 | .cia_max_keysize = SERPENT_MAX_KEY_SIZE, | ||
561 | .cia_setkey = tnepres_setkey, | ||
562 | .cia_encrypt = tnepres_encrypt, | ||
563 | .cia_decrypt = tnepres_decrypt } } | ||
564 | }; | ||
565 | |||
566 | static int __init init(void) | ||
567 | { | ||
568 | int ret = crypto_register_alg(&serpent_alg); | ||
569 | |||
570 | if (ret) | ||
571 | return ret; | ||
572 | |||
573 | ret = crypto_register_alg(&tnepres_alg); | ||
574 | |||
575 | if (ret) | ||
576 | crypto_unregister_alg(&serpent_alg); | ||
577 | |||
578 | return ret; | ||
579 | } | ||
580 | |||
581 | static void __exit fini(void) | ||
582 | { | ||
583 | crypto_unregister_alg(&tnepres_alg); | ||
584 | crypto_unregister_alg(&serpent_alg); | ||
585 | } | ||
586 | |||
587 | module_init(init); | ||
588 | module_exit(fini); | ||
589 | |||
590 | MODULE_LICENSE("GPL"); | ||
591 | MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm"); | ||
592 | MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>"); | ||
593 | MODULE_ALIAS("tnepres"); | ||