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