Coverage Report

Created: 2024-02-25 06:16

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