crypto.c revision 1.6
1/*	$OpenBSD: crypto.c,v 1.6 1999/04/19 21:22:49 niklas Exp $	*/
2/*	$EOM: crypto.c,v 1.25 1999/04/17 23:20:21 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#define DC	(des_cblock *)
85
86enum cryptoerr
87des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
88{
89  /* des_set_key returns -1 for parity problems, and -2 for weak keys */
90  des_set_odd_parity (DC key);
91  switch (des_set_key (DC key, ks->ks_des[0]))
92    {
93    case -2:
94      return EWEAKKEY;
95    default:
96      return EOKAY;
97    }
98}
99
100void
101des1_encrypt (struct keystate *ks, u_int8_t *d, u_int16_t len)
102{
103  des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT);
104}
105
106void
107des1_decrypt (struct keystate *ks, u_int8_t *d, u_int16_t len)
108{
109  des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT);
110}
111
112enum cryptoerr
113des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
114{
115  des_set_odd_parity (DC key);
116  des_set_odd_parity (DC key + 1);
117  des_set_odd_parity (DC key + 2);
118
119  /* As of the draft Tripe-DES does not check for weak keys */
120  des_set_key (DC key, ks->ks_des[0]);
121  des_set_key (DC key + 1, ks->ks_des[1]);
122  des_set_key (DC key + 2, ks->ks_des[2]);
123
124  return EOKAY;
125}
126
127void
128des3_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
129{
130  u_int8_t iv[MAXBLK];
131
132  memcpy (iv, ks->riv, ks->xf->blocksize);
133  des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
134			ks->ks_des[2], DC iv, DES_ENCRYPT);
135}
136
137void
138des3_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
139{
140  u_int8_t iv[MAXBLK];
141
142  memcpy (iv, ks->riv, ks->xf->blocksize);
143  des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1],
144			ks->ks_des[2], DC iv, DES_DECRYPT);
145}
146#undef DC
147
148enum cryptoerr
149blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
150{
151  blf_key (&ks->ks_blf, key, len);
152
153  return EOKAY;
154}
155
156void
157blf_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
158{
159  u_int16_t i, blocksize = ks->xf->blocksize;
160  u_int8_t *iv = ks->liv;
161  u_int32_t xl, xr;
162
163  memcpy (iv, ks->riv, blocksize);
164
165  for (i = 0; i < len; data += blocksize, i += blocksize)
166    {
167      XOR64 (data, iv);
168      xl = GET_32BIT_BIG (data);
169      xr = GET_32BIT_BIG (data + 4);
170      Blowfish_encipher (&ks->ks_blf, &xl, &xr);
171      SET_32BIT_BIG (data, xl);
172      SET_32BIT_BIG (data + 4, xr);
173      SET64 (iv, data);
174    }
175}
176
177void
178blf_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
179{
180  u_int16_t i, blocksize = ks->xf->blocksize;
181  u_int32_t xl, xr;
182
183  data += len - blocksize;
184  for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize)
185    {
186      xl = GET_32BIT_BIG (data);
187      xr = GET_32BIT_BIG (data + 4);
188      Blowfish_decipher (&ks->ks_blf, &xl, &xr);
189      SET_32BIT_BIG (data, xl);
190      SET_32BIT_BIG (data + 4, xr);
191      XOR64 (data, data - blocksize);
192
193    }
194  xl = GET_32BIT_BIG (data);
195  xr = GET_32BIT_BIG (data + 4);
196  Blowfish_decipher (&ks->ks_blf, &xl, &xr);
197  SET_32BIT_BIG (data, xl);
198  SET_32BIT_BIG (data + 4, xr);
199  XOR64 (data, ks->riv);
200}
201
202enum cryptoerr
203cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
204{
205  cast_setkey (&ks->ks_cast, key, len);
206  return EOKAY;
207}
208
209void
210cast1_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
211{
212  u_int16_t i, blocksize = ks->xf->blocksize;
213  u_int8_t *iv = ks->liv;
214
215  memcpy (iv, ks->riv, blocksize);
216
217  for (i = 0; i < len; data += blocksize, i += blocksize)
218    {
219      XOR64 (data, iv);
220      cast_encrypt (&ks->ks_cast, data, data);
221      SET64 (iv, data);
222    }
223}
224
225void
226cast1_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
227{
228  u_int16_t i, blocksize = ks->xf->blocksize;
229
230  data += len - blocksize;
231  for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize)
232    {
233      cast_decrypt (&ks->ks_cast, data, data);
234      XOR64 (data, data - blocksize);
235    }
236  cast_decrypt (&ks->ks_cast, data, data);
237  XOR64 (data, ks->riv);
238}
239
240struct crypto_xf *
241crypto_get (enum transform id)
242{
243  int i;
244
245  for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++)
246    if (id == transforms[i].id)
247      return &transforms[i];
248
249  return 0;
250}
251
252struct keystate *
253crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len,
254	     enum cryptoerr *err)
255{
256  struct keystate *ks;
257
258  if (len < xf->keymin || len > xf->keymax)
259    {
260      log_debug (LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len);
261      *err = EKEYLEN;
262      return 0;
263    }
264
265  ks = calloc (1, sizeof *ks);
266  if (!ks)
267    {
268      log_error ("crypto_init: calloc (1, %d) failed", sizeof *ks);
269      *err = ENOCRYPTO;
270      return 0;
271    }
272
273  ks->xf = xf;
274
275  /* Setup the IV.  */
276  ks->riv = ks->iv;
277  ks->liv = ks->iv2;
278
279  log_debug_buf (LOG_CRYPTO, 40, "crypto_init: key", key, len);
280
281  *err = xf->init (ks, key, len);
282  if (*err != EOKAY)
283    {
284      log_debug (LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
285		 xf->name);
286      free (ks);
287      return 0;
288    }
289
290  return ks;
291}
292
293void
294crypto_update_iv (struct keystate *ks)
295{
296  u_int8_t *tmp;
297
298  tmp = ks->riv;
299  ks->riv = ks->liv;
300  ks->liv = tmp;
301
302  log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
303		 ks->xf->blocksize);
304}
305
306void
307crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len)
308{
309  memcpy (ks->riv, buf, len);
310
311  log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv,
312		 len);
313}
314
315void
316crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
317{
318  log_debug_buf (LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf,
319		 len);
320  ks->xf->encrypt (ks, buf, len);
321  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
322  log_debug_buf (LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf,
323		 len);
324}
325
326void
327crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
328{
329  log_debug_buf (LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf,
330		 len);
331  /*
332   * XXX There is controversy about the correctness of updating the IV
333   * like this.
334   */
335  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
336  ks->xf->decrypt (ks, buf, len);;
337  log_debug_buf (LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf,
338		 len);
339}
340
341/* Make a copy of the keystate pointed to by OKS.  */
342struct keystate *
343crypto_clone_keystate (struct keystate *oks)
344{
345  struct keystate *ks;
346
347  ks = malloc (sizeof *ks);
348  if (!ks)
349    {
350      log_error ("crypto_clone_keystate: malloc (%d) failed", sizeof *ks);
351      return 0;
352    }
353  memcpy (ks, oks, sizeof *ks);
354  if (oks->riv == oks->iv)
355    {
356      ks->riv = ks->iv;
357      ks->liv = ks->iv2;
358    }
359  else
360    {
361      ks->riv = ks->iv2;
362      ks->liv = ks->iv;
363    }
364  return ks;
365}
366