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
}