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