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