]> git.ipfire.org Git - thirdparty/nettle.git/blame - des.c
Avoid warnings for assert_maybe.
[thirdparty/nettle.git] / des.c
CommitLineData
e62872fa 1/* des.c
e62872fa 2
90112edb
NM
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*/
e62872fa
NM
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
c5c15385
NM
40#if HAVE_CONFIG_H
41# include "config.h"
42#endif
43
44#include <assert.h>
45
e62872fa
NM
46#include "des.h"
47
48#include "desCode.h"
49
e62872fa
NM
50/* various tables */
51
b9d18b83
NM
52static const uint32_t
53des_keymap[] = {
e62872fa
NM
54#include "keymap.h"
55};
56
b9d18b83
NM
57static const uint8_t
58rotors[] = {
e62872fa
NM
59#include "rotors.h"
60};
b9d18b83 61
572c75fe
NM
62static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
63static DECRYPT(DesSmallFipsDecrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
64
26cf3cef
NM
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
69static const unsigned
70parity_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
75int
3eb603d0 76des_check_parity(size_t length, const uint8_t *key)
26cf3cef 77{
3eb603d0 78 size_t i;
26cf3cef
NM
79 for (i = 0; i<length; i++)
80 if (!PARITY(key[i]))
81 return 0;
82
83 return 1;
84}
85
7e12e96e 86void
3eb603d0 87des_fix_parity(size_t length, uint8_t *dst,
7e12e96e
NM
88 const uint8_t *src)
89{
3eb603d0 90 size_t i;
7e12e96e 91 for (i = 0; i<length; i++)
26cf3cef
NM
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
121static int
122des_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];
45a19a4b 176 const int8_t *candidate;
26cf3cef
NM
177
178 if (hash > 25)
179 return 0;
45a19a4b
NM
180
181 candidate = weak_key_hash[hash];
182
26cf3cef
NM
183 if (k0 != candidate[0]
184 || k1 != candidate[1])
185 return 0;
186
187 if ( (key[2] >> 1) != k0
188 || (key[3] >> 1) != k1)
189 return 0;
190
191 k0 = key[4] >> 1;
192 k1 = key[5] >> 1;
193 if (k0 != candidate[2]
194 || k1 != candidate[3])
195 return 0;
196 if ( (key[6] >> 1) != k0
197 || (key[7] >> 1) != k1)
198 return 0;
199
200 return 1;
7e12e96e
NM
201}
202
e62872fa
NM
203int
204des_set_key(struct des_ctx *ctx, const uint8_t *key)
205{
206 register uint32_t n, w;
207 register char * b0, * b1;
208 char bits0[56], bits1[56];
209 uint32_t *method;
b9d18b83 210 const uint8_t *k;
ba675b01 211
e62872fa
NM
212 /* explode the bits */
213 n = 56;
214 b0 = bits0;
215 b1 = bits1;
e907011a 216 k = key;
e62872fa 217 do {
e907011a 218 w = (256 | *k++) << 2;
e62872fa
NM
219 do {
220 --n;
221 b1[n] = 8 & w;
222 w >>= 1;
223 b0[n] = 4 & w;
224 } while ( w >= 16 );
225 } while ( n );
226
227 /* put the bits in the correct places */
228 n = 16;
229 k = rotors;
230 method = ctx->key;
231
232 do {
233 w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4;
234 w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2;
235 w |= b1[k[ 4 ]] | b0[k[ 5 ]];
236 w <<= 8;
237 w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4;
238 w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2;
239 w |= b1[k[10 ]] | b0[k[11 ]];
240 w <<= 8;
241 w |= (b1[k[12 ]] | b0[k[13 ]]) << 4;
242 w |= (b1[k[14 ]] | b0[k[15 ]]) << 2;
243 w |= b1[k[16 ]] | b0[k[17 ]];
244 w <<= 8;
245 w |= (b1[k[18 ]] | b0[k[19 ]]) << 4;
246 w |= (b1[k[20 ]] | b0[k[21 ]]) << 2;
247 w |= b1[k[22 ]] | b0[k[23 ]];
248
249 method[0] = w;
250
251 w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
252 w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
253 w |= b1[k[ 4+24]] | b0[k[ 5+24]];
254 w <<= 8;
255 w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
256 w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
257 w |= b1[k[10+24]] | b0[k[11+24]];
258 w <<= 8;
259 w |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
260 w |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
261 w |= b1[k[16+24]] | b0[k[17+24]];
262 w <<= 8;
263 w |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
264 w |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
265 w |= b1[k[22+24]] | b0[k[23+24]];
266
267 ROR(w, 4, 28); /* could be eliminated */
268 method[1] = w;
269
270 k += 48;
271 method += 2;
272 } while ( --n );
273
e907011a 274 return !des_weak_p (key);
e62872fa
NM
275}
276
277void
a4fa0f78 278des_encrypt(const struct des_ctx *ctx,
3eb603d0 279 size_t length, uint8_t *dst,
e62872fa
NM
280 const uint8_t *src)
281{
282 assert(!(length % DES_BLOCK_SIZE));
072dd6ef 283
e62872fa
NM
284 while (length)
285 {
286 DesSmallFipsEncrypt(dst, ctx->key, src);
287 length -= DES_BLOCK_SIZE;
288 src += DES_BLOCK_SIZE;
289 dst += DES_BLOCK_SIZE;
290 }
291}
292
293void
a4fa0f78 294des_decrypt(const struct des_ctx *ctx,
3eb603d0 295 size_t length, uint8_t *dst,
e62872fa
NM
296 const uint8_t *src)
297{
298 assert(!(length % DES_BLOCK_SIZE));
299
300 while (length)
301 {
302 DesSmallFipsDecrypt(dst, ctx->key, src);
303 length -= DES_BLOCK_SIZE;
304 src += DES_BLOCK_SIZE;
305 dst += DES_BLOCK_SIZE;
306 }
307}