crypto.c revision 1.7
1/*	$OpenBSD: crypto.c,v 1.7 2000/01/26 15:23:04 niklas Exp $	*/
2/*	$EOM: crypto.c,v 1.26 1999/12/08 20:31:02 niklas Exp $	*/
3
4/*
5 * Copyright (c) 1998 Niels Provos.  All rights reserved.
6 * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Ericsson Radio Systems.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * This code was written under funding by Ericsson Radio Systems.
36 */
37
38#include <sys/param.h>
39#include <stdlib.h>
40#include <string.h>
41
42#include "sysdep.h"
43
44#include "crypto.h"
45#include "log.h"
46
47enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t);
48enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t);
49enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t);
50enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t);
51void des1_encrypt (struct keystate *, u_int8_t *, u_int16_t);
52void des1_decrypt (struct keystate *, u_int8_t *, u_int16_t);
53void des3_encrypt (struct keystate *, u_int8_t *, u_int16_t);
54void des3_decrypt (struct keystate *, u_int8_t *, u_int16_t);
55void blf_encrypt (struct keystate *, u_int8_t *, u_int16_t);
56void blf_decrypt (struct keystate *, u_int8_t *, u_int16_t);
57void cast1_encrypt (struct keystate *, u_int8_t *, u_int16_t);
58void cast1_decrypt (struct keystate *, u_int8_t *, u_int16_t);
59
60struct crypto_xf transforms[] = {
61  {
62    DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, 0,
63    des1_init,
64    des1_encrypt, des1_decrypt
65  },
66  {
67    TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, 0,
68    des3_init,
69    des3_encrypt, des3_decrypt
70  },
71  {
72    BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, 0,
73    blf_init,
74    blf_encrypt, blf_decrypt
75  },
76  {
77    CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, 0,
78    cast_init,
79    cast1_encrypt, cast1_decrypt
80  },
81};
82
83/* Hmm, the function prototypes for des are really dumb */
84#ifdef __OpenBSD__
85#define DC	(des_cblock *)
86#else
87#define DC	(void *)
88#endif
89
90enum cryptoerr
91des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
92{
93  /* des_set_key returns -1 for parity problems, and -2 for weak keys */
94  des_set_odd_parity (DC key);
95  switch (des_set_key (DC key, ks->ks_des[0]))
96    {
97    case -2:
98      return EWEAKKEY;
99    default:
100      return EOKAY;
101    }
102}
103
104void
105des1_encrypt (struct keystate *ks, u_int8_t *d, u_int16_t len)
106{
107  des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT);
108}
109
110void
111des1_decrypt (struct keystate *ks, u_int8_t *d, u_int16_t len)
112{
113  des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT);
114}
115
116enum cryptoerr
117des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
118{
119  des_set_odd_parity (DC key);
120  des_set_odd_parity (DC key + 1);
121  des_set_odd_parity (DC key + 2);
122
123  /* As of the draft Tripe-DES does not check for weak keys */
124  des_set_key (DC key, ks->ks_des[0]);
125  des_set_key (DC key + 1, ks->ks_des[1]);
126  des_set_key (DC key + 2, ks->ks_des[2]);
127
128  return EOKAY;
129}
130
131void
132des3_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
133{
134  u_int8_t iv[MAXBLK];
135
136  memcpy (iv, ks->riv, ks->xf->blocksize);
137  des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
138			ks->ks_des[2], DC iv, DES_ENCRYPT);
139}
140
141void
142des3_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
143{
144  u_int8_t iv[MAXBLK];
145
146  memcpy (iv, ks->riv, ks->xf->blocksize);
147  des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
148			ks->ks_des[2], DC iv, DES_DECRYPT);
149}
150#undef DC
151
152enum cryptoerr
153blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
154{
155  blf_key (&ks->ks_blf, key, len);
156
157  return EOKAY;
158}
159
160void
161blf_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
162{
163  u_int16_t i, blocksize = ks->xf->blocksize;
164  u_int8_t *iv = ks->liv;
165  u_int32_t xl, xr;
166
167  memcpy (iv, ks->riv, blocksize);
168
169  for (i = 0; i < len; data += blocksize, i += blocksize)
170    {
171      XOR64 (data, iv);
172      xl = GET_32BIT_BIG (data);
173      xr = GET_32BIT_BIG (data + 4);
174      Blowfish_encipher (&ks->ks_blf, &xl, &xr);
175      SET_32BIT_BIG (data, xl);
176      SET_32BIT_BIG (data + 4, xr);
177      SET64 (iv, data);
178    }
179}
180
181void
182blf_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
183{
184  u_int16_t i, blocksize = ks->xf->blocksize;
185  u_int32_t xl, xr;
186
187  data += len - blocksize;
188  for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize)
189    {
190      xl = GET_32BIT_BIG (data);
191      xr = GET_32BIT_BIG (data + 4);
192      Blowfish_decipher (&ks->ks_blf, &xl, &xr);
193      SET_32BIT_BIG (data, xl);
194      SET_32BIT_BIG (data + 4, xr);
195      XOR64 (data, data - blocksize);
196
197    }
198  xl = GET_32BIT_BIG (data);
199  xr = GET_32BIT_BIG (data + 4);
200  Blowfish_decipher (&ks->ks_blf, &xl, &xr);
201  SET_32BIT_BIG (data, xl);
202  SET_32BIT_BIG (data + 4, xr);
203  XOR64 (data, ks->riv);
204}
205
206enum cryptoerr
207cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
208{
209  cast_setkey (&ks->ks_cast, key, len);
210  return EOKAY;
211}
212
213void
214cast1_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
215{
216  u_int16_t i, blocksize = ks->xf->blocksize;
217  u_int8_t *iv = ks->liv;
218
219  memcpy (iv, ks->riv, blocksize);
220
221  for (i = 0; i < len; data += blocksize, i += blocksize)
222    {
223      XOR64 (data, iv);
224      cast_encrypt (&ks->ks_cast, data, data);
225      SET64 (iv, data);
226    }
227}
228
229void
230cast1_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
231{
232  u_int16_t i, blocksize = ks->xf->blocksize;
233
234  data += len - blocksize;
235  for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize)
236    {
237      cast_decrypt (&ks->ks_cast, data, data);
238      XOR64 (data, data - blocksize);
239    }
240  cast_decrypt (&ks->ks_cast, data, data);
241  XOR64 (data, ks->riv);
242}
243
244struct crypto_xf *
245crypto_get (enum transform id)
246{
247  int i;
248
249  for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++)
250    if (id == transforms[i].id)
251      return &transforms[i];
252
253  return 0;
254}
255
256struct keystate *
257crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len,
258	     enum cryptoerr *err)
259{
260  struct keystate *ks;
261
262  if (len < xf->keymin || len > xf->keymax)
263    {
264      log_debug (LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len);
265      *err = EKEYLEN;
266      return 0;
267    }
268
269  ks = calloc (1, sizeof *ks);
270  if (!ks)
271    {
272      log_error ("crypto_init: calloc (1, %d) failed", sizeof *ks);
273      *err = ENOCRYPTO;
274      return 0;
275    }
276
277  ks->xf = xf;
278
279  /* Setup the IV.  */
280  ks->riv = ks->iv;
281  ks->liv = ks->iv2;
282
283  log_debug_buf (LOG_CRYPTO, 40, "crypto_init: key", key, len);
284
285  *err = xf->init (ks, key, len);
286  if (*err != EOKAY)
287    {
288      log_debug (LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
289		 xf->name);
290      free (ks);
291      return 0;
292    }
293
294  return ks;
295}
296
297void
298crypto_update_iv (struct keystate *ks)
299{
300  u_int8_t *tmp;
301
302  tmp = ks->riv;
303  ks->riv = ks->liv;
304  ks->liv = tmp;
305
306  log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
307		 ks->xf->blocksize);
308}
309
310void
311crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len)
312{
313  memcpy (ks->riv, buf, len);
314
315  log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv,
316		 len);
317}
318
319void
320crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
321{
322  log_debug_buf (LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf,
323		 len);
324  ks->xf->encrypt (ks, buf, len);
325  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
326  log_debug_buf (LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf,
327		 len);
328}
329
330void
331crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
332{
333  log_debug_buf (LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf,
334		 len);
335  /*
336   * XXX There is controversy about the correctness of updating the IV
337   * like this.
338   */
339  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
340  ks->xf->decrypt (ks, buf, len);;
341  log_debug_buf (LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf,
342		 len);
343}
344
345/* Make a copy of the keystate pointed to by OKS.  */
346struct keystate *
347crypto_clone_keystate (struct keystate *oks)
348{
349  struct keystate *ks;
350
351  ks = malloc (sizeof *ks);
352  if (!ks)
353    {
354      log_error ("crypto_clone_keystate: malloc (%d) failed", sizeof *ks);
355      return 0;
356    }
357  memcpy (ks, oks, sizeof *ks);
358  if (oks->riv == oks->iv)
359    {
360      ks->riv = ks->iv;
361      ks->liv = ks->iv2;
362    }
363  else
364    {
365      ks->riv = ks->iv2;
366      ks->liv = ks->iv;
367    }
368  return ks;
369}
370