Coverage Report

Created: 2024-11-21 07:00

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