Line | Count | Source (jump to first uncovered line) |
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 | 0 | static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS) |
63 | 0 | 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 | 0 | #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 | 0 | { |
78 | 0 | size_t i; |
79 | 0 | for (i = 0; i<length; i++) |
80 | 0 | if (!PARITY(key[i])) |
81 | 0 | return 0; |
82 | | |
83 | 0 | return 1; |
84 | 0 | } |
85 | | |
86 | | void |
87 | | des_fix_parity(size_t length, uint8_t *dst, |
88 | | const uint8_t *src) |
89 | 0 | { |
90 | 0 | size_t i; |
91 | 0 | for (i = 0; i<length; i++) |
92 | 0 | dst[i] = src[i] ^ PARITY(src[i]) ^ 1; |
93 | 0 | } |
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 | 0 | { |
124 | | /* Hash function generated using gperf. */ |
125 | 0 | static const unsigned char asso_values[0x81] = |
126 | 0 | { |
127 | 0 | 16, 9, 26, 26, 26, 26, 26, 26, 26, 26, |
128 | 0 | 26, 26, 26, 26, 26, 6, 2, 26, 26, 26, |
129 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
130 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
131 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
132 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
133 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
134 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
135 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
136 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
137 | 0 | 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, |
138 | 0 | 26, 26, 3, 1, 26, 26, 26, 26, 26, 26, |
139 | 0 | 26, 26, 26, 26, 26, 26, 26, 0, 0 |
140 | 0 | }; |
141 | |
|
142 | 0 | static const int8_t weak_key_hash[26][4] = |
143 | 0 | { |
144 | 0 | /* 0 */ {0x7f,0x7f, 0x7f,0x7f}, |
145 | 0 | /* 1 */ {0x7f,0x70, 0x7f,0x78}, |
146 | 0 | /* 2 */ {0x7f,0x0f, 0x7f,0x07}, |
147 | 0 | /* 3 */ {0x70,0x7f, 0x78,0x7f}, |
148 | 0 | /* 4 */ {0x70,0x70, 0x78,0x78}, |
149 | 0 | /* 5 */ {0x70,0x0f, 0x78,0x07}, |
150 | 0 | /* 6 */ {0x0f,0x7f, 0x07,0x7f}, |
151 | 0 | /* 7 */ {0x0f,0x70, 0x07,0x78}, |
152 | 0 | /* 8 */ {0x0f,0x0f, 0x07,0x07}, |
153 | 0 | /* 9 */ {0x7f,0x00, 0x7f,0x00}, |
154 | 0 | /* 10 */ {-1,-1,-1,-1}, |
155 | 0 | /* 11 */ {-1,-1,-1,-1}, |
156 | 0 | /* 12 */ {0x70,0x00, 0x78,0x00}, |
157 | 0 | /* 13 */ {-1,-1,-1,-1}, |
158 | 0 | /* 14 */ {-1,-1,-1,-1}, |
159 | 0 | /* 15 */ {0x0f,0x00, 0x07,0x00}, |
160 | 0 | /* 16 */ {0x00,0x7f, 0x00,0x7f}, |
161 | 0 | /* 17 */ {0x00,0x70, 0x00,0x78}, |
162 | 0 | /* 18 */ {0x00,0x0f, 0x00,0x07}, |
163 | 0 | /* 19 */ {-1,-1,-1,-1}, |
164 | 0 | /* 20 */ {-1,-1,-1,-1}, |
165 | 0 | /* 21 */ {-1,-1,-1,-1}, |
166 | 0 | /* 22 */ {-1,-1,-1,-1}, |
167 | 0 | /* 23 */ {-1,-1,-1,-1}, |
168 | 0 | /* 24 */ {-1,-1,-1,-1}, |
169 | 0 | /* 25 */ {0x00,0x00, 0x00,0x00} |
170 | 0 | }; |
171 | |
|
172 | 0 | int8_t k0 = key[0] >> 1; |
173 | 0 | int8_t k1 = key[1] >> 1; |
174 | |
|
175 | 0 | unsigned hash = asso_values[k1 + 1] + asso_values[k0]; |
176 | 0 | const int8_t *candidate; |
177 | |
|
178 | 0 | if (hash > 25) |
179 | 0 | return 0; |
180 | | |
181 | 0 | candidate = weak_key_hash[hash]; |
182 | |
|
183 | 0 | if (k0 != candidate[0] |
184 | 0 | || k1 != candidate[1]) |
185 | 0 | return 0; |
186 | | |
187 | 0 | if ( (key[2] >> 1) != k0 |
188 | 0 | || (key[3] >> 1) != k1) |
189 | 0 | return 0; |
190 | | |
191 | 0 | k0 = key[4] >> 1; |
192 | 0 | k1 = key[5] >> 1; |
193 | 0 | if (k0 != candidate[2] |
194 | 0 | || k1 != candidate[3]) |
195 | 0 | return 0; |
196 | 0 | if ( (key[6] >> 1) != k0 |
197 | 0 | || (key[7] >> 1) != k1) |
198 | 0 | return 0; |
199 | | |
200 | 0 | return 1; |
201 | 0 | } |
202 | | |
203 | | int |
204 | | des_set_key(struct des_ctx *ctx, const uint8_t *key) |
205 | 0 | { |
206 | 0 | register uint32_t n, w; |
207 | 0 | register char * b0, * b1; |
208 | 0 | char bits0[56], bits1[56]; |
209 | 0 | uint32_t *method; |
210 | 0 | const uint8_t *k; |
211 | | |
212 | | /* explode the bits */ |
213 | 0 | n = 56; |
214 | 0 | b0 = bits0; |
215 | 0 | b1 = bits1; |
216 | 0 | k = key; |
217 | 0 | do { |
218 | 0 | w = (256 | *k++) << 2; |
219 | 0 | do { |
220 | 0 | --n; |
221 | 0 | b1[n] = 8 & w; |
222 | 0 | w >>= 1; |
223 | 0 | b0[n] = 4 & w; |
224 | 0 | } while ( w >= 16 ); |
225 | 0 | } while ( n ); |
226 | | |
227 | | /* put the bits in the correct places */ |
228 | 0 | n = 16; |
229 | 0 | k = rotors; |
230 | 0 | method = ctx->key; |
231 | | |
232 | 0 | do { |
233 | 0 | w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4; |
234 | 0 | w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2; |
235 | 0 | w |= b1[k[ 4 ]] | b0[k[ 5 ]]; |
236 | 0 | w <<= 8; |
237 | 0 | w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4; |
238 | 0 | w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2; |
239 | 0 | w |= b1[k[10 ]] | b0[k[11 ]]; |
240 | 0 | w <<= 8; |
241 | 0 | w |= (b1[k[12 ]] | b0[k[13 ]]) << 4; |
242 | 0 | w |= (b1[k[14 ]] | b0[k[15 ]]) << 2; |
243 | 0 | w |= b1[k[16 ]] | b0[k[17 ]]; |
244 | 0 | w <<= 8; |
245 | 0 | w |= (b1[k[18 ]] | b0[k[19 ]]) << 4; |
246 | 0 | w |= (b1[k[20 ]] | b0[k[21 ]]) << 2; |
247 | 0 | w |= b1[k[22 ]] | b0[k[23 ]]; |
248 | |
|
249 | 0 | method[0] = w; |
250 | |
|
251 | 0 | w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4; |
252 | 0 | w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2; |
253 | 0 | w |= b1[k[ 4+24]] | b0[k[ 5+24]]; |
254 | 0 | w <<= 8; |
255 | 0 | w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4; |
256 | 0 | w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2; |
257 | 0 | w |= b1[k[10+24]] | b0[k[11+24]]; |
258 | 0 | w <<= 8; |
259 | 0 | w |= (b1[k[12+24]] | b0[k[13+24]]) << 4; |
260 | 0 | w |= (b1[k[14+24]] | b0[k[15+24]]) << 2; |
261 | 0 | w |= b1[k[16+24]] | b0[k[17+24]]; |
262 | 0 | w <<= 8; |
263 | 0 | w |= (b1[k[18+24]] | b0[k[19+24]]) << 4; |
264 | 0 | w |= (b1[k[20+24]] | b0[k[21+24]]) << 2; |
265 | 0 | w |= b1[k[22+24]] | b0[k[23+24]]; |
266 | |
|
267 | 0 | ROR(w, 4, 28); /* could be eliminated */ |
268 | 0 | method[1] = w; |
269 | |
|
270 | 0 | k += 48; |
271 | 0 | method += 2; |
272 | 0 | } while ( --n ); |
273 | |
|
274 | 0 | return !des_weak_p (key); |
275 | 0 | } |
276 | | |
277 | | void |
278 | | des_encrypt(const struct des_ctx *ctx, |
279 | | size_t length, uint8_t *dst, |
280 | | const uint8_t *src) |
281 | 0 | { |
282 | 0 | assert(!(length % DES_BLOCK_SIZE)); |
283 | | |
284 | 0 | while (length) |
285 | 0 | { |
286 | 0 | DesSmallFipsEncrypt(dst, ctx->key, src); |
287 | 0 | length -= DES_BLOCK_SIZE; |
288 | 0 | src += DES_BLOCK_SIZE; |
289 | 0 | dst += DES_BLOCK_SIZE; |
290 | 0 | } |
291 | 0 | } |
292 | | |
293 | | void |
294 | | des_decrypt(const struct des_ctx *ctx, |
295 | | size_t length, uint8_t *dst, |
296 | | const uint8_t *src) |
297 | 0 | { |
298 | 0 | assert(!(length % DES_BLOCK_SIZE)); |
299 | | |
300 | 0 | while (length) |
301 | 0 | { |
302 | 0 | DesSmallFipsDecrypt(dst, ctx->key, src); |
303 | 0 | length -= DES_BLOCK_SIZE; |
304 | 0 | src += DES_BLOCK_SIZE; |
305 | 0 | dst += DES_BLOCK_SIZE; |
306 | 0 | } |
307 | 0 | } |