des.c 6.26 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* des.c
 *
 * The des block cipher.
 *
 * $Id$
 */

/* nettle, low-level cryptographics library
 *
 * Copyright (C) 2001 Niels Mller
 *  
 * The nettle library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
Niels Möller's avatar
Niels Möller committed
17
 * The nettle library is distributed in the hope that it will be useful, but
Niels Möller's avatar
Niels Möller committed
18
19
20
21
22
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
Niels Möller's avatar
Niels Möller committed
23
 * along with the nettle library; see the file COPYING.LIB.  If not, write to
Niels Möller's avatar
Niels Möller committed
24
25
26
27
28
29
30
31
32
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA.
 */

/*	des - fast & portable DES encryption & decryption.
 *	Copyright (C) 1992  Dana L. How
 *	Please see the file `descore.README' for the complete copyright notice.
 */

33
34
35
36
37
38
#if HAVE_CONFIG_H
# include "config.h"
#endif

#include <assert.h>

Niels Möller's avatar
Niels Möller committed
39
40
41
42
43
44
#include "des.h"

#include "desCode.h"

/* various tables */

45
46
static const uint32_t
des_keymap[] = {
Niels Möller's avatar
Niels Möller committed
47
48
49
#include	"keymap.h"
};

50
51
static const uint8_t
rotors[] = {
Niels Möller's avatar
Niels Möller committed
52
53
#include	"rotors.h"
};
54
55
56

static const char
parity[] = {
Niels Möller's avatar
Niels Möller committed
57
58
59
#include	"parity.h"
};

60
61
62
static ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)
static DECRYPT(DesSmallFipsDecrypt,TEMPSMALL, LOADFIPS,KEYMAPSMALL,SAVEFIPS)

63
64
65
66
67
68
69
70
71
void
des_fix_parity(unsigned length, uint8_t *dst,
	       const uint8_t *src)
{
  unsigned i;
  for (i = 0; i<length; i++)
    dst[i] = src[i] ^ (parity[src[i]] == 8);
}

Niels Möller's avatar
Niels Möller committed
72
73
74
75
76
77
78
int
des_set_key(struct des_ctx *ctx, const uint8_t *key)
{
  register uint32_t n, w;
  register char * b0, * b1;
  char bits0[56], bits1[56];
  uint32_t *method;
79
  const uint8_t *k;
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  {
    register const char *b;
    /* check for bad parity and weak keys */
    b = parity;
    n  = b[key[0]]; n <<= 4;
    n |= b[key[1]]; n <<= 4;
    n |= b[key[2]]; n <<= 4;
    n |= b[key[3]]; n <<= 4;
    n |= b[key[4]]; n <<= 4;
    n |= b[key[5]]; n <<= 4;
    n |= b[key[6]]; n <<= 4;
    n |= b[key[7]];
    w  = 0x88888888l;
  }
  
Niels Möller's avatar
Niels Möller committed
96
97
98
99
100
101
  /* report bad parity in key */
  if ( n & w )
    {
      ctx->status = DES_BAD_PARITY;
      return 0;
    }
102
103
  ctx->status = DES_OK; 

Niels Möller's avatar
Niels Möller committed
104
105
106
107
108
109
  /* report a weak or semi-weak key */
  if ( !((n - (w >> 3)) & w) ) {	/* 1 in 10^10 keys passes this test */
    if ( n < 0X41415151 ) {
      if ( n < 0X31312121 ) {
	if ( n < 0X14141515 ) {
	  /* 01 01 01 01 01 01 01 01 */
110
	  if ( n == 0X11111111 ) goto weak;
Niels Möller's avatar
Niels Möller committed
111
	  /* 01 1F 01 1F 01 0E 01 0E */
112
	  if ( n == 0X13131212 ) goto weak;
Niels Möller's avatar
Niels Möller committed
113
114
	} else {
	  /* 01 E0 01 E0 01 F1 01 F1 */
115
	  if ( n == 0X14141515 ) goto weak;
Niels Möller's avatar
Niels Möller committed
116
	  /* 01 FE 01 FE 01 FE 01 FE */
117
	  if ( n == 0X16161616 ) goto weak;
Niels Möller's avatar
Niels Möller committed
118
119
120
121
	}
      } else {
	if ( n < 0X34342525 ) {
	  /* 1F 01 1F 01 0E 01 0E 01 */
122
	  if ( n == 0X31312121 ) goto weak;
Niels Möller's avatar
Niels Möller committed
123
	  /* 1F 1F 1F 1F 0E 0E 0E 0E */	/* ? */
124
	  if ( n == 0X33332222 ) goto weak;
Niels Möller's avatar
Niels Möller committed
125
126
	} else {
	  /* 1F E0 1F E0 0E F1 0E F1 */
127
	  if ( n == 0X34342525 ) goto weak;
Niels Möller's avatar
Niels Möller committed
128
	  /* 1F FE 1F FE 0E FE 0E FE */
129
	  if ( n == 0X36362626 ) goto weak;
Niels Möller's avatar
Niels Möller committed
130
131
132
133
134
135
	}
      }
    } else {
      if ( n < 0X61616161 ) {
	if ( n < 0X44445555 ) {
	  /* E0 01 E0 01 F1 01 F1 01 */
136
	  if ( n == 0X41415151 ) goto weak;
Niels Möller's avatar
Niels Möller committed
137
	  /* E0 1F E0 1F F1 0E F1 0E */
138
	  if ( n == 0X43435252 ) goto weak;
Niels Möller's avatar
Niels Möller committed
139
140
	} else {
	  /* E0 E0 E0 E0 F1 F1 F1 F1 */	/* ? */
141
	  if ( n == 0X44445555 ) goto weak;
Niels Möller's avatar
Niels Möller committed
142
	  /* E0 FE E0 FE F1 FE F1 FE */
143
	  if ( n == 0X46465656 ) goto weak;
Niels Möller's avatar
Niels Möller committed
144
145
146
147
	}
      } else {
	if ( n < 0X64646565 ) {
	  /* FE 01 FE 01 FE 01 FE 01 */
148
	  if ( n == 0X61616161 ) goto weak;
Niels Möller's avatar
Niels Möller committed
149
	  /* FE 1F FE 1F FE 0E FE 0E */
150
	  if ( n == 0X63636262 ) goto weak;
Niels Möller's avatar
Niels Möller committed
151
152
	} else {
	  /* FE E0 FE E0 FE F1 FE F1 */
153
	  if ( n == 0X64646565 ) goto weak;
Niels Möller's avatar
Niels Möller committed
154
	  /* FE FE FE FE FE FE FE FE */
155
156
157
158
159
	  if ( n == 0X66666666 )
          {
          weak:
            ctx->status = DES_WEAK_KEY;
          }
Niels Möller's avatar
Niels Möller committed
160
161
162
163
164
	}
      }
    }
  }

165
  /* NOTE: We go on and expand the key, even if it was weak */
Niels Möller's avatar
Niels Möller committed
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
  /* explode the bits */
  n = 56;
  b0 = bits0;
  b1 = bits1;
  do {
    w = (256 | *key++) << 2;
    do {
      --n;
      b1[n] = 8 & w;
      w >>= 1;
      b0[n] = 4 & w;
    } while ( w >= 16 );
  } while ( n );

  /* put the bits in the correct places */
  n = 16;
  k = rotors;
  method = ctx->key;
  
  do {
    w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
    w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
    w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
    w <<= 8;
    w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
    w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
    w  |=  b1[k[10   ]] | b0[k[11   ]];
    w <<= 8;
    w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
    w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
    w  |=  b1[k[16   ]] | b0[k[17   ]];
    w <<= 8;
    w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
    w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
    w  |=  b1[k[22   ]] | b0[k[23   ]];

    method[0] = w;

    w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
    w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
    w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
    w <<= 8;
    w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
    w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
    w  |=  b1[k[10+24]] | b0[k[11+24]];
    w <<= 8;
    w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
    w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
    w  |=  b1[k[16+24]] | b0[k[17+24]];
    w <<= 8;
    w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
    w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
    w  |=  b1[k[22+24]] | b0[k[23+24]];

    ROR(w, 4, 28);		/* could be eliminated */
    method[1] = w;

    k	+= 48;
    method	+= 2;
  } while ( --n );

227
  return (ctx->status == DES_OK);
Niels Möller's avatar
Niels Möller committed
228
229
230
}

void
231
des_encrypt(const struct des_ctx *ctx,
Niels Möller's avatar
Niels Möller committed
232
233
234
235
	    unsigned length, uint8_t *dst,
	    const uint8_t *src)
{
  assert(!(length % DES_BLOCK_SIZE));
236
237
  assert(ctx->status == DES_OK);
  
Niels Möller's avatar
Niels Möller committed
238
239
240
241
242
243
244
245
246
247
  while (length)
    {
      DesSmallFipsEncrypt(dst, ctx->key, src);
      length -= DES_BLOCK_SIZE;
      src += DES_BLOCK_SIZE;
      dst += DES_BLOCK_SIZE;
    }
}

void
248
des_decrypt(const struct des_ctx *ctx,
Niels Möller's avatar
Niels Möller committed
249
250
251
252
	    unsigned length, uint8_t *dst,
	    const uint8_t *src)
{
  assert(!(length % DES_BLOCK_SIZE));
253
  assert(ctx->status == DES_OK);
Niels Möller's avatar
Niels Möller committed
254
255
256
257
258
259
260
261
262

  while (length)
    {
      DesSmallFipsDecrypt(dst, ctx->key, src);
      length -= DES_BLOCK_SIZE;
      src += DES_BLOCK_SIZE;
      dst += DES_BLOCK_SIZE;
    }
}