crypto.c revision 1.16
1/* $OpenBSD: crypto.c,v 1.16 2003/08/28 14:43:35 markus 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 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/* 30 * This code was written under funding by Ericsson Radio Systems. 31 */ 32 33#include <sys/param.h> 34#include <stdlib.h> 35#include <string.h> 36 37#include "sysdep.h" 38 39#include "crypto.h" 40#include "log.h" 41 42enum cryptoerr evp_init (struct keystate *, u_int8_t *, u_int16_t, 43 const EVP_CIPHER *); 44enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t); 45enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t); 46enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t); 47enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t); 48enum cryptoerr aes_init (struct keystate *, u_int8_t *, u_int16_t); 49void evp_encrypt (struct keystate *, u_int8_t *, u_int16_t); 50void evp_decrypt (struct keystate *, u_int8_t *, u_int16_t); 51 52struct crypto_xf transforms[] = { 53#ifdef USE_DES 54 { 55 DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, 0, 56 des1_init, 57 evp_encrypt, evp_decrypt 58 }, 59#endif 60#ifdef USE_TRIPLEDES 61 { 62 TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, 0, 63 des3_init, 64 evp_encrypt, evp_decrypt 65 }, 66#endif 67#ifdef USE_BLOWFISH 68 { 69 BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, 0, 70 blf_init, 71 evp_encrypt, evp_decrypt 72 }, 73#endif 74#ifdef USE_CAST 75 { 76 CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, 0, 77 cast_init, 78 evp_encrypt, evp_decrypt 79 }, 80#endif 81#ifdef USE_AES 82 { 83 AES_CBC, "AES (CBC-Mode)", 16, 32, 2*BLOCKSIZE, 0, 84 aes_init, 85 evp_encrypt, evp_decrypt 86 }, 87#endif 88}; 89 90#ifdef USE_DES 91enum cryptoerr 92des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 93{ 94 const EVP_CIPHER *evp; 95 96 evp = EVP_des_cbc(); 97 return evp_init (ks, key, len, evp); 98} 99#endif 100 101#ifdef USE_TRIPLEDES 102enum cryptoerr 103des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 104{ 105 const EVP_CIPHER *evp; 106 107 evp = EVP_des_ede3_cbc(); 108 return evp_init (ks, key, len, evp); 109} 110#endif 111 112#ifdef USE_BLOWFISH 113enum cryptoerr 114blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 115{ 116 const EVP_CIPHER *evp; 117 118 evp = EVP_bf_cbc(); 119 return evp_init (ks, key, len, evp); 120} 121#endif 122 123#ifdef USE_CAST 124enum cryptoerr 125cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 126{ 127 const EVP_CIPHER *evp; 128 129 evp = EVP_cast5_cbc(); 130 return evp_init (ks, key, len, evp); 131} 132#endif 133 134#ifdef USE_AES 135enum cryptoerr 136aes_init (struct keystate *ks, u_int8_t *key, u_int16_t len) 137{ 138 const EVP_CIPHER *evp; 139 140 switch (8 * len) 141 { 142 case 128: 143 evp = EVP_aes_128_cbc(); 144 break; 145 case 192: 146 evp = EVP_aes_192_cbc(); 147 break; 148 case 256: 149 evp = EVP_aes_256_cbc(); 150 break; 151 default: 152 return EKEYLEN; 153 } 154 return evp_init (ks, key, len, evp); 155} 156#endif 157 158enum cryptoerr 159evp_init (struct keystate *ks, u_int8_t *key, u_int16_t len, const EVP_CIPHER *evp) 160{ 161 EVP_CIPHER_CTX_init(&ks->ks_evpenc); 162 EVP_CIPHER_CTX_init(&ks->ks_evpdec); 163 164 if (EVP_CIPHER_key_length(evp) != len 165 && !(EVP_CIPHER_flags(evp) & EVP_CIPH_VARIABLE_LENGTH)) 166 return EKEYLEN; 167 if (EVP_CipherInit(&ks->ks_evpenc, evp, key, NULL, 1) <= 0) 168 return EKEYLEN; 169 if (EVP_CipherInit(&ks->ks_evpdec, evp, key, NULL, 0) <= 0) 170 return EKEYLEN; 171 return EOKAY; 172} 173 174void 175evp_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 176{ 177 (void) EVP_CipherInit(&ks->ks_evpenc, NULL, NULL, ks->riv, -1); 178 EVP_Cipher(&ks->ks_evpenc, data, data, len); 179} 180 181void 182evp_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) 183{ 184 (void) EVP_CipherInit(&ks->ks_evpdec, NULL, NULL, ks->riv, -1); 185 EVP_Cipher(&ks->ks_evpdec, data, data, len); 186} 187 188struct crypto_xf * 189crypto_get (enum transform id) 190{ 191 int i; 192 193 for (i = 0; i < sizeof transforms / sizeof transforms[0]; i++) 194 if (id == transforms[i].id) 195 return &transforms[i]; 196 197 return 0; 198} 199 200struct keystate * 201crypto_init (struct crypto_xf *xf, u_int8_t *key, u_int16_t len, 202 enum cryptoerr *err) 203{ 204 struct keystate *ks; 205 206 if (len < xf->keymin || len > xf->keymax) 207 { 208 LOG_DBG ((LOG_CRYPTO, 10, "crypto_init: invalid key length %d", len)); 209 *err = EKEYLEN; 210 return 0; 211 } 212 213 ks = calloc (1, sizeof *ks); 214 if (!ks) 215 { 216 log_error ("crypto_init: calloc (1, %lu) failed", 217 (unsigned long)sizeof *ks); 218 *err = ENOCRYPTO; 219 return 0; 220 } 221 222 ks->xf = xf; 223 224 /* Setup the IV. */ 225 ks->riv = ks->iv; 226 ks->liv = ks->iv2; 227 228 LOG_DBG_BUF ((LOG_CRYPTO, 40, "crypto_init: key", key, len)); 229 230 *err = xf->init (ks, key, len); 231 if (*err != EOKAY) 232 { 233 LOG_DBG ((LOG_CRYPTO, 30, "crypto_init: weak key found for %s", 234 xf->name)); 235 free (ks); 236 return 0; 237 } 238 239 return ks; 240} 241 242void 243crypto_update_iv (struct keystate *ks) 244{ 245 u_int8_t *tmp; 246 247 tmp = ks->riv; 248 ks->riv = ks->liv; 249 ks->liv = tmp; 250 251 LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: updated IV", ks->riv, 252 ks->xf->blocksize)); 253} 254 255void 256crypto_init_iv (struct keystate *ks, u_int8_t *buf, size_t len) 257{ 258 memcpy (ks->riv, buf, len); 259 260 LOG_DBG_BUF ((LOG_CRYPTO, 50, "crypto_update_iv: initialized IV", ks->riv, 261 len)); 262} 263 264void 265crypto_encrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 266{ 267 LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_encrypt: before encryption", buf, 268 len)); 269 ks->xf->encrypt (ks, buf, len); 270 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 271 LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_encrypt: after encryption", buf, 272 len)); 273} 274 275void 276crypto_decrypt (struct keystate *ks, u_int8_t *buf, u_int16_t len) 277{ 278 LOG_DBG_BUF ((LOG_CRYPTO, 10, "crypto_decrypt: before decryption", buf, 279 len)); 280 /* 281 * XXX There is controversy about the correctness of updating the IV 282 * like this. 283 */ 284 memcpy (ks->liv, buf + len - ks->xf->blocksize, ks->xf->blocksize); 285 ks->xf->decrypt (ks, buf, len); 286 LOG_DBG_BUF ((LOG_CRYPTO, 30, "crypto_decrypt: after decryption", buf, 287 len)); 288} 289 290/* Make a copy of the keystate pointed to by OKS. */ 291struct keystate * 292crypto_clone_keystate (struct keystate *oks) 293{ 294 struct keystate *ks; 295 296 ks = malloc (sizeof *ks); 297 if (!ks) 298 { 299 log_error ("crypto_clone_keystate: malloc (%lu) failed", 300 (unsigned long)sizeof *ks); 301 return 0; 302 } 303 memcpy (ks, oks, sizeof *ks); 304 if (oks->riv == oks->iv) 305 { 306 ks->riv = ks->iv; 307 ks->liv = ks->iv2; 308 } 309 else 310 { 311 ks->riv = ks->iv2; 312 ks->liv = ks->iv; 313 } 314 return ks; 315} 316