Coverage Report

Created: 2024-06-28 06:39

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