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