crypto.c revision 1.11
1/*	$OpenBSD: crypto.c,v 1.11 2001/02/24 04:42:48 angelos 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, %d) failed", sizeof *ks);
287      *err = ENOCRYPTO;
288      return 0;
289    }
290
291  ks->xf = xf;
292
293  /* Setup the IV.  */
294  ks->riv = ks->iv;
295  ks->liv = ks->iv2;
296
297  LOG_DBG_BUF ((LOG_CRYPTO, 40, "crypto_init: key", key, len));
298
299  *err = xf->init (ks, key, len);
300  if (*err != EOKAY)
301    {
302      LOG_DBG ((LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
303		xf->name));
304      free (ks);
305      return 0;
306    }
307
308  return ks;
309}
310
311void
312crypto_update_iv (struct keystate *ks)
313{
314  u_int8_t *tmp;
315
316  tmp = ks->riv;
317  ks->riv = ks->liv;
318  ks->liv = tmp;
319
320  LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
321		ks->xf->blocksize));
322}
323
324void
325crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len)
326{
327  memcpy (ks->riv, buf, len);
328
329  LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv,
330		len));
331}
332
333void
334crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
335{
336  LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf,
337		len));
338  ks->xf->encrypt (ks, buf, len);
339  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
340  LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf,
341		len));
342}
343
344void
345crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
346{
347  LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf,
348		len));
349  /*
350   * XXX There is controversy about the correctness of updating the IV
351   * like this.
352   */
353  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
354  ks->xf->decrypt (ks, buf, len);;
355  LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf,
356		len));
357}
358
359/* Make a copy of the keystate pointed to by OKS.  */
360struct keystate *
361crypto_clone_keystate (struct keystate *oks)
362{
363  struct keystate *ks;
364
365  ks = malloc (sizeof *ks);
366  if (!ks)
367    {
368      log_error ("crypto_clone_keystate: malloc (%d) failed", sizeof *ks);
369      return 0;
370    }
371  memcpy (ks, oks, sizeof *ks);
372  if (oks->riv == oks->iv)
373    {
374      ks->riv = ks->iv;
375      ks->liv = ks->iv2;
376    }
377  else
378    {
379      ks->riv = ks->iv2;
380      ks->liv = ks->iv;
381    }
382  return ks;
383}
384