des-compat.c 5.56 KB
Newer Older
1
/* des-compat.c
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

   The des block cipher, old libdes/openssl-style interface.

   Copyright (C) 2001 Niels Möller

   This file is part of GNU Nettle.

   GNU Nettle is free software: you can redistribute it and/or
   modify it under the terms of either:

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at your
       option) any later version.

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at your
       option) any later version.

   or both in parallel, as here.

   GNU Nettle is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see http://www.gnu.org/licenses/.
*/
Niels Möller's avatar
Niels Möller committed
33

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

38
#include <stdlib.h>
39
40
41
#include <string.h>
#include <assert.h>

Niels Möller's avatar
Niels Möller committed
42
43
44
#include "des-compat.h"

#include "cbc.h"
45
#include "macros.h"
Niels Möller's avatar
Niels Möller committed
46
47
#include "memxor.h"

48
struct des_compat_des3 { const struct des_ctx *keys[3]; }; 
49
50
51

static void
des_compat_des3_encrypt(struct des_compat_des3 *ctx,
52
			size_t length, uint8_t *dst, const uint8_t *src)
53
{
54
55
56
  nettle_des_encrypt(ctx->keys[0], length, dst, src);
  nettle_des_decrypt(ctx->keys[1], length, dst, dst);
  nettle_des_encrypt(ctx->keys[2], length, dst, dst);
57
58
59
60
}

static void
des_compat_des3_decrypt(struct des_compat_des3 *ctx,
61
			size_t length, uint8_t *dst, const uint8_t *src)
Niels Möller's avatar
Niels Möller committed
62
{
63
64
65
  nettle_des_decrypt(ctx->keys[2], length, dst, src);
  nettle_des_encrypt(ctx->keys[1], length, dst, dst);
  nettle_des_decrypt(ctx->keys[0], length, dst, dst);
66
67
68
}

void
69
des_ecb3_encrypt(const_des_cblock *src, des_cblock *dst,
70
71
72
		 des_key_schedule k1,
		 des_key_schedule k2,
		 des_key_schedule k3, int enc)
73
{
74
75
76
77
  struct des_compat_des3 keys;
  keys.keys[0] = k1;
  keys.keys[1] = k2;
  keys.keys[2] = k3;
78
79

  ((enc == DES_ENCRYPT) ? des_compat_des3_encrypt : des_compat_des3_decrypt)
80
    (&keys, DES_BLOCK_SIZE, *dst, *src);
Niels Möller's avatar
Niels Möller committed
81
82
}

83
84
85
86
/* If input is not a integral number of blocks, the final block is
   padded with zeros, no length field or anything like that. That's
   pretty broken, since it means that "$100" and "$100\0" always have
   the same checksum, but I think that's how it's supposed to work. */
87
uint32_t
88
des_cbc_cksum(const uint8_t *src, des_cblock *dst,
89
	      long length, des_key_schedule ctx,
90
	      const_des_cblock *iv)
Niels Möller's avatar
Niels Möller committed
91
92
93
94
95
{
  /* FIXME: I'm not entirely sure how this function is supposed to
   * work, in particular what it should return, and if iv can be
   * modified. */
  uint8_t block[DES_BLOCK_SIZE];
96
97

  memcpy(block, *iv, DES_BLOCK_SIZE);
98
99

  while (length >= DES_BLOCK_SIZE)
Niels Möller's avatar
Niels Möller committed
100
    {
101
      memxor(block, src, DES_BLOCK_SIZE);
102
      nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block);
103
104
105
106
107
108
109
110

      src += DES_BLOCK_SIZE;
      length -= DES_BLOCK_SIZE;	  
    }
  if (length > 0)
    {
      memxor(block, src, length);
      nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block);	  
Niels Möller's avatar
Niels Möller committed
111
    }
112
  memcpy(*dst, block, DES_BLOCK_SIZE);
113
114

  return LE_READ_UINT32(block + 4);
Niels Möller's avatar
Niels Möller committed
115
116
}

117
void
118
des_ncbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
119
                 des_key_schedule ctx, des_cblock *iv,
120
121
122
123
124
                 int enc)
{
  switch (enc)
    {
    case DES_ENCRYPT:
125
      nettle_cbc_encrypt(ctx, (nettle_cipher_func *) des_encrypt,
126
127
			 DES_BLOCK_SIZE, *iv,
			 length, *dst, *src);
128
129
      break;
    case DES_DECRYPT:
130
      nettle_cbc_decrypt(ctx,
131
			 (nettle_cipher_func *) des_decrypt,
132
133
			 DES_BLOCK_SIZE, *iv,
			 length, *dst, *src);
134
135
136
137
138
      break;
    default:
      abort();
    }
}
Niels Möller's avatar
Niels Möller committed
139
140

void
141
142
des_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
		des_key_schedule ctx, const_des_cblock *civ,
Niels Möller's avatar
Niels Möller committed
143
144
		int enc)
{
145
  des_cblock iv;
146
147

  memcpy(iv, civ, DES_BLOCK_SIZE);
Niels Möller's avatar
Niels Möller committed
148

149
  des_ncbc_encrypt(src, dst, length, ctx, &iv, enc);
150
}
Niels Möller's avatar
Niels Möller committed
151

152

Niels Möller's avatar
Niels Möller committed
153
void
154
des_ecb_encrypt(const_des_cblock *src, des_cblock *dst,
155
		des_key_schedule ctx,
Niels Möller's avatar
Niels Möller committed
156
157
		int enc)
{
158
159
  ((enc == DES_ENCRYPT) ? nettle_des_encrypt : nettle_des_decrypt)
    (ctx, DES_BLOCK_SIZE, *dst, *src);
Niels Möller's avatar
Niels Möller committed
160
}
161

Niels Möller's avatar
Niels Möller committed
162
void
163
des_ede3_cbc_encrypt(const_des_cblock *src, des_cblock *dst, long length,
164
165
166
		     des_key_schedule k1,
		     des_key_schedule k2,
		     des_key_schedule k3,
167
		     des_cblock *iv,
168
169
		     int enc)
{
170
171
172
173
  struct des_compat_des3 keys;
  keys.keys[0] = k1;
  keys.keys[1] = k2;
  keys.keys[2] = k3;
174

175
176
177
  switch (enc)
    {
    case DES_ENCRYPT:
178
      nettle_cbc_encrypt(&keys, (nettle_cipher_func *) des_compat_des3_encrypt,
179
180
			 DES_BLOCK_SIZE, *iv,
			 length, *dst, *src);
181
182
      break;
    case DES_DECRYPT:
183
      nettle_cbc_decrypt(&keys, (nettle_cipher_func *) des_compat_des3_decrypt,
184
185
			 DES_BLOCK_SIZE, *iv,
			 length, *dst, *src);
186
187
188
189
      break;
    default:
      abort();
    }
190
}
Niels Möller's avatar
Niels Möller committed
191
192

int
193
des_set_odd_parity(des_cblock *key)
194
{
195
  nettle_des_fix_parity(DES_KEY_SIZE, *key, *key);
Niels Möller's avatar
Niels Möller committed
196
197
198

  /* FIXME: What to return? */
  return 0;
199
}
Niels Möller's avatar
Niels Möller committed
200

201
202
203
204
205
206
207
208
209
210

/* If des_check_key is non-zero, returns
 *
 *   0 for ok, -1 for bad parity, and -2 for weak keys.
 *
 * If des_check_key is zero (the default), always returns zero.
 */

int des_check_key = 0;

Niels Möller's avatar
Niels Möller committed
211
int
212
des_key_sched(const_des_cblock *key, des_key_schedule ctx)
213
{
214
215
216
  if (des_check_key && !des_check_parity (DES_KEY_SIZE, *key))
    /* Bad parity */
    return -1;
217
  
218
219
220
221
222
  if (!nettle_des_set_key(ctx, *key) && des_check_key)
    /* Weak key */
    return -2;

  return 0;
223
}
Niels Möller's avatar
Niels Möller committed
224
225

int
226
des_is_weak_key(const_des_cblock *key)
227
228
229
{
  struct des_ctx ctx;

230
  return !nettle_des_set_key(&ctx, *key);
231
}