crypto.c revision 1.2
1/* $OpenBSD: crypto.c,v 1.2 1998/11/15 00:43:51 niklas Exp $ */ 2 3/* 4 * Copyright (c) 1998 Niels Provos. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Ericsson Radio Systems. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * This code was written under funding by Ericsson Radio Systems. 34 */ 35 36#include <sys/param.h> 37#include <stdlib.h> 38#include <string.h> 39 40#include "crypto.h" 41#include "log.h" 42 43enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t); 44enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t); 45enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t); 46enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t); 47void des1_encrypt (struct keystate *, u_int8_t *, u_int16_t); 48void des1_decrypt (struct keystate *, u_int8_t *, u_int16_t); 49void des3_encrypt (struct keystate *, u_int8_t *, u_int16_t); 50void des3_decrypt (struct keystate *, u_int8_t *, u_int16_t); 51void blf_encrypt (struct keystate *, u_int8_t *, u_int16_t); 52void blf_decrypt (struct keystate *, u_int8_t *, u_int16_t); 53void cast1_encrypt (struct keystate *, u_int8_t *, u_int16_t); 54void cast1_decrypt (struct keystate *, u_int8_t *, u_int16_t); 55 56struct crypto_xf transforms[] = { 57 { 58 DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, NULL, 59 des1_init, 60 des1_encrypt, des1_decrypt 61 }, 62 { 63 TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, NULL, 64 des3_init, 65 des3_encrypt, des3_decrypt 66 }, 67 { 68 BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, NULL, 69 blf_init, 70 blf_encrypt, blf_decrypt 71 }, 72 { 73 CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, NULL, 74 cast_init, 75 cast1_encrypt, cast1_decrypt 76 }, 77}; 78 79/* Hmm, the function prototypes for des are really dumb */ 80#define DC (des_cblock *) 81 82enum cryptoerr 83des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 84{ 85 /* des_set_key returns -1 for parity problems, and -2 for weak keys */ 86 des_set_odd_parity (DC key); 87 switch (des_set_key (DC key, ks->ks_des[0])) 88 { 89 case -2: 90 return EWEAKKEY; 91 default: 92 return EOKAY; 93 } 94} 95 96void 97des1_encrypt (struct keystate *ks, u_int8_t *d, u_int16_t len) 98{ 99 des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT); 100} 101 102void 103des1_decrypt (struct keystate *ks, u_int8_t *d, u_int16_t len) 104{ 105 des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT); 106} 107 108enum cryptoerr 109des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 110{ 111 des_set_odd_parity (DC key); 112 des_set_odd_parity (DC key + 1); 113 des_set_odd_parity (DC key + 2); 114 115 /* As of the draft Tripe-DES does not check for weak keys */ 116 des_set_key (DC key, ks->ks_des[0]); 117 des_set_key (DC key + 1, ks->ks_des[1]); 118 des_set_key (DC key + 2, ks->ks_des[2]); 119 120 return EOKAY; 121} 122 123void 124des3_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 125{ 126 u_int8_t iv[MAXBLK]; 127 128 memcpy (iv, ks->riv, ks->xf->blocksize); 129 des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1], 130 ks->ks_des[2], DC iv, DES_ENCRYPT); 131} 132 133void 134des3_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 135{ 136 u_int8_t iv[MAXBLK]; 137 138 memcpy (iv, ks->riv, ks->xf->blocksize); 139 des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1], 140 ks->ks_des[2], DC iv, DES_DECRYPT); 141} 142#undef DC 143 144enum cryptoerr 145blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 146{ 147 blf_key (&ks->ks_blf, key, len); 148 149 return EOKAY; 150} 151 152void 153blf_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 154{ 155 u_int16_t i, blocksize = ks->xf->blocksize; 156 u_int8_t *iv = ks->liv; 157 u_int32_t xl, xr; 158 159 memcpy (iv, ks->riv, blocksize); 160 161 for (i = 0; i < len; data += blocksize, i += blocksize) 162 { 163 XOR64 (data, iv); 164 xl = GET_32BIT_BIG (data); 165 xr = GET_32BIT_BIG (data + 4); 166 Blowfish_encipher (&ks->ks_blf, &xl, &xr); 167 SET_32BIT_BIG (data, xl); 168 SET_32BIT_BIG (data + 4, xr); 169 SET64 (iv, data); 170 } 171} 172 173void 174blf_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 175{ 176 u_int16_t i, blocksize = ks->xf->blocksize; 177 u_int32_t xl, xr; 178 179 data += len - blocksize; 180 for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) 181 { 182 xl = GET_32BIT_BIG (data); 183 xr = GET_32BIT_BIG (data + 4); 184 Blowfish_decipher (&ks->ks_blf, &xl, &xr); 185 SET_32BIT_BIG (data, xl); 186 SET_32BIT_BIG (data + 4, xr); 187 XOR64 (data, data - blocksize); 188 189 } 190 xl = GET_32BIT_BIG (data); 191 xr = GET_32BIT_BIG (data + 4); 192 Blowfish_decipher (&ks->ks_blf, &xl, &xr); 193 SET_32BIT_BIG (data, xl); 194 SET_32BIT_BIG (data + 4, xr); 195 XOR64 (data, ks->riv); 196} 197 198enum cryptoerr 199cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 200{ 201 cast_setkey (&ks->ks_cast, key, len); 202 return EOKAY; 203} 204 205void 206cast1_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 207{ 208 u_int16_t i, blocksize = ks->xf->blocksize; 209 u_int8_t *iv = ks->liv; 210 211 memcpy (iv, ks->riv, blocksize); 212 213 for (i = 0; i < len; data += blocksize, i += blocksize) 214 { 215 XOR64 (data, iv); 216 cast_encrypt (&ks->ks_cast, data, data); 217 SET64 (iv, data); 218 } 219} 220 221void 222cast1_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 223{ 224 u_int16_t i, blocksize = ks->xf->blocksize; 225 226 data += len - blocksize; 227 for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) 228 { 229 cast_decrypt (&ks->ks_cast, data, data); 230 XOR64 (data, data - blocksize); 231 } 232 cast_decrypt (&ks->ks_cast, data, data); 233 XOR64 (data, ks->riv); 234} 235 236struct crypto_xf * 237crypto_get (enum transform id) 238{ 239 int i; 240 241 for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++) 242 if (id == transforms[i].id) 243 return &transforms[i]; 244 245 return 0; 246} 247 248struct keystate * 249crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len, 250 enum cryptoerr *err) 251{ 252 struct keystate *ks = NULL; 253 254 if (len < xf->keymin || len > xf->keymax) 255 { 256 log_debug (LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len); 257 *err = EKEYLEN; 258 return NULL; 259 } 260 261 if ((ks = calloc (1, sizeof (struct keystate))) == NULL) 262 { 263 *err = ENOCRYPTO; 264 return NULL; 265 } 266 267 ks->xf = xf; 268 269 /* Set up the iv */ 270 ks->riv = ks->iv; 271 ks->liv = ks->iv2; 272 273 log_debug_buf (LOG_CRYPTO, 40, "crypto_init: key", key, len); 274 275 *err = xf->init (ks, key, len); 276 if (*err != EOKAY) 277 { 278 log_debug (LOG_CRYPTO, 30, "crypto_init: weak key found for %s", 279 xf->name); 280 free (ks); 281 return NULL; 282 } 283 284 return ks; 285} 286 287void 288crypto_update_iv (struct keystate *ks) 289{ 290 u_int8_t *tmp; 291 292 tmp = ks->riv; 293 ks->riv = ks->liv; 294 ks->liv = tmp; 295 296 log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv, 297 ks->xf->blocksize); 298} 299 300void 301crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len) 302{ 303 memcpy (ks->riv, buf, len); 304 305 log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv, 306 len); 307} 308 309void 310crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 311{ 312 log_debug_buf (LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf, 313 len); 314 ks->xf->encrypt (ks, buf, len); 315 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 316 log_debug_buf (LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf, 317 len); 318} 319 320void 321crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 322{ 323 log_debug_buf (LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf, 324 len); 325 /* 326 * XXX There is controversy about the correctness of updating the IV 327 * like this. 328 */ 329 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 330 ks->xf->decrypt (ks, buf, len);; 331 log_debug_buf (LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf, 332 len); 333} 334 335struct keystate * 336crypto_clone_keystate (struct keystate *oks) 337{ 338 struct keystate *ks; 339 340 ks = malloc (sizeof *ks); 341 if (!ks) 342 return 0; 343 memcpy (ks, oks, sizeof *ks); 344 if (oks->riv == oks->iv) 345 { 346 ks->riv = ks->iv; 347 ks->liv = ks->iv2; 348 } 349 else 350 { 351 ks->riv = ks->iv2; 352 ks->liv = ks->iv; 353 } 354 return ks; 355} 356