f880f8f868638e8d651cf706ceac7ffd00cd8345
[platform/upstream/nettle.git] / des.c
1 /* des.c
2
3    The des block cipher.
4
5    Copyright (C) 2001, 2010 Niels Möller
6    Copyright (C) 1992  Dana L. How
7
8    This file is part of GNU Nettle.
9
10    GNU Nettle is free software: you can redistribute it and/or
11    modify it under the terms of either:
12
13      * the GNU Lesser General Public License as published by the Free
14        Software Foundation; either version 3 of the License, or (at your
15        option) any later version.
16
17    or
18
19      * the GNU General Public License as published by the Free
20        Software Foundation; either version 2 of the License, or (at your
21        option) any later version.
22
23    or both in parallel, as here.
24
25    GNU Nettle is distributed in the hope that it will be useful,
26    but WITHOUT ANY WARRANTY; without even the implied warranty of
27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
28    General Public License for more details.
29
30    You should have received copies of the GNU General Public License and
31    the GNU Lesser General Public License along with this program.  If
32    not, see http://www.gnu.org/licenses/.
33 */
34
35 /*      des - fast & portable DES encryption & decryption.
36  *      Copyright (C) 1992  Dana L. How
37  *      Please see the file `descore.README' for the complete copyright notice.
38  */
39
40 #if HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <assert.h>
45
46 #include "des.h"
47
48 #include "desCode.h"
49
50 /* various tables */
51
52 static const uint32_t
53 des_keymap[] = {
54 #include        "keymap.h"
55 };
56
57 static const uint8_t
58 rotors[] = {
59 #include        "rotors.h"
60 };
61
62 static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
63 static DECRYPT(DesSmallFipsDecrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
64
65 /* If parity bits are used, keys should have odd parity. We use a
66    small table, to not waste any memory on this fairly obscure DES
67    feature. */
68
69 static const unsigned
70 parity_16[16] =
71 { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
72
73 #define PARITY(x) (parity_16[(x)&0xf] ^ parity_16[((x)>>4) & 0xf])
74
75 int
76 des_check_parity(size_t length, const uint8_t *key)
77 {
78   size_t i;
79   for (i = 0; i<length; i++)
80     if (!PARITY(key[i]))
81       return 0;
82
83   return 1;
84 }
85
86 void
87 des_fix_parity(size_t length, uint8_t *dst,
88                const uint8_t *src)
89 {
90   size_t i;
91   for (i = 0; i<length; i++)
92     dst[i] = src[i] ^ PARITY(src[i]) ^ 1;
93 }
94
95 /* Weak and semiweak keys, excluding parity:
96  *
97  * 00 00 00 00  00 00 00 00
98  * 7f 7f 7f 7f  7f 7f 7f 7f 
99  * 0f 0f 0f 0f  07 07 07 07
100  * 70 70 70 70  78 78 78 78
101  *
102  * 00 7f 00 7f  00 7f 00 7f
103  * 7f 00 7f 00  7f 00 7f 00
104  *
105  * 0f 70 0f 70  07 78 07 78
106  * 70 0f 70 0f  78 07 78 07
107  *
108  * 00 70 00 70  00 78 00 78
109  * 70 00 70 00  78 00 78 00
110  *
111  * 0f 7f 0f 7f  07 7f 07 7f
112  * 7f 0f 7f 0f  7f 07 7f 07
113  *
114  * 00 0f 00 0f  00 07 00 07
115  * 0f 00 0f 00  07 00 07 00
116  *
117  * 70 7f 70 7f  78 7f 78 7f
118  * 7f 70 7f 70  7f 78 7f 78
119  */
120
121 static int
122 des_weak_p(const uint8_t *key)
123 {
124   /* Hash function generated using gperf. */
125   static const unsigned char asso_values[0x81] =
126     {
127       16,  9, 26, 26, 26, 26, 26, 26, 26, 26,
128       26, 26, 26, 26, 26,  6,  2, 26, 26, 26,
129       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
130       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
131       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
132       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
133       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
134       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
135       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
136       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
137       26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
138       26, 26,  3,  1, 26, 26, 26, 26, 26, 26,
139       26, 26, 26, 26, 26, 26, 26,  0,  0
140     };
141
142   static const int8_t weak_key_hash[26][4] =
143     {
144       /*  0 */ {0x7f,0x7f, 0x7f,0x7f},
145       /*  1 */ {0x7f,0x70, 0x7f,0x78},
146       /*  2 */ {0x7f,0x0f, 0x7f,0x07},
147       /*  3 */ {0x70,0x7f, 0x78,0x7f},
148       /*  4 */ {0x70,0x70, 0x78,0x78},
149       /*  5 */ {0x70,0x0f, 0x78,0x07},
150       /*  6 */ {0x0f,0x7f, 0x07,0x7f},
151       /*  7 */ {0x0f,0x70, 0x07,0x78},
152       /*  8 */ {0x0f,0x0f, 0x07,0x07},
153       /*  9 */ {0x7f,0x00, 0x7f,0x00},
154       /* 10 */ {-1,-1,-1,-1},
155       /* 11 */ {-1,-1,-1,-1},
156       /* 12 */ {0x70,0x00, 0x78,0x00},
157       /* 13 */ {-1,-1,-1,-1},
158       /* 14 */ {-1,-1,-1,-1},
159       /* 15 */ {0x0f,0x00, 0x07,0x00},
160       /* 16 */ {0x00,0x7f, 0x00,0x7f},
161       /* 17 */ {0x00,0x70, 0x00,0x78},
162       /* 18 */ {0x00,0x0f, 0x00,0x07},
163       /* 19 */ {-1,-1,-1,-1},
164       /* 20 */ {-1,-1,-1,-1},
165       /* 21 */ {-1,-1,-1,-1},
166       /* 22 */ {-1,-1,-1,-1},
167       /* 23 */ {-1,-1,-1,-1},
168       /* 24 */ {-1,-1,-1,-1},
169       /* 25 */ {0x00,0x00, 0x00,0x00}
170     };
171
172   int8_t k0 = key[0] >> 1;
173   int8_t k1 = key[1] >> 1;
174
175   unsigned hash = asso_values[k1 + 1] + asso_values[k0];
176   const int8_t *candidate = weak_key_hash[hash];
177
178   if (hash > 25)
179     return 0;
180   if (k0 != candidate[0]
181       || k1 != candidate[1])
182     return 0;
183   
184   if ( (key[2] >> 1) != k0
185        || (key[3] >> 1) != k1)
186     return 0;
187
188   k0 = key[4] >> 1;
189   k1 = key[5] >> 1;
190   if (k0 != candidate[2]
191       || k1 != candidate[3])
192     return 0;
193   if ( (key[6] >> 1) != k0
194        || (key[7] >> 1) != k1)
195     return 0;
196
197   return 1;
198 }
199
200 int
201 des_set_key(struct des_ctx *ctx, const uint8_t *key)
202 {
203   register uint32_t n, w;
204   register char * b0, * b1;
205   char bits0[56], bits1[56];
206   uint32_t *method;
207   const uint8_t *k;
208
209   /* explode the bits */
210   n = 56;
211   b0 = bits0;
212   b1 = bits1;
213   k = key;
214   do {
215     w = (256 | *k++) << 2;
216     do {
217       --n;
218       b1[n] = 8 & w;
219       w >>= 1;
220       b0[n] = 4 & w;
221     } while ( w >= 16 );
222   } while ( n );
223
224   /* put the bits in the correct places */
225   n = 16;
226   k = rotors;
227   method = ctx->key;
228   
229   do {
230     w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
231     w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
232     w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
233     w <<= 8;
234     w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
235     w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
236     w  |=  b1[k[10   ]] | b0[k[11   ]];
237     w <<= 8;
238     w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
239     w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
240     w  |=  b1[k[16   ]] | b0[k[17   ]];
241     w <<= 8;
242     w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
243     w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
244     w  |=  b1[k[22   ]] | b0[k[23   ]];
245
246     method[0] = w;
247
248     w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
249     w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
250     w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
251     w <<= 8;
252     w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
253     w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
254     w  |=  b1[k[10+24]] | b0[k[11+24]];
255     w <<= 8;
256     w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
257     w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
258     w  |=  b1[k[16+24]] | b0[k[17+24]];
259     w <<= 8;
260     w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
261     w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
262     w  |=  b1[k[22+24]] | b0[k[23+24]];
263
264     ROR(w, 4, 28);              /* could be eliminated */
265     method[1] = w;
266
267     k   += 48;
268     method      += 2;
269   } while ( --n );
270
271   return !des_weak_p (key);
272 }
273
274 void
275 des_encrypt(const struct des_ctx *ctx,
276             size_t length, uint8_t *dst,
277             const uint8_t *src)
278 {
279   assert(!(length % DES_BLOCK_SIZE));
280   
281   while (length)
282     {
283       DesSmallFipsEncrypt(dst, ctx->key, src);
284       length -= DES_BLOCK_SIZE;
285       src += DES_BLOCK_SIZE;
286       dst += DES_BLOCK_SIZE;
287     }
288 }
289
290 void
291 des_decrypt(const struct des_ctx *ctx,
292             size_t length, uint8_t *dst,
293             const uint8_t *src)
294 {
295   assert(!(length % DES_BLOCK_SIZE));
296
297   while (length)
298     {
299       DesSmallFipsDecrypt(dst, ctx->key, src);
300       length -= DES_BLOCK_SIZE;
301       src += DES_BLOCK_SIZE;
302       dst += DES_BLOCK_SIZE;
303     }
304 }