crypto.c revision 1.9
1/* $OpenBSD: crypto.c,v 1.9 2000/02/25 17:23:39 niklas Exp $ */ 2/* $EOM: crypto.c,v 1.28 2000/02/20 19:58:36 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 + 1); 128 des_set_odd_parity (DC key + 2); 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 + 1, ks->ks_des[1]); 133 des_set_key (DC key + 2, 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