/src/nettle-with-libgmp/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  | 24.4k  | #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  | 740  |   do { \ | 
85  | 740  |     type t02, t03, t05, t06, t07, t08, t09; \  | 
86  | 740  |     type t11, t12, t13, t14, t15, t17, t01; \  | 
87  | 740  |     t01 = b   ^ c  ; \  | 
88  | 740  |     t02 = a   | d  ; \  | 
89  | 740  |     t03 = a   ^ b  ; \  | 
90  | 740  |     z   = t02 ^ t01; \  | 
91  | 740  |     t05 = c   | z  ; \  | 
92  | 740  |     t06 = a   ^ d  ; \  | 
93  | 740  |     t07 = b   | c  ; \  | 
94  | 740  |     t08 = d   & t05; \  | 
95  | 740  |     t09 = t03 & t07; \  | 
96  | 740  |     y   = t09 ^ t08; \  | 
97  | 740  |     t11 = t09 & y  ; \  | 
98  | 740  |     t12 = c   ^ d  ; \  | 
99  | 740  |     t13 = t07 ^ t11; \  | 
100  | 740  |     t14 = b   & t06; \  | 
101  | 740  |     t15 = t06 ^ t13; \  | 
102  | 740  |     w   =     ~ t15; \  | 
103  | 740  |     t17 = w   ^ t14; \  | 
104  | 740  |     x   = t12 ^ t17; \  | 
105  | 740  |   } while (0)  | 
106  |  |  | 
107  |  | #define SBOX1(type, a, b, c, d, w, x, y, z) \  | 
108  | 740  |   do { \ | 
109  | 740  |     type t02, t03, t04, t05, t06, t07, t08; \  | 
110  | 740  |     type t10, t11, t12, t13, t16, t17, t01; \  | 
111  | 740  |     t01 = a   | d  ; \  | 
112  | 740  |     t02 = c   ^ d  ; \  | 
113  | 740  |     t03 =     ~ b  ; \  | 
114  | 740  |     t04 = a   ^ c  ; \  | 
115  | 740  |     t05 = a   | t03; \  | 
116  | 740  |     t06 = d   & t04; \  | 
117  | 740  |     t07 = t01 & t02; \  | 
118  | 740  |     t08 = b   | t06; \  | 
119  | 740  |     y   = t02 ^ t05; \  | 
120  | 740  |     t10 = t07 ^ t08; \  | 
121  | 740  |     t11 = t01 ^ t10; \  | 
122  | 740  |     t12 = y   ^ t11; \  | 
123  | 740  |     t13 = b   & d  ; \  | 
124  | 740  |     z   =     ~ t10; \  | 
125  | 740  |     x   = t13 ^ t12; \  | 
126  | 740  |     t16 = t10 | x  ; \  | 
127  | 740  |     t17 = t05 & t16; \  | 
128  | 740  |     w   = c   ^ t17; \  | 
129  | 740  |   } while (0)  | 
130  |  |  | 
131  |  | #define SBOX2(type, a, b, c, d, w, x, y, z) \  | 
132  | 740  |   do {            \ | 
133  | 740  |     type t02, t03, t05, t06, t07, t08; \  | 
134  | 740  |     type t09, t10, t12, t13, t14, t01; \  | 
135  | 740  |     t01 = a   | c  ; \  | 
136  | 740  |     t02 = a   ^ b  ; \  | 
137  | 740  |     t03 = d   ^ t01; \  | 
138  | 740  |     w   = t02 ^ t03; \  | 
139  | 740  |     t05 = c   ^ w  ; \  | 
140  | 740  |     t06 = b   ^ t05; \  | 
141  | 740  |     t07 = b   | t05; \  | 
142  | 740  |     t08 = t01 & t06; \  | 
143  | 740  |     t09 = t03 ^ t07; \  | 
144  | 740  |     t10 = t02 | t09; \  | 
145  | 740  |     x   = t10 ^ t08; \  | 
146  | 740  |     t12 = a   | d  ; \  | 
147  | 740  |     t13 = t09 ^ x  ; \  | 
148  | 740  |     t14 = b   ^ t13; \  | 
149  | 740  |     z   =     ~ t09; \  | 
150  | 740  |     y   = t12 ^ t14; \  | 
151  | 740  |   } while (0)  | 
152  |  |  | 
153  |  | #define SBOX3(type, a, b, c, d, w, x, y, z) \  | 
154  | 925  |   do {           \ | 
155  | 925  |     type t02, t03, t04, t05, t06, t07, t08; \  | 
156  | 925  |     type t09, t10, t11, t13, t14, t15, t01; \  | 
157  | 925  |     t01 = a   ^ c  ; \  | 
158  | 925  |     t02 = a   | d  ; \  | 
159  | 925  |     t03 = a   & d  ; \  | 
160  | 925  |     t04 = t01 & t02; \  | 
161  | 925  |     t05 = b   | t03; \  | 
162  | 925  |     t06 = a   & b  ; \  | 
163  | 925  |     t07 = d   ^ t04; \  | 
164  | 925  |     t08 = c   | t06; \  | 
165  | 925  |     t09 = b   ^ t07; \  | 
166  | 925  |     t10 = d   & t05; \  | 
167  | 925  |     t11 = t02 ^ t10; \  | 
168  | 925  |     z   = t08 ^ t09; \  | 
169  | 925  |     t13 = d   | z  ; \  | 
170  | 925  |     t14 = a   | t07; \  | 
171  | 925  |     t15 = b   & t13; \  | 
172  | 925  |     y   = t08 ^ t11; \  | 
173  | 925  |     w   = t14 ^ t15; \  | 
174  | 925  |     x   = t05 ^ t04; \  | 
175  | 925  |   } while (0)  | 
176  |  |  | 
177  |  | #define SBOX4(type, a, b, c, d, w, x, y, z) \  | 
178  | 740  |   do { \ | 
179  | 740  |     type t02, t03, t04, t05, t06, t08, t09; \  | 
180  | 740  |     type t10, t11, t12, t13, t14, t15, t16, t01; \  | 
181  | 740  |     t01 = a   | b  ; \  | 
182  | 740  |     t02 = b   | c  ; \  | 
183  | 740  |     t03 = a   ^ t02; \  | 
184  | 740  |     t04 = b   ^ d  ; \  | 
185  | 740  |     t05 = d   | t03; \  | 
186  | 740  |     t06 = d   & t01; \  | 
187  | 740  |     z   = t03 ^ t06; \  | 
188  | 740  |     t08 = z   & t04; \  | 
189  | 740  |     t09 = t04 & t05; \  | 
190  | 740  |     t10 = c   ^ t06; \  | 
191  | 740  |     t11 = b   & c  ; \  | 
192  | 740  |     t12 = t04 ^ t08; \  | 
193  | 740  |     t13 = t11 | t03; \  | 
194  | 740  |     t14 = t10 ^ t09; \  | 
195  | 740  |     t15 = a   & t05; \  | 
196  | 740  |     t16 = t11 | t12; \  | 
197  | 740  |     y   = t13 ^ t08; \  | 
198  | 740  |     x   = t15 ^ t16; \  | 
199  | 740  |     w   =     ~ t14; \  | 
200  | 740  |   } while (0)  | 
201  |  |  | 
202  |  | #define SBOX5(type, a, b, c, d, w, x, y, z) \  | 
203  | 740  |   do { \ | 
204  | 740  |     type t02, t03, t04, t05, t07, t08, t09; \  | 
205  | 740  |     type t10, t11, t12, t13, t14, t01; \  | 
206  | 740  |     t01 = b   ^ d  ; \  | 
207  | 740  |     t02 = b   | d  ; \  | 
208  | 740  |     t03 = a   & t01; \  | 
209  | 740  |     t04 = c   ^ t02; \  | 
210  | 740  |     t05 = t03 ^ t04; \  | 
211  | 740  |     w   =     ~ t05; \  | 
212  | 740  |     t07 = a   ^ t01; \  | 
213  | 740  |     t08 = d   | w  ; \  | 
214  | 740  |     t09 = b   | t05; \  | 
215  | 740  |     t10 = d   ^ t08; \  | 
216  | 740  |     t11 = b   | t07; \  | 
217  | 740  |     t12 = t03 | w  ; \  | 
218  | 740  |     t13 = t07 | t10; \  | 
219  | 740  |     t14 = t01 ^ t11; \  | 
220  | 740  |     y   = t09 ^ t13; \  | 
221  | 740  |     x   = t07 ^ t08; \  | 
222  | 740  |     z   = t12 ^ t14; \  | 
223  | 740  |   } while (0)  | 
224  |  |  | 
225  |  | #define SBOX6(type, a, b, c, d, w, x, y, z) \  | 
226  | 740  |   do { \ | 
227  | 740  |     type t02, t03, t04, t05, t07, t08, t09, t10;  \  | 
228  | 740  |     type t11, t12, t13, t15, t17, t18, t01; \  | 
229  | 740  |     t01 = a   & d  ; \  | 
230  | 740  |     t02 = b   ^ c  ; \  | 
231  | 740  |     t03 = a   ^ d  ; \  | 
232  | 740  |     t04 = t01 ^ t02; \  | 
233  | 740  |     t05 = b   | c  ; \  | 
234  | 740  |     x   =     ~ t04; \  | 
235  | 740  |     t07 = t03 & t05; \  | 
236  | 740  |     t08 = b   & x  ; \  | 
237  | 740  |     t09 = a   | c  ; \  | 
238  | 740  |     t10 = t07 ^ t08; \  | 
239  | 740  |     t11 = b   | d  ; \  | 
240  | 740  |     t12 = c   ^ t11; \  | 
241  | 740  |     t13 = t09 ^ t10; \  | 
242  | 740  |     y   =     ~ t13; \  | 
243  | 740  |     t15 = x   & t03; \  | 
244  | 740  |     z   = t12 ^ t07; \  | 
245  | 740  |     t17 = a   ^ b  ; \  | 
246  | 740  |     t18 = y   ^ t15; \  | 
247  | 740  |     w   = t17 ^ t18; \  | 
248  | 740  |   } while (0)  | 
249  |  |  | 
250  |  | #define SBOX7(type, a, b, c, d, w, x, y, z) \  | 
251  | 740  |   do { \ | 
252  | 740  |     type t02, t03, t04, t05, t06, t08, t09, t10;  \  | 
253  | 740  |     type t11, t13, t14, t15, t16, t17, t01; \  | 
254  | 740  |     t01 = a   & c  ; \  | 
255  | 740  |     t02 =     ~ d  ; \  | 
256  | 740  |     t03 = a   & t02; \  | 
257  | 740  |     t04 = b   | t01; \  | 
258  | 740  |     t05 = a   & b  ; \  | 
259  | 740  |     t06 = c   ^ t04; \  | 
260  | 740  |     z   = t03 ^ t06; \  | 
261  | 740  |     t08 = c   | z  ; \  | 
262  | 740  |     t09 = d   | t05; \  | 
263  | 740  |     t10 = a   ^ t08; \  | 
264  | 740  |     t11 = t04 & z  ; \  | 
265  | 740  |     x   = t09 ^ t10; \  | 
266  | 740  |     t13 = b   ^ x  ; \  | 
267  | 740  |     t14 = t01 ^ x  ; \  | 
268  | 740  |     t15 = c   ^ t05; \  | 
269  | 740  |     t16 = t11 | t13; \  | 
270  | 740  |     t17 = t02 | t14; \  | 
271  | 740  |     w   = t15 ^ t17; \  | 
272  | 740  |     y   = a   ^ t16; \  | 
273  | 740  |   } while (0)  | 
274  |  |  | 
275  |  | /* Key schedule */  | 
276  |  | /* Note: Increments k */  | 
277  |  | #define KS_RECURRENCE(w, i, k)            \  | 
278  | 24.4k  |   do {                 \ | 
279  | 24.4k  |     uint32_t _wn = (w)[(i)] ^ (w)[((i)+3)&7] ^ w[((i)+5)&7]   \  | 
280  | 24.4k  |       ^ w[((i)+7)&7] ^ PHI ^ (k)++;         \  | 
281  | 24.4k  |     ((w)[(i)] = ROTL32(11, _wn));         \  | 
282  | 24.4k  |   } while (0)  | 
283  |  |  | 
284  |  | /* Note: Increments k four times and keys once */  | 
285  |  | #define KS(keys, s, w, i, k)          \  | 
286  | 6.10k  |   do {               \ | 
287  | 6.10k  |     KS_RECURRENCE(w, (i), (k));          \  | 
288  | 6.10k  |     KS_RECURRENCE(w, (i)+1, (k));        \  | 
289  | 6.10k  |     KS_RECURRENCE(w, (i)+2, (k));        \  | 
290  | 6.10k  |     KS_RECURRENCE(w, (i)+3, (k));        \  | 
291  | 6.10k  |     SBOX##s(uint32_t, w[(i)],w[(i)+1],w[(i)+2],w[(i)+3],    \  | 
292  | 6.10k  |       (*keys)[0],(*keys)[1],(*keys)[2],(*keys)[3]); \  | 
293  | 6.10k  |     (keys)++;             \  | 
294  | 6.10k  |   } 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  | 185  | { | 
301  | 185  |   unsigned int i;  | 
302  |  |  | 
303  | 185  |   assert (key_length <= SERPENT_MAX_KEY_SIZE);  | 
304  |  |     | 
305  | 1.39k  |   for (i = 0; key_length >= 4; key_length -=4, key += 4)  | 
306  | 1.21k  |     w[i++] = LE_READ_UINT32(key);  | 
307  |  |  | 
308  | 185  |   if (i < 8)  | 
309  | 125  |     { | 
310  |  |       /* Key must be padded according to the Serpent specification.  | 
311  |  |          "aabbcc" -> "aabbcc0100...00" -> 0x01ccbbaa. */  | 
312  | 125  |       uint32_t pad = 0x01;  | 
313  |  |         | 
314  | 277  |       while (key_length > 0)  | 
315  | 152  |   pad = pad << 8 | key[--key_length];  | 
316  |  |  | 
317  | 125  |       w[i++] = pad;  | 
318  |  |  | 
319  | 267  |       while (i < 8)  | 
320  | 142  |   w[i++] = 0;  | 
321  | 125  |     }  | 
322  | 185  | }  | 
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  | 185  | { | 
329  | 185  |   uint32_t w[8];  | 
330  | 185  |   uint32_t (*keys)[4];  | 
331  | 185  |   unsigned k;  | 
332  |  |     | 
333  | 185  |   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  | 185  |   keys = ctx->keys;  | 
344  | 185  |   k = 0;  | 
345  | 185  |   for (;;)  | 
346  | 925  |     { | 
347  | 925  |       KS(keys, 3, w, 0, k);  | 
348  | 925  |       if (k == 132)  | 
349  | 185  |   break;  | 
350  | 740  |       KS(keys, 2, w, 4, k);  | 
351  | 740  |       KS(keys, 1, w, 0, k);  | 
352  | 740  |       KS(keys, 0, w, 4, k);  | 
353  | 740  |       KS(keys, 7, w, 0, k);  | 
354  | 740  |       KS(keys, 6, w, 4, k);  | 
355  | 740  |       KS(keys, 5, w, 0, k);  | 
356  | 740  |       KS(keys, 4, w, 4, k);  | 
357  | 740  |     }  | 
358  | 185  |   assert (keys == ctx->keys + 33);  | 
359  | 185  | }  | 
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  | }  |