xref: /openbsd-src/sbin/isakmpd/crypto.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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 
47 enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t);
48 enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t);
49 enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t);
50 enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t);
51 void des1_encrypt (struct keystate *, u_int8_t *, u_int16_t);
52 void des1_decrypt (struct keystate *, u_int8_t *, u_int16_t);
53 void des3_encrypt (struct keystate *, u_int8_t *, u_int16_t);
54 void des3_decrypt (struct keystate *, u_int8_t *, u_int16_t);
55 void blf_encrypt (struct keystate *, u_int8_t *, u_int16_t);
56 void blf_decrypt (struct keystate *, u_int8_t *, u_int16_t);
57 void cast1_encrypt (struct keystate *, u_int8_t *, u_int16_t);
58 void cast1_decrypt (struct keystate *, u_int8_t *, u_int16_t);
59 
60 struct 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 
98 enum cryptoerr
99 des1_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 
112 void
113 des1_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 
118 void
119 des1_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
125 enum cryptoerr
126 des3_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 
140 void
141 des3_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 
150 void
151 des3_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
163 enum cryptoerr
164 blf_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 
171 void
172 blf_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 
192 void
193 blf_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
219 enum cryptoerr
220 cast_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 
226 void
227 cast1_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 
242 void
243 cast1_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 
258 struct crypto_xf *
259 crypto_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 
270 struct keystate *
271 crypto_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 
311 void
312 crypto_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 
324 void
325 crypto_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 
333 void
334 crypto_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 
344 void
345 crypto_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.  */
360 struct keystate *
361 crypto_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