Blame view

crypto/serpent_generic.c 21.5 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
  /*
   * Cryptographic API.
   *
   * Serpent Cipher Algorithm.
   *
   * Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
   *               2003 Herbert Valerio Riedel <hvr@gnu.org>
   *
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
10
11
12
   * Added tnepres support:
   *		Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004
   *              Based on code by hvr
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
   */
  
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/errno.h>
  #include <asm/byteorder.h>
  #include <linux/crypto.h>
06ace7a9b   Herbert Xu   [CRYPTO] Use stan...
20
  #include <linux/types.h>
bc83b8299   Jussi Kivilinna   crypto: serpent -...
21
  #include <crypto/serpent.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
  
  /* Key is padded to the maximum of 256 bits before round key generation.
   * Any key length <= 256 bits (32 bytes) is allowed by the algorithm.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #define PHI 0x9e3779b9UL
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
27
28
  #define keyiter(a, b, c, d, i, j) \
  	({ b ^= d; b ^= c; b ^= a; b ^= PHI ^ i; b = rol32(b, 11); k[j] = b; })
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
30
31
  #define loadkeys(x0, x1, x2, x3, i) \
  	({ x0 = k[i]; x1 = k[i+1]; x2 = k[i+2]; x3 = k[i+3]; })
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
33
34
  #define storekeys(x0, x1, x2, x3, i) \
  	({ k[i] = x0; k[i+1] = x1; k[i+2] = x2; k[i+3] = x3; })
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
36
37
38
39
  #define store_and_load_keys(x0, x1, x2, x3, s, l) \
  	({ storekeys(x0, x1, x2, x3, s); loadkeys(x0, x1, x2, x3, l); })
  
  #define K(x0, x1, x2, x3, i) ({				\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
  	x3 ^= k[4*(i)+3];        x2 ^= k[4*(i)+2];	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  	x1 ^= k[4*(i)+1];        x0 ^= k[4*(i)+0];	\
  	})
  
  #define LK(x0, x1, x2, x3, x4, i) ({					   \
  							x0 = rol32(x0, 13);\
  	x2 = rol32(x2, 3);	x1 ^= x0;		x4  = x0 << 3;	   \
  	x3 ^= x2;		x1 ^= x2;				   \
  	x1 = rol32(x1, 1);	x3 ^= x4;				   \
  	x3 = rol32(x3, 7);	x4  = x1;				   \
  	x0 ^= x1;		x4 <<= 7;		x2 ^= x3;	   \
  	x0 ^= x3;		x2 ^= x4;		x3 ^= k[4*i+3];	   \
  	x1 ^= k[4*i+1];		x0 = rol32(x0, 5);	x2 = rol32(x2, 22);\
  	x0 ^= k[4*i+0];		x2 ^= k[4*i+2];				   \
  	})
  
  #define KL(x0, x1, x2, x3, x4, i) ({					   \
  	x0 ^= k[4*i+0];		x1 ^= k[4*i+1];		x2 ^= k[4*i+2];	   \
  	x3 ^= k[4*i+3];		x0 = ror32(x0, 5);	x2 = ror32(x2, 22);\
  	x4 =  x1;		x2 ^= x3;		x0 ^= x3;	   \
  	x4 <<= 7;		x0 ^= x1;		x1 = ror32(x1, 1); \
  	x2 ^= x4;		x3 = ror32(x3, 7);	x4 = x0 << 3;	   \
  	x1 ^= x0;		x3 ^= x4;		x0 = ror32(x0, 13);\
  	x1 ^= x2;		x3 ^= x2;		x2 = ror32(x2, 3); \
  	})
  
  #define S0(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
  					x4  = x3;	\
  	x3 |= x0;	x0 ^= x4;	x4 ^= x2;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
69
  	x4 = ~x4;	x3 ^= x1;	x1 &= x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
  	x1 ^= x4;	x2 ^= x0;	x0 ^= x3;	\
  	x4 |= x0;	x0 ^= x2;	x2 &= x1;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
72
73
74
  	x3 ^= x2;	x1 = ~x1;	x2 ^= x4;	\
  	x1 ^= x2;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
76
  #define S1(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  					x4  = x1;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
78
  	x1 ^= x0;	x0 ^= x3;	x3 = ~x3;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
  	x4 &= x1;	x0 |= x1;	x3 ^= x2;	\
  	x0 ^= x3;	x1 ^= x3;	x3 ^= x4;	\
  	x1 |= x4;	x4 ^= x2;	x2 &= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
82
83
84
  	x2 ^= x1;	x1 |= x0;	x0 = ~x0;	\
  	x0 ^= x2;	x4 ^= x1;			\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
86
87
  #define S2(x0, x1, x2, x3, x4) ({			\
  					x3 = ~x3;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
  	x1 ^= x0;	x4  = x0;	x0 &= x2;	\
  	x0 ^= x3;	x3 |= x4;	x2 ^= x1;	\
  	x3 ^= x1;	x1 &= x0;	x0 ^= x2;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
91
  	x2 &= x3;	x3 |= x1;	x0 = ~x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  	x3 ^= x0;	x4 ^= x0;	x0 ^= x2;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
93
94
  	x1 |= x2;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
96
  #define S3(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
100
101
102
  					x4  = x1;	\
  	x1 ^= x3;	x3 |= x0;	x4 &= x0;	\
  	x0 ^= x2;	x2 ^= x1;	x1 &= x3;	\
  	x2 ^= x3;	x0 |= x4;	x4 ^= x3;	\
  	x1 ^= x0;	x0 &= x3;	x3 &= x4;	\
  	x3 ^= x2;	x4 |= x1;	x2 &= x1;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
103
104
  	x4 ^= x3;	x0 ^= x3;	x3 ^= x2;	\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
106
  #define S4(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
110
111
112
  					x4  = x3;	\
  	x3 &= x0;	x0 ^= x4;			\
  	x3 ^= x2;	x2 |= x4;	x0 ^= x1;	\
  	x4 ^= x3;	x2 |= x0;			\
  	x2 ^= x1;	x1 &= x0;			\
  	x1 ^= x4;	x4 &= x2;	x2 ^= x3;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
113
114
115
  	x4 ^= x0;	x3 |= x1;	x1 = ~x1;	\
  	x3 ^= x0;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
117
  #define S5(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
  	x4  = x1;	x1 |= x0;			\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
119
  	x2 ^= x1;	x3 = ~x3;	x4 ^= x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
  	x0 ^= x2;	x1 &= x4;	x4 |= x3;	\
  	x4 ^= x0;	x0 &= x3;	x1 ^= x3;	\
  	x3 ^= x2;	x0 ^= x1;	x2 &= x4;	\
  	x1 ^= x2;	x2 &= x0;			\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
124
125
  	x3 ^= x2;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
127
  #define S6(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
  					x4  = x1;	\
  	x3 ^= x0;	x1 ^= x2;	x2 ^= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
130
  	x0 &= x3;	x1 |= x3;	x4 = ~x4;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
132
133
  	x0 ^= x1;	x1 ^= x2;			\
  	x3 ^= x4;	x4 ^= x0;	x2 &= x0;	\
  	x4 ^= x1;	x2 ^= x3;	x3 &= x1;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
134
135
  	x3 ^= x0;	x1 ^= x2;			\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
137
138
139
  #define S7(x0, x1, x2, x3, x4) ({			\
  					x1 = ~x1;	\
  	x4  = x1;	x0 = ~x0;	x1 &= x2;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
141
142
143
144
  	x1 ^= x3;	x3 |= x4;	x4 ^= x2;	\
  	x2 ^= x3;	x3 ^= x0;	x0 |= x1;	\
  	x2 &= x0;	x0 ^= x4;	x4 ^= x3;	\
  	x3 &= x0;	x4 ^= x1;			\
  	x2 ^= x4;	x3 ^= x1;	x4 |= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
145
146
  	x4 ^= x1;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
148
  #define SI0(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  			x4  = x3;	x1 ^= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
150
  	x3 |= x1;	x4 ^= x1;	x0 = ~x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
  	x2 ^= x3;	x3 ^= x0;	x0 &= x1;	\
  	x0 ^= x2;	x2 &= x3;	x3 ^= x4;	\
  	x2 ^= x3;	x1 ^= x3;	x3 &= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
154
155
  	x1 ^= x0;	x0 ^= x2;	x4 ^= x3;	\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
157
  #define SI1(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  	x1 ^= x3;	x4  = x0;			\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
159
  	x0 ^= x2;	x2 = ~x2;	x4 |= x1;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
161
162
163
  	x4 ^= x3;	x3 &= x1;	x1 ^= x2;	\
  	x2 &= x4;	x4 ^= x1;	x1 |= x3;	\
  	x3 ^= x0;	x2 ^= x0;	x0 |= x4;	\
  	x2 ^= x4;	x1 ^= x0;			\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
164
165
  	x4 ^= x1;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
167
168
  #define SI2(x0, x1, x2, x3, x4) ({			\
  	x2 ^= x1;	x4  = x3;	x3 = ~x3;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
170
171
172
  	x3 |= x2;	x2 ^= x4;	x4 ^= x0;	\
  	x3 ^= x1;	x1 |= x2;	x2 ^= x0;	\
  	x1 ^= x4;	x4 |= x3;	x2 ^= x3;	\
  	x4 ^= x2;	x2 &= x1;			\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
173
174
  	x2 ^= x3;	x3 ^= x4;	x4 ^= x0;	\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
176
  #define SI3(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
180
181
182
  					x2 ^= x1;	\
  	x4  = x1;	x1 &= x2;			\
  	x1 ^= x0;	x0 |= x4;	x4 ^= x3;	\
  	x0 ^= x3;	x3 |= x1;	x1 ^= x2;	\
  	x1 ^= x3;	x0 ^= x2;	x2 ^= x3;	\
  	x3 &= x1;	x1 ^= x0;	x0 &= x2;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
183
184
  	x4 ^= x3;	x3 ^= x0;	x0 ^= x1;	\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
186
  #define SI4(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
  	x2 ^= x3;	x4  = x0;	x0 &= x1;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
188
  	x0 ^= x2;	x2 |= x3;	x4 = ~x4;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
191
192
  	x1 ^= x0;	x0 ^= x2;	x2 &= x4;	\
  	x2 ^= x0;	x0 |= x4;			\
  	x0 ^= x3;	x3 &= x2;			\
  	x4 ^= x3;	x3 ^= x1;	x1 &= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
193
194
  	x4 ^= x1;	x0 ^= x3;			\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
196
  #define SI5(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
  			x4  = x1;	x1 |= x2;	\
  	x2 ^= x4;	x1 ^= x3;	x3 &= x4;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
199
  	x2 ^= x3;	x3 |= x0;	x0 = ~x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
  	x3 ^= x2;	x2 |= x0;	x4 ^= x1;	\
  	x2 ^= x4;	x4 &= x0;	x0 ^= x1;	\
  	x1 ^= x3;	x0 &= x2;	x2 ^= x3;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
203
204
  	x0 ^= x2;	x2 ^= x4;	x4 ^= x3;	\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
206
  #define SI6(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
  			x0 ^= x2;			\
  	x4  = x0;	x0 &= x3;	x2 ^= x3;	\
  	x0 ^= x2;	x3 ^= x1;	x2 |= x4;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
210
  	x2 ^= x3;	x3 &= x0;	x0 = ~x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
  	x3 ^= x1;	x1 &= x2;	x4 ^= x0;	\
  	x3 ^= x4;	x4 ^= x2;	x0 ^= x1;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
213
214
  	x2 ^= x0;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215

7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
216
  #define SI7(x0, x1, x2, x3, x4) ({			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
  	x4  = x3;	x3 &= x0;	x0 ^= x2;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
218
  	x2 |= x4;	x4 ^= x1;	x0 = ~x0;	\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
220
221
222
  	x1 |= x3;	x4 ^= x0;	x0 &= x2;	\
  	x0 ^= x1;	x1 &= x2;	x3 ^= x2;	\
  	x4 ^= x3;	x2 &= x3;	x3 |= x0;	\
  	x1 ^= x4;	x3 ^= x4;	x4 &= x0;	\
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
223
224
  	x4 ^= x2;					\
  	})
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225

473971187   Arnd Bergmann   crypto: serpent -...
226
227
228
229
230
231
232
  /*
   * both gcc and clang have misoptimized this function in the past,
   * producing horrible object code from spilling temporary variables
   * on the stack. Forcing this part out of line avoids that.
   */
  static noinline void __serpent_setkey_sbox(u32 r0, u32 r1, u32 r2,
  					   u32 r3, u32 r4, u32 *k)
c871c10e4   Arnd Bergmann   crypto: serpent -...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
  {
  	k += 100;
  	S3(r3, r4, r0, r1, r2); store_and_load_keys(r1, r2, r4, r3, 28, 24);
  	S4(r1, r2, r4, r3, r0); store_and_load_keys(r2, r4, r3, r0, 24, 20);
  	S5(r2, r4, r3, r0, r1); store_and_load_keys(r1, r2, r4, r0, 20, 16);
  	S6(r1, r2, r4, r0, r3); store_and_load_keys(r4, r3, r2, r0, 16, 12);
  	S7(r4, r3, r2, r0, r1); store_and_load_keys(r1, r2, r0, r4, 12, 8);
  	S0(r1, r2, r0, r4, r3); store_and_load_keys(r0, r2, r4, r1, 8, 4);
  	S1(r0, r2, r4, r1, r3); store_and_load_keys(r3, r4, r1, r0, 4, 0);
  	S2(r3, r4, r1, r0, r2); store_and_load_keys(r2, r4, r3, r0, 0, -4);
  	S3(r2, r4, r3, r0, r1); store_and_load_keys(r0, r1, r4, r2, -4, -8);
  	S4(r0, r1, r4, r2, r3); store_and_load_keys(r1, r4, r2, r3, -8, -12);
  	S5(r1, r4, r2, r3, r0); store_and_load_keys(r0, r1, r4, r3, -12, -16);
  	S6(r0, r1, r4, r3, r2); store_and_load_keys(r4, r2, r1, r3, -16, -20);
  	S7(r4, r2, r1, r3, r0); store_and_load_keys(r0, r1, r3, r4, -20, -24);
  	S0(r0, r1, r3, r4, r2); store_and_load_keys(r3, r1, r4, r0, -24, -28);
  	k -= 50;
  	S1(r3, r1, r4, r0, r2); store_and_load_keys(r2, r4, r0, r3, 22, 18);
  	S2(r2, r4, r0, r3, r1); store_and_load_keys(r1, r4, r2, r3, 18, 14);
  	S3(r1, r4, r2, r3, r0); store_and_load_keys(r3, r0, r4, r1, 14, 10);
  	S4(r3, r0, r4, r1, r2); store_and_load_keys(r0, r4, r1, r2, 10, 6);
  	S5(r0, r4, r1, r2, r3); store_and_load_keys(r3, r0, r4, r2, 6, 2);
  	S6(r3, r0, r4, r2, r1); store_and_load_keys(r4, r1, r0, r2, 2, -2);
  	S7(r4, r1, r0, r2, r3); store_and_load_keys(r3, r0, r2, r4, -2, -6);
  	S0(r3, r0, r2, r4, r1); store_and_load_keys(r2, r0, r4, r3, -6, -10);
  	S1(r2, r0, r4, r3, r1); store_and_load_keys(r1, r4, r3, r2, -10, -14);
  	S2(r1, r4, r3, r2, r0); store_and_load_keys(r0, r4, r1, r2, -14, -18);
  	S3(r0, r4, r1, r2, r3); store_and_load_keys(r2, r3, r4, r0, -18, -22);
  	k -= 50;
  	S4(r2, r3, r4, r0, r1); store_and_load_keys(r3, r4, r0, r1, 28, 24);
  	S5(r3, r4, r0, r1, r2); store_and_load_keys(r2, r3, r4, r1, 24, 20);
  	S6(r2, r3, r4, r1, r0); store_and_load_keys(r4, r0, r3, r1, 20, 16);
  	S7(r4, r0, r3, r1, r2); store_and_load_keys(r2, r3, r1, r4, 16, 12);
  	S0(r2, r3, r1, r4, r0); store_and_load_keys(r1, r3, r4, r2, 12, 8);
  	S1(r1, r3, r4, r2, r0); store_and_load_keys(r0, r4, r2, r1, 8, 4);
  	S2(r0, r4, r2, r1, r3); store_and_load_keys(r3, r4, r0, r1, 4, 0);
  	S3(r3, r4, r0, r1, r2); storekeys(r1, r2, r4, r3, 0);
  }
18482053f   Jussi Kivilinna   crypto: serpent-s...
271
272
  int __serpent_setkey(struct serpent_ctx *ctx, const u8 *key,
  		     unsigned int keylen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
  {
6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
274
  	u32 *k = ctx->expkey;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
  	u8  *k8 = (u8 *)k;
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
276
  	u32 r0, r1, r2, r3, r4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  	/* Copy key, add padding */
  
  	for (i = 0; i < keylen; ++i)
  		k8[i] = key[i];
  	if (i < SERPENT_MAX_KEY_SIZE)
  		k8[i++] = 1;
  	while (i < SERPENT_MAX_KEY_SIZE)
  		k8[i++] = 0;
  
  	/* Expand key using polynomial */
  
  	r0 = le32_to_cpu(k[3]);
  	r1 = le32_to_cpu(k[4]);
  	r2 = le32_to_cpu(k[5]);
  	r3 = le32_to_cpu(k[6]);
  	r4 = le32_to_cpu(k[7]);
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
  	keyiter(le32_to_cpu(k[0]), r0, r4, r2, 0, 0);
  	keyiter(le32_to_cpu(k[1]), r1, r0, r3, 1, 1);
  	keyiter(le32_to_cpu(k[2]), r2, r1, r4, 2, 2);
  	keyiter(le32_to_cpu(k[3]), r3, r2, r0, 3, 3);
  	keyiter(le32_to_cpu(k[4]), r4, r3, r1, 4, 4);
  	keyiter(le32_to_cpu(k[5]), r0, r4, r2, 5, 5);
  	keyiter(le32_to_cpu(k[6]), r1, r0, r3, 6, 6);
  	keyiter(le32_to_cpu(k[7]), r2, r1, r4, 7, 7);
  
  	keyiter(k[0], r3, r2, r0, 8, 8);
  	keyiter(k[1], r4, r3, r1, 9, 9);
  	keyiter(k[2], r0, r4, r2, 10, 10);
  	keyiter(k[3], r1, r0, r3, 11, 11);
  	keyiter(k[4], r2, r1, r4, 12, 12);
  	keyiter(k[5], r3, r2, r0, 13, 13);
  	keyiter(k[6], r4, r3, r1, 14, 14);
  	keyiter(k[7], r0, r4, r2, 15, 15);
  	keyiter(k[8], r1, r0, r3, 16, 16);
  	keyiter(k[9], r2, r1, r4, 17, 17);
  	keyiter(k[10], r3, r2, r0, 18, 18);
  	keyiter(k[11], r4, r3, r1, 19, 19);
  	keyiter(k[12], r0, r4, r2, 20, 20);
  	keyiter(k[13], r1, r0, r3, 21, 21);
  	keyiter(k[14], r2, r1, r4, 22, 22);
  	keyiter(k[15], r3, r2, r0, 23, 23);
  	keyiter(k[16], r4, r3, r1, 24, 24);
  	keyiter(k[17], r0, r4, r2, 25, 25);
  	keyiter(k[18], r1, r0, r3, 26, 26);
  	keyiter(k[19], r2, r1, r4, 27, 27);
  	keyiter(k[20], r3, r2, r0, 28, 28);
  	keyiter(k[21], r4, r3, r1, 29, 29);
  	keyiter(k[22], r0, r4, r2, 30, 30);
  	keyiter(k[23], r1, r0, r3, 31, 31);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
  
  	k += 50;
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  	keyiter(k[-26], r2, r1, r4, 32, -18);
  	keyiter(k[-25], r3, r2, r0, 33, -17);
  	keyiter(k[-24], r4, r3, r1, 34, -16);
  	keyiter(k[-23], r0, r4, r2, 35, -15);
  	keyiter(k[-22], r1, r0, r3, 36, -14);
  	keyiter(k[-21], r2, r1, r4, 37, -13);
  	keyiter(k[-20], r3, r2, r0, 38, -12);
  	keyiter(k[-19], r4, r3, r1, 39, -11);
  	keyiter(k[-18], r0, r4, r2, 40, -10);
  	keyiter(k[-17], r1, r0, r3, 41, -9);
  	keyiter(k[-16], r2, r1, r4, 42, -8);
  	keyiter(k[-15], r3, r2, r0, 43, -7);
  	keyiter(k[-14], r4, r3, r1, 44, -6);
  	keyiter(k[-13], r0, r4, r2, 45, -5);
  	keyiter(k[-12], r1, r0, r3, 46, -4);
  	keyiter(k[-11], r2, r1, r4, 47, -3);
  	keyiter(k[-10], r3, r2, r0, 48, -2);
  	keyiter(k[-9], r4, r3, r1, 49, -1);
  	keyiter(k[-8], r0, r4, r2, 50, 0);
  	keyiter(k[-7], r1, r0, r3, 51, 1);
  	keyiter(k[-6], r2, r1, r4, 52, 2);
  	keyiter(k[-5], r3, r2, r0, 53, 3);
  	keyiter(k[-4], r4, r3, r1, 54, 4);
  	keyiter(k[-3], r0, r4, r2, 55, 5);
  	keyiter(k[-2], r1, r0, r3, 56, 6);
  	keyiter(k[-1], r2, r1, r4, 57, 7);
  	keyiter(k[0], r3, r2, r0, 58, 8);
  	keyiter(k[1], r4, r3, r1, 59, 9);
  	keyiter(k[2], r0, r4, r2, 60, 10);
  	keyiter(k[3], r1, r0, r3, 61, 11);
  	keyiter(k[4], r2, r1, r4, 62, 12);
  	keyiter(k[5], r3, r2, r0, 63, 13);
  	keyiter(k[6], r4, r3, r1, 64, 14);
  	keyiter(k[7], r0, r4, r2, 65, 15);
  	keyiter(k[8], r1, r0, r3, 66, 16);
  	keyiter(k[9], r2, r1, r4, 67, 17);
  	keyiter(k[10], r3, r2, r0, 68, 18);
  	keyiter(k[11], r4, r3, r1, 69, 19);
  	keyiter(k[12], r0, r4, r2, 70, 20);
  	keyiter(k[13], r1, r0, r3, 71, 21);
  	keyiter(k[14], r2, r1, r4, 72, 22);
  	keyiter(k[15], r3, r2, r0, 73, 23);
  	keyiter(k[16], r4, r3, r1, 74, 24);
  	keyiter(k[17], r0, r4, r2, 75, 25);
  	keyiter(k[18], r1, r0, r3, 76, 26);
  	keyiter(k[19], r2, r1, r4, 77, 27);
  	keyiter(k[20], r3, r2, r0, 78, 28);
  	keyiter(k[21], r4, r3, r1, 79, 29);
  	keyiter(k[22], r0, r4, r2, 80, 30);
  	keyiter(k[23], r1, r0, r3, 81, 31);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
  
  	k += 50;
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
  	keyiter(k[-26], r2, r1, r4, 82, -18);
  	keyiter(k[-25], r3, r2, r0, 83, -17);
  	keyiter(k[-24], r4, r3, r1, 84, -16);
  	keyiter(k[-23], r0, r4, r2, 85, -15);
  	keyiter(k[-22], r1, r0, r3, 86, -14);
  	keyiter(k[-21], r2, r1, r4, 87, -13);
  	keyiter(k[-20], r3, r2, r0, 88, -12);
  	keyiter(k[-19], r4, r3, r1, 89, -11);
  	keyiter(k[-18], r0, r4, r2, 90, -10);
  	keyiter(k[-17], r1, r0, r3, 91, -9);
  	keyiter(k[-16], r2, r1, r4, 92, -8);
  	keyiter(k[-15], r3, r2, r0, 93, -7);
  	keyiter(k[-14], r4, r3, r1, 94, -6);
  	keyiter(k[-13], r0, r4, r2, 95, -5);
  	keyiter(k[-12], r1, r0, r3, 96, -4);
  	keyiter(k[-11], r2, r1, r4, 97, -3);
  	keyiter(k[-10], r3, r2, r0, 98, -2);
  	keyiter(k[-9], r4, r3, r1, 99, -1);
  	keyiter(k[-8], r0, r4, r2, 100, 0);
  	keyiter(k[-7], r1, r0, r3, 101, 1);
  	keyiter(k[-6], r2, r1, r4, 102, 2);
  	keyiter(k[-5], r3, r2, r0, 103, 3);
  	keyiter(k[-4], r4, r3, r1, 104, 4);
  	keyiter(k[-3], r0, r4, r2, 105, 5);
  	keyiter(k[-2], r1, r0, r3, 106, 6);
  	keyiter(k[-1], r2, r1, r4, 107, 7);
  	keyiter(k[0], r3, r2, r0, 108, 8);
  	keyiter(k[1], r4, r3, r1, 109, 9);
  	keyiter(k[2], r0, r4, r2, 110, 10);
  	keyiter(k[3], r1, r0, r3, 111, 11);
  	keyiter(k[4], r2, r1, r4, 112, 12);
  	keyiter(k[5], r3, r2, r0, 113, 13);
  	keyiter(k[6], r4, r3, r1, 114, 14);
  	keyiter(k[7], r0, r4, r2, 115, 15);
  	keyiter(k[8], r1, r0, r3, 116, 16);
  	keyiter(k[9], r2, r1, r4, 117, 17);
  	keyiter(k[10], r3, r2, r0, 118, 18);
  	keyiter(k[11], r4, r3, r1, 119, 19);
  	keyiter(k[12], r0, r4, r2, 120, 20);
  	keyiter(k[13], r1, r0, r3, 121, 21);
  	keyiter(k[14], r2, r1, r4, 122, 22);
  	keyiter(k[15], r3, r2, r0, 123, 23);
  	keyiter(k[16], r4, r3, r1, 124, 24);
  	keyiter(k[17], r0, r4, r2, 125, 25);
  	keyiter(k[18], r1, r0, r3, 126, 26);
  	keyiter(k[19], r2, r1, r4, 127, 27);
  	keyiter(k[20], r3, r2, r0, 128, 28);
  	keyiter(k[21], r4, r3, r1, 129, 29);
  	keyiter(k[22], r0, r4, r2, 130, 30);
  	keyiter(k[23], r1, r0, r3, 131, 31);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
432
  
  	/* Apply S-boxes */
c871c10e4   Arnd Bergmann   crypto: serpent -...
433
  	__serpent_setkey_sbox(r0, r1, r2, r3, r4, ctx->expkey);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
436
  
  	return 0;
  }
18482053f   Jussi Kivilinna   crypto: serpent-s...
437
438
439
440
441
442
  EXPORT_SYMBOL_GPL(__serpent_setkey);
  
  int serpent_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
  {
  	return __serpent_setkey(crypto_tfm_ctx(tfm), key, keylen);
  }
bc83b8299   Jussi Kivilinna   crypto: serpent -...
443
  EXPORT_SYMBOL_GPL(serpent_setkey);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444

9c1e8836e   Kees Cook   crypto: x86 - Reg...
445
  void __serpent_encrypt(const void *c, u8 *dst, const u8 *src)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  {
9c1e8836e   Kees Cook   crypto: x86 - Reg...
447
  	const struct serpent_ctx *ctx = c;
bc83b8299   Jussi Kivilinna   crypto: serpent -...
448
  	const u32 *k = ctx->expkey;
d08f74e58   Alexey Dobriyan   [PATCH] serpent: ...
449
450
451
  	const __le32 *s = (const __le32 *)src;
  	__le32	*d = (__le32 *)dst;
  	u32	r0, r1, r2, r3, r4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
454
455
456
457
458
459
460
461
  
  /*
   * Note: The conversions between u8* and u32* might cause trouble
   * on architectures with stricter alignment rules than x86
   */
  
  	r0 = le32_to_cpu(s[0]);
  	r1 = le32_to_cpu(s[1]);
  	r2 = le32_to_cpu(s[2]);
  	r3 = le32_to_cpu(s[3]);
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
  					K(r0, r1, r2, r3, 0);
  	S0(r0, r1, r2, r3, r4);		LK(r2, r1, r3, r0, r4, 1);
  	S1(r2, r1, r3, r0, r4);		LK(r4, r3, r0, r2, r1, 2);
  	S2(r4, r3, r0, r2, r1);		LK(r1, r3, r4, r2, r0, 3);
  	S3(r1, r3, r4, r2, r0);		LK(r2, r0, r3, r1, r4, 4);
  	S4(r2, r0, r3, r1, r4);		LK(r0, r3, r1, r4, r2, 5);
  	S5(r0, r3, r1, r4, r2);		LK(r2, r0, r3, r4, r1, 6);
  	S6(r2, r0, r3, r4, r1);		LK(r3, r1, r0, r4, r2, 7);
  	S7(r3, r1, r0, r4, r2);		LK(r2, r0, r4, r3, r1, 8);
  	S0(r2, r0, r4, r3, r1);		LK(r4, r0, r3, r2, r1, 9);
  	S1(r4, r0, r3, r2, r1);		LK(r1, r3, r2, r4, r0, 10);
  	S2(r1, r3, r2, r4, r0);		LK(r0, r3, r1, r4, r2, 11);
  	S3(r0, r3, r1, r4, r2);		LK(r4, r2, r3, r0, r1, 12);
  	S4(r4, r2, r3, r0, r1);		LK(r2, r3, r0, r1, r4, 13);
  	S5(r2, r3, r0, r1, r4);		LK(r4, r2, r3, r1, r0, 14);
  	S6(r4, r2, r3, r1, r0);		LK(r3, r0, r2, r1, r4, 15);
  	S7(r3, r0, r2, r1, r4);		LK(r4, r2, r1, r3, r0, 16);
  	S0(r4, r2, r1, r3, r0);		LK(r1, r2, r3, r4, r0, 17);
  	S1(r1, r2, r3, r4, r0);		LK(r0, r3, r4, r1, r2, 18);
  	S2(r0, r3, r4, r1, r2);		LK(r2, r3, r0, r1, r4, 19);
  	S3(r2, r3, r0, r1, r4);		LK(r1, r4, r3, r2, r0, 20);
  	S4(r1, r4, r3, r2, r0);		LK(r4, r3, r2, r0, r1, 21);
  	S5(r4, r3, r2, r0, r1);		LK(r1, r4, r3, r0, r2, 22);
  	S6(r1, r4, r3, r0, r2);		LK(r3, r2, r4, r0, r1, 23);
  	S7(r3, r2, r4, r0, r1);		LK(r1, r4, r0, r3, r2, 24);
  	S0(r1, r4, r0, r3, r2);		LK(r0, r4, r3, r1, r2, 25);
  	S1(r0, r4, r3, r1, r2);		LK(r2, r3, r1, r0, r4, 26);
  	S2(r2, r3, r1, r0, r4);		LK(r4, r3, r2, r0, r1, 27);
  	S3(r4, r3, r2, r0, r1);		LK(r0, r1, r3, r4, r2, 28);
  	S4(r0, r1, r3, r4, r2);		LK(r1, r3, r4, r2, r0, 29);
  	S5(r1, r3, r4, r2, r0);		LK(r0, r1, r3, r2, r4, 30);
  	S6(r0, r1, r3, r2, r4);		LK(r3, r4, r1, r2, r0, 31);
  	S7(r3, r4, r1, r2, r0);		K(r0, r1, r2, r3, 32);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
497
498
499
500
  
  	d[0] = cpu_to_le32(r0);
  	d[1] = cpu_to_le32(r1);
  	d[2] = cpu_to_le32(r2);
  	d[3] = cpu_to_le32(r3);
  }
bc83b8299   Jussi Kivilinna   crypto: serpent -...
501
  EXPORT_SYMBOL_GPL(__serpent_encrypt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502

bc83b8299   Jussi Kivilinna   crypto: serpent -...
503
  static void serpent_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
  {
6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
505
  	struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
bc83b8299   Jussi Kivilinna   crypto: serpent -...
506
507
508
  
  	__serpent_encrypt(ctx, dst, src);
  }
9c1e8836e   Kees Cook   crypto: x86 - Reg...
509
  void __serpent_decrypt(const void *c, u8 *dst, const u8 *src)
bc83b8299   Jussi Kivilinna   crypto: serpent -...
510
  {
9c1e8836e   Kees Cook   crypto: x86 - Reg...
511
  	const struct serpent_ctx *ctx = c;
bc83b8299   Jussi Kivilinna   crypto: serpent -...
512
  	const u32 *k = ctx->expkey;
d08f74e58   Alexey Dobriyan   [PATCH] serpent: ...
513
514
515
  	const __le32 *s = (const __le32 *)src;
  	__le32	*d = (__le32 *)dst;
  	u32	r0, r1, r2, r3, r4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
517
518
519
520
  
  	r0 = le32_to_cpu(s[0]);
  	r1 = le32_to_cpu(s[1]);
  	r2 = le32_to_cpu(s[2]);
  	r3 = le32_to_cpu(s[3]);
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
  					K(r0, r1, r2, r3, 32);
  	SI7(r0, r1, r2, r3, r4);	KL(r1, r3, r0, r4, r2, 31);
  	SI6(r1, r3, r0, r4, r2);	KL(r0, r2, r4, r1, r3, 30);
  	SI5(r0, r2, r4, r1, r3);	KL(r2, r3, r0, r4, r1, 29);
  	SI4(r2, r3, r0, r4, r1);	KL(r2, r0, r1, r4, r3, 28);
  	SI3(r2, r0, r1, r4, r3);	KL(r1, r2, r3, r4, r0, 27);
  	SI2(r1, r2, r3, r4, r0);	KL(r2, r0, r4, r3, r1, 26);
  	SI1(r2, r0, r4, r3, r1);	KL(r1, r0, r4, r3, r2, 25);
  	SI0(r1, r0, r4, r3, r2);	KL(r4, r2, r0, r1, r3, 24);
  	SI7(r4, r2, r0, r1, r3);	KL(r2, r1, r4, r3, r0, 23);
  	SI6(r2, r1, r4, r3, r0);	KL(r4, r0, r3, r2, r1, 22);
  	SI5(r4, r0, r3, r2, r1);	KL(r0, r1, r4, r3, r2, 21);
  	SI4(r0, r1, r4, r3, r2);	KL(r0, r4, r2, r3, r1, 20);
  	SI3(r0, r4, r2, r3, r1);	KL(r2, r0, r1, r3, r4, 19);
  	SI2(r2, r0, r1, r3, r4);	KL(r0, r4, r3, r1, r2, 18);
  	SI1(r0, r4, r3, r1, r2);	KL(r2, r4, r3, r1, r0, 17);
  	SI0(r2, r4, r3, r1, r0);	KL(r3, r0, r4, r2, r1, 16);
  	SI7(r3, r0, r4, r2, r1);	KL(r0, r2, r3, r1, r4, 15);
  	SI6(r0, r2, r3, r1, r4);	KL(r3, r4, r1, r0, r2, 14);
  	SI5(r3, r4, r1, r0, r2);	KL(r4, r2, r3, r1, r0, 13);
  	SI4(r4, r2, r3, r1, r0);	KL(r4, r3, r0, r1, r2, 12);
  	SI3(r4, r3, r0, r1, r2);	KL(r0, r4, r2, r1, r3, 11);
  	SI2(r0, r4, r2, r1, r3);	KL(r4, r3, r1, r2, r0, 10);
  	SI1(r4, r3, r1, r2, r0);	KL(r0, r3, r1, r2, r4, 9);
  	SI0(r0, r3, r1, r2, r4);	KL(r1, r4, r3, r0, r2, 8);
  	SI7(r1, r4, r3, r0, r2);	KL(r4, r0, r1, r2, r3, 7);
  	SI6(r4, r0, r1, r2, r3);	KL(r1, r3, r2, r4, r0, 6);
  	SI5(r1, r3, r2, r4, r0);	KL(r3, r0, r1, r2, r4, 5);
  	SI4(r3, r0, r1, r2, r4);	KL(r3, r1, r4, r2, r0, 4);
  	SI3(r3, r1, r4, r2, r0);	KL(r4, r3, r0, r2, r1, 3);
  	SI2(r4, r3, r0, r2, r1);	KL(r3, r1, r2, r0, r4, 2);
  	SI1(r3, r1, r2, r0, r4);	KL(r4, r1, r2, r0, r3, 1);
  	SI0(r4, r1, r2, r0, r3);	K(r2, r3, r1, r4, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
555
556
557
558
559
  
  	d[0] = cpu_to_le32(r2);
  	d[1] = cpu_to_le32(r3);
  	d[2] = cpu_to_le32(r1);
  	d[3] = cpu_to_le32(r4);
  }
bc83b8299   Jussi Kivilinna   crypto: serpent -...
560
561
562
563
564
565
566
567
  EXPORT_SYMBOL_GPL(__serpent_decrypt);
  
  static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
  {
  	struct serpent_ctx *ctx = crypto_tfm_ctx(tfm);
  
  	__serpent_decrypt(ctx, dst, src);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568

6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
569
  static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
560c06ae1   Herbert Xu   [CRYPTO] api: Get...
570
  			  unsigned int keylen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
571
572
573
  {
  	u8 rev_key[SERPENT_MAX_KEY_SIZE];
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
575
  	for (i = 0; i < keylen; ++i)
  		rev_key[keylen - i - 1] = key[i];
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
576

560c06ae1   Herbert Xu   [CRYPTO] api: Get...
577
  	return serpent_setkey(tfm, rev_key, keylen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
  }
6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
579
  static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
581
582
583
584
585
586
587
588
589
  {
  	const u32 * const s = (const u32 * const)src;
  	u32 * const d = (u32 * const)dst;
  
  	u32 rs[4], rd[4];
  
  	rs[0] = swab32(s[3]);
  	rs[1] = swab32(s[2]);
  	rs[2] = swab32(s[1]);
  	rs[3] = swab32(s[0]);
6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
590
  	serpent_encrypt(tfm, (u8 *)rd, (u8 *)rs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
593
594
595
596
  
  	d[0] = swab32(rd[3]);
  	d[1] = swab32(rd[2]);
  	d[2] = swab32(rd[1]);
  	d[3] = swab32(rd[0]);
  }
6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
597
  static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
598
599
600
601
602
603
604
605
606
607
  {
  	const u32 * const s = (const u32 * const)src;
  	u32 * const d = (u32 * const)dst;
  
  	u32 rs[4], rd[4];
  
  	rs[0] = swab32(s[3]);
  	rs[1] = swab32(s[2]);
  	rs[2] = swab32(s[1]);
  	rs[3] = swab32(s[0]);
6c2bb98bc   Herbert Xu   [CRYPTO] all: Pas...
608
  	serpent_decrypt(tfm, (u8 *)rd, (u8 *)rs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
610
611
612
613
614
  
  	d[0] = swab32(rd[3]);
  	d[1] = swab32(rd[2]);
  	d[2] = swab32(rd[1]);
  	d[3] = swab32(rd[0]);
  }
bbc406b9d   Jussi Kivilinna   crypto: serpent -...
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
  static struct crypto_alg srp_algs[2] = { {
  	.cra_name		=	"serpent",
  	.cra_driver_name	=	"serpent-generic",
  	.cra_priority		=	100,
  	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
  	.cra_blocksize		=	SERPENT_BLOCK_SIZE,
  	.cra_ctxsize		=	sizeof(struct serpent_ctx),
  	.cra_alignmask		=	3,
  	.cra_module		=	THIS_MODULE,
  	.cra_u			=	{ .cipher = {
  	.cia_min_keysize	=	SERPENT_MIN_KEY_SIZE,
  	.cia_max_keysize	=	SERPENT_MAX_KEY_SIZE,
  	.cia_setkey		=	serpent_setkey,
  	.cia_encrypt		=	serpent_encrypt,
  	.cia_decrypt		=	serpent_decrypt } }
  }, {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  	.cra_name		=	"tnepres",
d6ebf5286   Eric Biggers   crypto: make all ...
632
  	.cra_driver_name	=	"tnepres-generic",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
  	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
  	.cra_blocksize		=	SERPENT_BLOCK_SIZE,
  	.cra_ctxsize		=	sizeof(struct serpent_ctx),
a429d2609   Herbert Xu   [CRYPTO] cipher: ...
636
  	.cra_alignmask		=	3,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
  	.cra_module		=	THIS_MODULE,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
639
640
  	.cra_u			=	{ .cipher = {
  	.cia_min_keysize	=	SERPENT_MIN_KEY_SIZE,
  	.cia_max_keysize	=	SERPENT_MAX_KEY_SIZE,
7f4e3e3fa   Jussi Kivilinna   crypto: serpent -...
641
642
643
  	.cia_setkey		=	tnepres_setkey,
  	.cia_encrypt		=	tnepres_encrypt,
  	.cia_decrypt		=	tnepres_decrypt } }
bbc406b9d   Jussi Kivilinna   crypto: serpent -...
644
  } };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645

3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
646
  static int __init serpent_mod_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
  {
bbc406b9d   Jussi Kivilinna   crypto: serpent -...
648
  	return crypto_register_algs(srp_algs, ARRAY_SIZE(srp_algs));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
  }
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
650
  static void __exit serpent_mod_fini(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  {
bbc406b9d   Jussi Kivilinna   crypto: serpent -...
652
  	crypto_unregister_algs(srp_algs, ARRAY_SIZE(srp_algs));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
  }
c4741b230   Eric Biggers   crypto: run initc...
654
  subsys_initcall(serpent_mod_init);
3af5b90bd   Kamalesh Babulal   [CRYPTO] all: Cle...
655
  module_exit(serpent_mod_fini);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
658
659
  
  MODULE_LICENSE("GPL");
  MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm");
  MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
5d26a105b   Kees Cook   crypto: prefix mo...
660
661
  MODULE_ALIAS_CRYPTO("tnepres");
  MODULE_ALIAS_CRYPTO("serpent");
3e14dcf7c   Mathias Krause   crypto: add missi...
662
  MODULE_ALIAS_CRYPTO("serpent-generic");