crypto.c revision 1.16
1/*	$OpenBSD: crypto.c,v 1.16 2003/08/28 14:43:35 markus 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 evp_init (struct keystate *, u_int8_t *, u_int16_t,
43    const EVP_CIPHER *);
44enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t);
45enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t);
46enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t);
47enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t);
48enum cryptoerr aes_init (struct keystate *, u_int8_t *, u_int16_t);
49void evp_encrypt (struct keystate *, u_int8_t *, u_int16_t);
50void evp_decrypt (struct keystate *, u_int8_t *, u_int16_t);
51
52struct crypto_xf transforms[] = {
53#ifdef USE_DES
54  {
55    DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, 0,
56    des1_init,
57    evp_encrypt, evp_decrypt
58  },
59#endif
60#ifdef USE_TRIPLEDES
61  {
62    TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, 0,
63    des3_init,
64    evp_encrypt, evp_decrypt
65  },
66#endif
67#ifdef USE_BLOWFISH
68  {
69    BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, 0,
70    blf_init,
71    evp_encrypt, evp_decrypt
72  },
73#endif
74#ifdef USE_CAST
75  {
76    CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, 0,
77    cast_init,
78    evp_encrypt, evp_decrypt
79  },
80#endif
81#ifdef USE_AES
82  {
83    AES_CBC, "AES (CBC-Mode)", 16, 32, 2*BLOCKSIZE, 0,
84    aes_init,
85    evp_encrypt, evp_decrypt
86  },
87#endif
88};
89
90#ifdef USE_DES
91enum cryptoerr
92des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
93{
94  const EVP_CIPHER *evp;
95
96  evp = EVP_des_cbc();
97  return evp_init (ks, key, len, evp);
98}
99#endif
100
101#ifdef USE_TRIPLEDES
102enum cryptoerr
103des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
104{
105  const EVP_CIPHER *evp;
106
107  evp = EVP_des_ede3_cbc();
108  return evp_init (ks, key, len, evp);
109}
110#endif
111
112#ifdef USE_BLOWFISH
113enum cryptoerr
114blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
115{
116  const EVP_CIPHER *evp;
117
118  evp = EVP_bf_cbc();
119  return evp_init (ks, key, len, evp);
120}
121#endif
122
123#ifdef USE_CAST
124enum cryptoerr
125cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
126{
127  const EVP_CIPHER *evp;
128
129  evp = EVP_cast5_cbc();
130  return evp_init (ks, key, len, evp);
131}
132#endif
133
134#ifdef USE_AES
135enum cryptoerr
136aes_init (struct keystate *ks, u_int8_t *key, u_int16_t len)
137{
138  const EVP_CIPHER *evp;
139
140  switch (8 * len)
141    {
142    case 128:
143      evp = EVP_aes_128_cbc();
144      break;
145    case 192:
146      evp = EVP_aes_192_cbc();
147      break;
148    case 256:
149      evp = EVP_aes_256_cbc();
150      break;
151    default:
152      return EKEYLEN;
153    }
154  return evp_init (ks, key, len, evp);
155}
156#endif
157
158enum cryptoerr
159evp_init (struct keystate *ks, u_int8_t *key, u_int16_t len, const EVP_CIPHER *evp)
160{
161  EVP_CIPHER_CTX_init(&ks->ks_evpenc);
162  EVP_CIPHER_CTX_init(&ks->ks_evpdec);
163
164  if (EVP_CIPHER_key_length(evp) != len
165      && !(EVP_CIPHER_flags(evp) & EVP_CIPH_VARIABLE_LENGTH))
166    return EKEYLEN;
167  if (EVP_CipherInit(&ks->ks_evpenc, evp, key, NULL, 1) <= 0)
168    return EKEYLEN;
169  if (EVP_CipherInit(&ks->ks_evpdec, evp, key, NULL, 0) <= 0)
170    return EKEYLEN;
171  return EOKAY;
172}
173
174void
175evp_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
176{
177  (void) EVP_CipherInit(&ks->ks_evpenc, NULL, NULL, ks->riv, -1);
178  EVP_Cipher(&ks->ks_evpenc, data, data, len);
179}
180
181void
182evp_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len)
183{
184  (void) EVP_CipherInit(&ks->ks_evpdec, NULL, NULL, ks->riv, -1);
185  EVP_Cipher(&ks->ks_evpdec, data, data, len);
186}
187
188struct crypto_xf *
189crypto_get (enum transform id)
190{
191  int i;
192
193  for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++)
194    if (id == transforms[i].id)
195      return &transforms[i];
196
197  return 0;
198}
199
200struct keystate *
201crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len,
202	     enum cryptoerr *err)
203{
204  struct keystate *ks;
205
206  if (len < xf->keymin || len > xf->keymax)
207    {
208      LOG_DBG ((LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len));
209      *err = EKEYLEN;
210      return 0;
211    }
212
213  ks = calloc (1, sizeof *ks);
214  if (!ks)
215    {
216      log_error ("crypto_init: calloc (1, %lu) failed",
217	(unsigned long)sizeof *ks);
218      *err = ENOCRYPTO;
219      return 0;
220    }
221
222  ks->xf = xf;
223
224  /* Setup the IV.  */
225  ks->riv = ks->iv;
226  ks->liv = ks->iv2;
227
228  LOG_DBG_BUF ((LOG_CRYPTO, 40, "crypto_init: key", key, len));
229
230  *err = xf->init (ks, key, len);
231  if (*err != EOKAY)
232    {
233      LOG_DBG ((LOG_CRYPTO, 30, "crypto_init: weak key found for %s",
234		xf->name));
235      free (ks);
236      return 0;
237    }
238
239  return ks;
240}
241
242void
243crypto_update_iv (struct keystate *ks)
244{
245  u_int8_t *tmp;
246
247  tmp = ks->riv;
248  ks->riv = ks->liv;
249  ks->liv = tmp;
250
251  LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv,
252		ks->xf->blocksize));
253}
254
255void
256crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len)
257{
258  memcpy (ks->riv, buf, len);
259
260  LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv,
261		len));
262}
263
264void
265crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
266{
267  LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf,
268		len));
269  ks->xf->encrypt (ks, buf, len);
270  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
271  LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf,
272		len));
273}
274
275void
276crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len)
277{
278  LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf,
279		len));
280  /*
281   * XXX There is controversy about the correctness of updating the IV
282   * like this.
283   */
284  memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize);
285  ks->xf->decrypt (ks, buf, len);
286  LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf,
287		len));
288}
289
290/* Make a copy of the keystate pointed to by OKS.  */
291struct keystate *
292crypto_clone_keystate (struct keystate *oks)
293{
294  struct keystate *ks;
295
296  ks = malloc (sizeof *ks);
297  if (!ks)
298    {
299      log_error ("crypto_clone_keystate: malloc (%lu) failed",
300	(unsigned long)sizeof *ks);
301      return 0;
302    }
303  memcpy (ks, oks, sizeof *ks);
304  if (oks->riv == oks->iv)
305    {
306      ks->riv = ks->iv;
307      ks->liv = ks->iv2;
308    }
309  else
310    {
311      ks->riv = ks->iv2;
312      ks->liv = ks->iv;
313    }
314  return ks;
315}
316