crypto.c revision 1.12
1/* $OpenBSD: crypto.c,v 1.12 2002/06/01 07:44:21 deraadt 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#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 98enum cryptoerr 99des1_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 112void 113des1_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 118void 119des1_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 125enum cryptoerr 126des3_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 140void 141des3_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 150void 151des3_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 163enum cryptoerr 164blf_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 171void 172blf_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 192void 193blf_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 219enum cryptoerr 220cast_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 226void 227cast1_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 242void 243cast1_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 258struct crypto_xf * 259crypto_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 270struct keystate * 271crypto_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, %lu) failed", 287 (unsigned long)sizeof *ks); 288 *err = ENOCRYPTO; 289 return 0; 290 } 291 292 ks->xf = xf; 293 294 /* Setup the IV. */ 295 ks->riv = ks->iv; 296 ks->liv = ks->iv2; 297 298 LOG_DBG_BUF ((LOG_CRYPTO, 40, "crypto_init: key", key, len)); 299 300 *err = xf->init (ks, key, len); 301 if (*err != EOKAY) 302 { 303 LOG_DBG ((LOG_CRYPTO, 30, "crypto_init: weak key found for %s", 304 xf->name)); 305 free (ks); 306 return 0; 307 } 308 309 return ks; 310} 311 312void 313crypto_update_iv (struct keystate *ks) 314{ 315 u_int8_t *tmp; 316 317 tmp = ks->riv; 318 ks->riv = ks->liv; 319 ks->liv = tmp; 320 321 LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv, 322 ks->xf->blocksize)); 323} 324 325void 326crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len) 327{ 328 memcpy (ks->riv, buf, len); 329 330 LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv, 331 len)); 332} 333 334void 335crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 336{ 337 LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf, 338 len)); 339 ks->xf->encrypt (ks, buf, len); 340 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 341 LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf, 342 len)); 343} 344 345void 346crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 347{ 348 LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf, 349 len)); 350 /* 351 * XXX There is controversy about the correctness of updating the IV 352 * like this. 353 */ 354 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 355 ks->xf->decrypt (ks, buf, len);; 356 LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf, 357 len)); 358} 359 360/* Make a copy of the keystate pointed to by OKS. */ 361struct keystate * 362crypto_clone_keystate (struct keystate *oks) 363{ 364 struct keystate *ks; 365 366 ks = malloc (sizeof *ks); 367 if (!ks) 368 { 369 log_error ("crypto_clone_keystate: malloc (%lu) failed", 370 (unsigned long)sizeof *ks); 371 return 0; 372 } 373 memcpy (ks, oks, sizeof *ks); 374 if (oks->riv == oks->iv) 375 { 376 ks->riv = ks->iv; 377 ks->liv = ks->iv2; 378 } 379 else 380 { 381 ks->riv = ks->iv2; 382 ks->liv = ks->iv; 383 } 384 return ks; 385} 386