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