/src/nettle-with-mini-gmp/serpent-set-key.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* serpent-set-key.c |
2 | | |
3 | | The serpent block cipher. |
4 | | |
5 | | For more details on this algorithm, see the Serpent website at |
6 | | http://www.cl.cam.ac.uk/~rja14/serpent.html |
7 | | |
8 | | Copyright (C) 2011, 2014 Niels Möller |
9 | | Copyright (C) 2010, 2011 Simon Josefsson |
10 | | Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. |
11 | | |
12 | | This file is part of GNU Nettle. |
13 | | |
14 | | GNU Nettle is free software: you can redistribute it and/or |
15 | | modify it under the terms of either: |
16 | | |
17 | | * the GNU Lesser General Public License as published by the Free |
18 | | Software Foundation; either version 3 of the License, or (at your |
19 | | option) any later version. |
20 | | |
21 | | or |
22 | | |
23 | | * the GNU General Public License as published by the Free |
24 | | Software Foundation; either version 2 of the License, or (at your |
25 | | option) any later version. |
26 | | |
27 | | or both in parallel, as here. |
28 | | |
29 | | GNU Nettle is distributed in the hope that it will be useful, |
30 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
31 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
32 | | General Public License for more details. |
33 | | |
34 | | You should have received copies of the GNU General Public License and |
35 | | the GNU Lesser General Public License along with this program. If |
36 | | not, see http://www.gnu.org/licenses/. |
37 | | */ |
38 | | |
39 | | /* This file is derived from cipher/serpent.c in Libgcrypt v1.4.6. |
40 | | The adaption to Nettle was made by Simon Josefsson on 2010-12-07 |
41 | | with final touches on 2011-05-30. Changes include replacing |
42 | | libgcrypt with nettle in the license template, renaming |
43 | | serpent_context to serpent_ctx, renaming u32 to uint32_t, removing |
44 | | libgcrypt stubs and selftests, modifying entry function prototypes, |
45 | | using FOR_BLOCKS to iterate through data in encrypt/decrypt, using |
46 | | LE_READ_UINT32 and LE_WRITE_UINT32 to access data in |
47 | | encrypt/decrypt, and running indent on the code. */ |
48 | | |
49 | | #if HAVE_CONFIG_H |
50 | | #include "config.h" |
51 | | #endif |
52 | | |
53 | | #include <assert.h> |
54 | | #include <limits.h> |
55 | | |
56 | | #include "serpent.h" |
57 | | |
58 | | #include "macros.h" |
59 | | #include "serpent-internal.h" |
60 | | |
61 | | /* Magic number, used during generating of the subkeys. */ |
62 | 39.3k | #define PHI 0x9E3779B9 |
63 | | |
64 | | /* These are the S-Boxes of Serpent. They are copied from Serpents |
65 | | reference implementation (the optimized one, contained in |
66 | | `floppy2') and are therefore: |
67 | | |
68 | | Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen. |
69 | | |
70 | | To quote the Serpent homepage |
71 | | (http://www.cl.cam.ac.uk/~rja14/serpent.html): |
72 | | |
73 | | "Serpent is now completely in the public domain, and we impose no |
74 | | restrictions on its use. This was announced on the 21st August at |
75 | | the First AES Candidate Conference. The optimised implementations |
76 | | in the submission package are now under the GNU PUBLIC LICENSE |
77 | | (GPL), although some comments in the code still say otherwise. You |
78 | | are welcome to use Serpent for any application." */ |
79 | | |
80 | | /* FIXME: Except when used within the key schedule, the inputs are not |
81 | | used after the substitution, and hence we could allow them to be |
82 | | destroyed. Can this freedom be used to optimize the sboxes? */ |
83 | | #define SBOX0(type, a, b, c, d, w, x, y, z) \ |
84 | 1.19k | do { \ |
85 | 1.19k | type t02, t03, t05, t06, t07, t08, t09; \ |
86 | 1.19k | type t11, t12, t13, t14, t15, t17, t01; \ |
87 | 1.19k | t01 = b ^ c ; \ |
88 | 1.19k | t02 = a | d ; \ |
89 | 1.19k | t03 = a ^ b ; \ |
90 | 1.19k | z = t02 ^ t01; \ |
91 | 1.19k | t05 = c | z ; \ |
92 | 1.19k | t06 = a ^ d ; \ |
93 | 1.19k | t07 = b | c ; \ |
94 | 1.19k | t08 = d & t05; \ |
95 | 1.19k | t09 = t03 & t07; \ |
96 | 1.19k | y = t09 ^ t08; \ |
97 | 1.19k | t11 = t09 & y ; \ |
98 | 1.19k | t12 = c ^ d ; \ |
99 | 1.19k | t13 = t07 ^ t11; \ |
100 | 1.19k | t14 = b & t06; \ |
101 | 1.19k | t15 = t06 ^ t13; \ |
102 | 1.19k | w = ~ t15; \ |
103 | 1.19k | t17 = w ^ t14; \ |
104 | 1.19k | x = t12 ^ t17; \ |
105 | 1.19k | } while (0) |
106 | | |
107 | | #define SBOX1(type, a, b, c, d, w, x, y, z) \ |
108 | 1.19k | do { \ |
109 | 1.19k | type t02, t03, t04, t05, t06, t07, t08; \ |
110 | 1.19k | type t10, t11, t12, t13, t16, t17, t01; \ |
111 | 1.19k | t01 = a | d ; \ |
112 | 1.19k | t02 = c ^ d ; \ |
113 | 1.19k | t03 = ~ b ; \ |
114 | 1.19k | t04 = a ^ c ; \ |
115 | 1.19k | t05 = a | t03; \ |
116 | 1.19k | t06 = d & t04; \ |
117 | 1.19k | t07 = t01 & t02; \ |
118 | 1.19k | t08 = b | t06; \ |
119 | 1.19k | y = t02 ^ t05; \ |
120 | 1.19k | t10 = t07 ^ t08; \ |
121 | 1.19k | t11 = t01 ^ t10; \ |
122 | 1.19k | t12 = y ^ t11; \ |
123 | 1.19k | t13 = b & d ; \ |
124 | 1.19k | z = ~ t10; \ |
125 | 1.19k | x = t13 ^ t12; \ |
126 | 1.19k | t16 = t10 | x ; \ |
127 | 1.19k | t17 = t05 & t16; \ |
128 | 1.19k | w = c ^ t17; \ |
129 | 1.19k | } while (0) |
130 | | |
131 | | #define SBOX2(type, a, b, c, d, w, x, y, z) \ |
132 | 1.19k | do { \ |
133 | 1.19k | type t02, t03, t05, t06, t07, t08; \ |
134 | 1.19k | type t09, t10, t12, t13, t14, t01; \ |
135 | 1.19k | t01 = a | c ; \ |
136 | 1.19k | t02 = a ^ b ; \ |
137 | 1.19k | t03 = d ^ t01; \ |
138 | 1.19k | w = t02 ^ t03; \ |
139 | 1.19k | t05 = c ^ w ; \ |
140 | 1.19k | t06 = b ^ t05; \ |
141 | 1.19k | t07 = b | t05; \ |
142 | 1.19k | t08 = t01 & t06; \ |
143 | 1.19k | t09 = t03 ^ t07; \ |
144 | 1.19k | t10 = t02 | t09; \ |
145 | 1.19k | x = t10 ^ t08; \ |
146 | 1.19k | t12 = a | d ; \ |
147 | 1.19k | t13 = t09 ^ x ; \ |
148 | 1.19k | t14 = b ^ t13; \ |
149 | 1.19k | z = ~ t09; \ |
150 | 1.19k | y = t12 ^ t14; \ |
151 | 1.19k | } while (0) |
152 | | |
153 | | #define SBOX3(type, a, b, c, d, w, x, y, z) \ |
154 | 1.49k | do { \ |
155 | 1.49k | type t02, t03, t04, t05, t06, t07, t08; \ |
156 | 1.49k | type t09, t10, t11, t13, t14, t15, t01; \ |
157 | 1.49k | t01 = a ^ c ; \ |
158 | 1.49k | t02 = a | d ; \ |
159 | 1.49k | t03 = a & d ; \ |
160 | 1.49k | t04 = t01 & t02; \ |
161 | 1.49k | t05 = b | t03; \ |
162 | 1.49k | t06 = a & b ; \ |
163 | 1.49k | t07 = d ^ t04; \ |
164 | 1.49k | t08 = c | t06; \ |
165 | 1.49k | t09 = b ^ t07; \ |
166 | 1.49k | t10 = d & t05; \ |
167 | 1.49k | t11 = t02 ^ t10; \ |
168 | 1.49k | z = t08 ^ t09; \ |
169 | 1.49k | t13 = d | z ; \ |
170 | 1.49k | t14 = a | t07; \ |
171 | 1.49k | t15 = b & t13; \ |
172 | 1.49k | y = t08 ^ t11; \ |
173 | 1.49k | w = t14 ^ t15; \ |
174 | 1.49k | x = t05 ^ t04; \ |
175 | 1.49k | } while (0) |
176 | | |
177 | | #define SBOX4(type, a, b, c, d, w, x, y, z) \ |
178 | 1.19k | do { \ |
179 | 1.19k | type t02, t03, t04, t05, t06, t08, t09; \ |
180 | 1.19k | type t10, t11, t12, t13, t14, t15, t16, t01; \ |
181 | 1.19k | t01 = a | b ; \ |
182 | 1.19k | t02 = b | c ; \ |
183 | 1.19k | t03 = a ^ t02; \ |
184 | 1.19k | t04 = b ^ d ; \ |
185 | 1.19k | t05 = d | t03; \ |
186 | 1.19k | t06 = d & t01; \ |
187 | 1.19k | z = t03 ^ t06; \ |
188 | 1.19k | t08 = z & t04; \ |
189 | 1.19k | t09 = t04 & t05; \ |
190 | 1.19k | t10 = c ^ t06; \ |
191 | 1.19k | t11 = b & c ; \ |
192 | 1.19k | t12 = t04 ^ t08; \ |
193 | 1.19k | t13 = t11 | t03; \ |
194 | 1.19k | t14 = t10 ^ t09; \ |
195 | 1.19k | t15 = a & t05; \ |
196 | 1.19k | t16 = t11 | t12; \ |
197 | 1.19k | y = t13 ^ t08; \ |
198 | 1.19k | x = t15 ^ t16; \ |
199 | 1.19k | w = ~ t14; \ |
200 | 1.19k | } while (0) |
201 | | |
202 | | #define SBOX5(type, a, b, c, d, w, x, y, z) \ |
203 | 1.19k | do { \ |
204 | 1.19k | type t02, t03, t04, t05, t07, t08, t09; \ |
205 | 1.19k | type t10, t11, t12, t13, t14, t01; \ |
206 | 1.19k | t01 = b ^ d ; \ |
207 | 1.19k | t02 = b | d ; \ |
208 | 1.19k | t03 = a & t01; \ |
209 | 1.19k | t04 = c ^ t02; \ |
210 | 1.19k | t05 = t03 ^ t04; \ |
211 | 1.19k | w = ~ t05; \ |
212 | 1.19k | t07 = a ^ t01; \ |
213 | 1.19k | t08 = d | w ; \ |
214 | 1.19k | t09 = b | t05; \ |
215 | 1.19k | t10 = d ^ t08; \ |
216 | 1.19k | t11 = b | t07; \ |
217 | 1.19k | t12 = t03 | w ; \ |
218 | 1.19k | t13 = t07 | t10; \ |
219 | 1.19k | t14 = t01 ^ t11; \ |
220 | 1.19k | y = t09 ^ t13; \ |
221 | 1.19k | x = t07 ^ t08; \ |
222 | 1.19k | z = t12 ^ t14; \ |
223 | 1.19k | } while (0) |
224 | | |
225 | | #define SBOX6(type, a, b, c, d, w, x, y, z) \ |
226 | 1.19k | do { \ |
227 | 1.19k | type t02, t03, t04, t05, t07, t08, t09, t10; \ |
228 | 1.19k | type t11, t12, t13, t15, t17, t18, t01; \ |
229 | 1.19k | t01 = a & d ; \ |
230 | 1.19k | t02 = b ^ c ; \ |
231 | 1.19k | t03 = a ^ d ; \ |
232 | 1.19k | t04 = t01 ^ t02; \ |
233 | 1.19k | t05 = b | c ; \ |
234 | 1.19k | x = ~ t04; \ |
235 | 1.19k | t07 = t03 & t05; \ |
236 | 1.19k | t08 = b & x ; \ |
237 | 1.19k | t09 = a | c ; \ |
238 | 1.19k | t10 = t07 ^ t08; \ |
239 | 1.19k | t11 = b | d ; \ |
240 | 1.19k | t12 = c ^ t11; \ |
241 | 1.19k | t13 = t09 ^ t10; \ |
242 | 1.19k | y = ~ t13; \ |
243 | 1.19k | t15 = x & t03; \ |
244 | 1.19k | z = t12 ^ t07; \ |
245 | 1.19k | t17 = a ^ b ; \ |
246 | 1.19k | t18 = y ^ t15; \ |
247 | 1.19k | w = t17 ^ t18; \ |
248 | 1.19k | } while (0) |
249 | | |
250 | | #define SBOX7(type, a, b, c, d, w, x, y, z) \ |
251 | 1.19k | do { \ |
252 | 1.19k | type t02, t03, t04, t05, t06, t08, t09, t10; \ |
253 | 1.19k | type t11, t13, t14, t15, t16, t17, t01; \ |
254 | 1.19k | t01 = a & c ; \ |
255 | 1.19k | t02 = ~ d ; \ |
256 | 1.19k | t03 = a & t02; \ |
257 | 1.19k | t04 = b | t01; \ |
258 | 1.19k | t05 = a & b ; \ |
259 | 1.19k | t06 = c ^ t04; \ |
260 | 1.19k | z = t03 ^ t06; \ |
261 | 1.19k | t08 = c | z ; \ |
262 | 1.19k | t09 = d | t05; \ |
263 | 1.19k | t10 = a ^ t08; \ |
264 | 1.19k | t11 = t04 & z ; \ |
265 | 1.19k | x = t09 ^ t10; \ |
266 | 1.19k | t13 = b ^ x ; \ |
267 | 1.19k | t14 = t01 ^ x ; \ |
268 | 1.19k | t15 = c ^ t05; \ |
269 | 1.19k | t16 = t11 | t13; \ |
270 | 1.19k | t17 = t02 | t14; \ |
271 | 1.19k | w = t15 ^ t17; \ |
272 | 1.19k | y = a ^ t16; \ |
273 | 1.19k | } while (0) |
274 | | |
275 | | /* Key schedule */ |
276 | | /* Note: Increments k */ |
277 | | #define KS_RECURRENCE(w, i, k) \ |
278 | 39.3k | do { \ |
279 | 39.3k | uint32_t _wn = (w)[(i)] ^ (w)[((i)+3)&7] ^ w[((i)+5)&7] \ |
280 | 39.3k | ^ w[((i)+7)&7] ^ PHI ^ (k)++; \ |
281 | 39.3k | ((w)[(i)] = ROTL32(11, _wn)); \ |
282 | 39.3k | } while (0) |
283 | | |
284 | | /* Note: Increments k four times and keys once */ |
285 | | #define KS(keys, s, w, i, k) \ |
286 | 9.83k | do { \ |
287 | 9.83k | KS_RECURRENCE(w, (i), (k)); \ |
288 | 9.83k | KS_RECURRENCE(w, (i)+1, (k)); \ |
289 | 9.83k | KS_RECURRENCE(w, (i)+2, (k)); \ |
290 | 9.83k | KS_RECURRENCE(w, (i)+3, (k)); \ |
291 | 9.83k | SBOX##s(uint32_t, w[(i)],w[(i)+1],w[(i)+2],w[(i)+3], \ |
292 | 9.83k | (*keys)[0],(*keys)[1],(*keys)[2],(*keys)[3]); \ |
293 | 9.83k | (keys)++; \ |
294 | 9.83k | } while (0) |
295 | | |
296 | | /* Pad user key and convert to an array of 8 uint32_t. */ |
297 | | static void |
298 | | serpent_key_pad (const uint8_t *key, unsigned int key_length, |
299 | | uint32_t *w) |
300 | 298 | { |
301 | 298 | unsigned int i; |
302 | | |
303 | 298 | assert (key_length <= SERPENT_MAX_KEY_SIZE); |
304 | | |
305 | 2.22k | for (i = 0; key_length >= 4; key_length -=4, key += 4) |
306 | 1.92k | w[i++] = LE_READ_UINT32(key); |
307 | | |
308 | 298 | if (i < 8) |
309 | 235 | { |
310 | | /* Key must be padded according to the Serpent specification. |
311 | | "aabbcc" -> "aabbcc0100...00" -> 0x01ccbbaa. */ |
312 | 235 | uint32_t pad = 0x01; |
313 | | |
314 | 501 | while (key_length > 0) |
315 | 266 | pad = pad << 8 | key[--key_length]; |
316 | | |
317 | 235 | w[i++] = pad; |
318 | | |
319 | 461 | while (i < 8) |
320 | 226 | w[i++] = 0; |
321 | 235 | } |
322 | 298 | } |
323 | | |
324 | | /* Initialize CONTEXT with the key KEY of LENGTH bytes. */ |
325 | | void |
326 | | serpent_set_key (struct serpent_ctx *ctx, |
327 | | size_t length, const uint8_t * key) |
328 | 298 | { |
329 | 298 | uint32_t w[8]; |
330 | 298 | uint32_t (*keys)[4]; |
331 | 298 | unsigned k; |
332 | | |
333 | 298 | serpent_key_pad (key, length, w); |
334 | | |
335 | | /* Derive the 33 subkeys from KEY and store them in SUBKEYS. We do |
336 | | the recurrence in the key schedule using W as a circular buffer |
337 | | of just 8 uint32_t. */ |
338 | | |
339 | | /* FIXME: Would be better to invoke SBOX with scalar variables as |
340 | | arguments, no arrays. To do that, unpack w into separate |
341 | | variables, use temporary variables as the SBOX destination. */ |
342 | | |
343 | 298 | keys = ctx->keys; |
344 | 298 | k = 0; |
345 | 298 | for (;;) |
346 | 1.49k | { |
347 | 1.49k | KS(keys, 3, w, 0, k); |
348 | 1.49k | if (k == 132) |
349 | 298 | break; |
350 | 1.19k | KS(keys, 2, w, 4, k); |
351 | 1.19k | KS(keys, 1, w, 0, k); |
352 | 1.19k | KS(keys, 0, w, 4, k); |
353 | 1.19k | KS(keys, 7, w, 0, k); |
354 | 1.19k | KS(keys, 6, w, 4, k); |
355 | 1.19k | KS(keys, 5, w, 0, k); |
356 | 1.19k | KS(keys, 4, w, 4, k); |
357 | 1.19k | } |
358 | 298 | assert (keys == ctx->keys + 33); |
359 | 298 | } |
360 | | |
361 | | void |
362 | | serpent128_set_key (struct serpent_ctx *ctx, const uint8_t *key) |
363 | 0 | { |
364 | 0 | serpent_set_key (ctx, SERPENT128_KEY_SIZE, key); |
365 | 0 | } |
366 | | |
367 | | void |
368 | | serpent192_set_key (struct serpent_ctx *ctx, const uint8_t *key) |
369 | 0 | { |
370 | 0 | serpent_set_key (ctx, SERPENT192_KEY_SIZE, key); |
371 | 0 | } |
372 | | |
373 | | void |
374 | | serpent256_set_key (struct serpent_ctx *ctx, const uint8_t *key) |
375 | 0 | { |
376 | 0 | serpent_set_key (ctx, SERPENT256_KEY_SIZE, key); |
377 | 0 | } |