des-compat.c 5.55 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 38 39 40
#if HAVE_CONFIG_H
# include "config.h"
#endif

#include <string.h>
#include <assert.h>

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

#include "cbc.h"
44
#include "macros.h"
45 46
#include "memxor.h"

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

static void
des_compat_des3_encrypt(struct des_compat_des3 *ctx,
			uint32_t length, uint8_t *dst, const uint8_t *src)
{
53 54 55
  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);
56 57 58 59 60
}

static void
des_compat_des3_decrypt(struct des_compat_des3 *ctx,
			uint32_t length, uint8_t *dst, const uint8_t *src)
Niels Möller's avatar
Niels Möller committed
61
{
62 63 64
  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);
65 66 67
}

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

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

82 83 84 85
/* 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. */
86
uint32_t
87
des_cbc_cksum(const uint8_t *src, des_cblock *dst,
88
	      long length, des_key_schedule ctx,
89
	      const_des_cblock *iv)
90 91 92 93 94
{
  /* 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];
95 96

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

  while (length >= DES_BLOCK_SIZE)
99
    {
100
      memxor(block, src, DES_BLOCK_SIZE);
101
      nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block);
102 103 104 105 106 107 108 109

      src += DES_BLOCK_SIZE;
      length -= DES_BLOCK_SIZE;	  
    }
  if (length > 0)
    {
      memxor(block, src, length);
      nettle_des_encrypt(ctx, DES_BLOCK_SIZE, block, block);	  
110
    }
111
  memcpy(*dst, block, DES_BLOCK_SIZE);
112 113

  return LE_READ_UINT32(block + 4);
114 115
}

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

void
140 141
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
142 143
		int enc)
{
144
  des_cblock iv;
145 146

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

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

151

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

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

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

int
192
des_set_odd_parity(des_cblock *key)
193
{
194
  nettle_des_fix_parity(DES_KEY_SIZE, *key, *key);
195 196 197

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

200 201 202 203 204 205 206 207 208 209

/* 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
210
int
211
des_key_sched(const_des_cblock *key, des_key_schedule ctx)
212
{
213 214 215
  if (des_check_key && !des_check_parity (DES_KEY_SIZE, *key))
    /* Bad parity */
    return -1;
216
  
217 218 219 220 221
  if (!nettle_des_set_key(ctx, *key) && des_check_key)
    /* Weak key */
    return -2;

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

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

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