crypto.c revision 1.5
1/* $OpenBSD: crypto.c,v 1.5 1999/04/05 21:00:27 niklas Exp $ */ 2/* $EOM: crypto.c,v 1.24 1999/04/05 07:57:03 niklas Exp $ */ 3 4/* 5 * Copyright (c) 1998 Niels Provos. All rights reserved. 6 * Copyright (c) 1999 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, NULL, 63 des1_init, 64 des1_encrypt, des1_decrypt 65 }, 66 { 67 TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, NULL, 68 des3_init, 69 des3_encrypt, des3_decrypt 70 }, 71 { 72 BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, NULL, 73 blf_init, 74 blf_encrypt, blf_decrypt 75 }, 76 { 77 CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, NULL, 78 cast_init, 79 cast1_encrypt, cast1_decrypt 80 }, 81}; 82 83/* Hmm, the function prototypes for des are really dumb */ 84#define DC (des_cblock *) 85 86enum cryptoerr 87des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 88{ 89 /* des_set_key returns -1 for parity problems, and -2 for weak keys */ 90 des_set_odd_parity (DC key); 91 switch (des_set_key (DC key, ks->ks_des[0])) 92 { 93 case -2: 94 return EWEAKKEY; 95 default: 96 return EOKAY; 97 } 98} 99 100void 101des1_encrypt (struct keystate *ks, u_int8_t *d, u_int16_t len) 102{ 103 des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT); 104} 105 106void 107des1_decrypt (struct keystate *ks, u_int8_t *d, u_int16_t len) 108{ 109 des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT); 110} 111 112enum cryptoerr 113des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 114{ 115 des_set_odd_parity (DC key); 116 des_set_odd_parity (DC key + 1); 117 des_set_odd_parity (DC key + 2); 118 119 /* As of the draft Tripe-DES does not check for weak keys */ 120 des_set_key (DC key, ks->ks_des[0]); 121 des_set_key (DC key + 1, ks->ks_des[1]); 122 des_set_key (DC key + 2, ks->ks_des[2]); 123 124 return EOKAY; 125} 126 127void 128des3_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 129{ 130 u_int8_t iv[MAXBLK]; 131 132 memcpy (iv, ks->riv, ks->xf->blocksize); 133 des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1], 134 ks->ks_des[2], DC iv, DES_ENCRYPT); 135} 136 137void 138des3_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 139{ 140 u_int8_t iv[MAXBLK]; 141 142 memcpy (iv, ks->riv, ks->xf->blocksize); 143 des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1], 144 ks->ks_des[2], DC iv, DES_DECRYPT); 145} 146#undef DC 147 148enum cryptoerr 149blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 150{ 151 blf_key (&ks->ks_blf, key, len); 152 153 return EOKAY; 154} 155 156void 157blf_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 158{ 159 u_int16_t i, blocksize = ks->xf->blocksize; 160 u_int8_t *iv = ks->liv; 161 u_int32_t xl, xr; 162 163 memcpy (iv, ks->riv, blocksize); 164 165 for (i = 0; i < len; data += blocksize, i += blocksize) 166 { 167 XOR64 (data, iv); 168 xl = GET_32BIT_BIG (data); 169 xr = GET_32BIT_BIG (data + 4); 170 Blowfish_encipher (&ks->ks_blf, &xl, &xr); 171 SET_32BIT_BIG (data, xl); 172 SET_32BIT_BIG (data + 4, xr); 173 SET64 (iv, data); 174 } 175} 176 177void 178blf_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 179{ 180 u_int16_t i, blocksize = ks->xf->blocksize; 181 u_int32_t xl, xr; 182 183 data += len - blocksize; 184 for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) 185 { 186 xl = GET_32BIT_BIG (data); 187 xr = GET_32BIT_BIG (data + 4); 188 Blowfish_decipher (&ks->ks_blf, &xl, &xr); 189 SET_32BIT_BIG (data, xl); 190 SET_32BIT_BIG (data + 4, xr); 191 XOR64 (data, data - blocksize); 192 193 } 194 xl = GET_32BIT_BIG (data); 195 xr = GET_32BIT_BIG (data + 4); 196 Blowfish_decipher (&ks->ks_blf, &xl, &xr); 197 SET_32BIT_BIG (data, xl); 198 SET_32BIT_BIG (data + 4, xr); 199 XOR64 (data, ks->riv); 200} 201 202enum cryptoerr 203cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 204{ 205 cast_setkey (&ks->ks_cast, key, len); 206 return EOKAY; 207} 208 209void 210cast1_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 211{ 212 u_int16_t i, blocksize = ks->xf->blocksize; 213 u_int8_t *iv = ks->liv; 214 215 memcpy (iv, ks->riv, blocksize); 216 217 for (i = 0; i < len; data += blocksize, i += blocksize) 218 { 219 XOR64 (data, iv); 220 cast_encrypt (&ks->ks_cast, data, data); 221 SET64 (iv, data); 222 } 223} 224 225void 226cast1_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 227{ 228 u_int16_t i, blocksize = ks->xf->blocksize; 229 230 data += len - blocksize; 231 for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) 232 { 233 cast_decrypt (&ks->ks_cast, data, data); 234 XOR64 (data, data - blocksize); 235 } 236 cast_decrypt (&ks->ks_cast, data, data); 237 XOR64 (data, ks->riv); 238} 239 240struct crypto_xf * 241crypto_get (enum transform id) 242{ 243 int i; 244 245 for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++) 246 if (id == transforms[i].id) 247 return &transforms[i]; 248 249 return 0; 250} 251 252struct keystate * 253crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len, 254 enum cryptoerr *err) 255{ 256 struct keystate *ks; 257 258 if (len < xf->keymin || len > xf->keymax) 259 { 260 log_debug (LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len); 261 *err = EKEYLEN; 262 return 0; 263 } 264 265 ks = calloc (1, sizeof *ks); 266 if (!ks) 267 { 268 log_error ("crypto_init: calloc (1, %d) failed", sizeof *ks); 269 *err = ENOCRYPTO; 270 return 0; 271 } 272 273 ks->xf = xf; 274 275 /* Setup the IV. */ 276 ks->riv = ks->iv; 277 ks->liv = ks->iv2; 278 279 log_debug_buf (LOG_CRYPTO, 40, "crypto_init: key", key, len); 280 281 *err = xf->init (ks, key, len); 282 if (*err != EOKAY) 283 { 284 log_debug (LOG_CRYPTO, 30, "crypto_init: weak key found for %s", 285 xf->name); 286 free (ks); 287 return 0; 288 } 289 290 return ks; 291} 292 293void 294crypto_update_iv (struct keystate *ks) 295{ 296 u_int8_t *tmp; 297 298 tmp = ks->riv; 299 ks->riv = ks->liv; 300 ks->liv = tmp; 301 302 log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv, 303 ks->xf->blocksize); 304} 305 306void 307crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len) 308{ 309 memcpy (ks->riv, buf, len); 310 311 log_debug_buf (LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv, 312 len); 313} 314 315void 316crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 317{ 318 log_debug_buf (LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf, 319 len); 320 ks->xf->encrypt (ks, buf, len); 321 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 322 log_debug_buf (LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf, 323 len); 324} 325 326void 327crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 328{ 329 log_debug_buf (LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf, 330 len); 331 /* 332 * XXX There is controversy about the correctness of updating the IV 333 * like this. 334 */ 335 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 336 ks->xf->decrypt (ks, buf, len);; 337 log_debug_buf (LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf, 338 len); 339} 340 341/* Make a copy of the keystate pointed to by OKS. */ 342struct keystate * 343crypto_clone_keystate (struct keystate *oks) 344{ 345 struct keystate *ks; 346 347 ks = malloc (sizeof *ks); 348 if (!ks) 349 { 350 log_error ("crypto_clone_keystate: malloc (%d) failed", sizeof *ks); 351 return 0; 352 } 353 memcpy (ks, oks, sizeof *ks); 354 if (oks->riv == oks->iv) 355 { 356 ks->riv = ks->iv; 357 ks->liv = ks->iv2; 358 } 359 else 360 { 361 ks->riv = ks->iv2; 362 ks->liv = ks->iv; 363 } 364 return ks; 365} 366