diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2003-09-24 10:13:44 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2003-09-24 10:13:44 +0000 |
commit | 8fb6dc36aafc4e88a71f21465125a39f218c6486 (patch) | |
tree | d384f5ec5c9f65bbf5f7acd28c80339e27c381fc | |
parent | 67dad3bb6434822c3d946151d6e0a8d4e5e13b97 (diff) |
back out EVP change; causes fd leaks; ok cedric@
-rw-r--r-- | sbin/isakmpd/crypto.c | 209 | ||||
-rw-r--r-- | sbin/isakmpd/crypto.h | 75 | ||||
-rw-r--r-- | sbin/isakmpd/regress/crypto/cryptotest.c | 4 |
3 files changed, 203 insertions, 85 deletions
diff --git a/sbin/isakmpd/crypto.c b/sbin/isakmpd/crypto.c index 54ce6104919..df63774f80b 100644 --- a/sbin/isakmpd/crypto.c +++ b/sbin/isakmpd/crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.c,v 1.16 2003/08/28 14:43:35 markus Exp $ */ +/* $OpenBSD: crypto.c,v 1.17 2003/09/24 10:13:43 markus Exp $ */ /* $EOM: crypto.c,v 1.32 2000/03/07 20:08:51 niklas Exp $ */ /* @@ -39,151 +39,216 @@ #include "crypto.h" #include "log.h" -enum cryptoerr evp_init (struct keystate *, u_int8_t *, u_int16_t, - const EVP_CIPHER *); enum cryptoerr des1_init (struct keystate *, u_int8_t *, u_int16_t); enum cryptoerr des3_init (struct keystate *, u_int8_t *, u_int16_t); enum cryptoerr blf_init (struct keystate *, u_int8_t *, u_int16_t); enum cryptoerr cast_init (struct keystate *, u_int8_t *, u_int16_t); -enum cryptoerr aes_init (struct keystate *, u_int8_t *, u_int16_t); -void evp_encrypt (struct keystate *, u_int8_t *, u_int16_t); -void evp_decrypt (struct keystate *, u_int8_t *, u_int16_t); +void des1_encrypt (struct keystate *, u_int8_t *, u_int16_t); +void des1_decrypt (struct keystate *, u_int8_t *, u_int16_t); +void des3_encrypt (struct keystate *, u_int8_t *, u_int16_t); +void des3_decrypt (struct keystate *, u_int8_t *, u_int16_t); +void blf_encrypt (struct keystate *, u_int8_t *, u_int16_t); +void blf_decrypt (struct keystate *, u_int8_t *, u_int16_t); +void cast1_encrypt (struct keystate *, u_int8_t *, u_int16_t); +void cast1_decrypt (struct keystate *, u_int8_t *, u_int16_t); struct crypto_xf transforms[] = { #ifdef USE_DES { DES_CBC, "Data Encryption Standard (CBC-Mode)", 8, 8, BLOCKSIZE, 0, des1_init, - evp_encrypt, evp_decrypt + des1_encrypt, des1_decrypt }, #endif #ifdef USE_TRIPLEDES { TRIPLEDES_CBC, "Triple-DES (CBC-Mode)", 24, 24, BLOCKSIZE, 0, des3_init, - evp_encrypt, evp_decrypt + des3_encrypt, des3_decrypt }, #endif #ifdef USE_BLOWFISH { BLOWFISH_CBC, "Blowfish (CBC-Mode)", 12, 56, BLOCKSIZE, 0, blf_init, - evp_encrypt, evp_decrypt + blf_encrypt, blf_decrypt }, #endif #ifdef USE_CAST { CAST_CBC, "CAST (CBC-Mode)", 12, 16, BLOCKSIZE, 0, cast_init, - evp_encrypt, evp_decrypt - }, -#endif -#ifdef USE_AES - { - AES_CBC, "AES (CBC-Mode)", 16, 32, 2*BLOCKSIZE, 0, - aes_init, - evp_encrypt, evp_decrypt + cast1_encrypt, cast1_decrypt }, #endif }; -#ifdef USE_DES +/* Hmm, the function prototypes for des are really dumb */ +#ifdef __OpenBSD__ +#define DC (des_cblock *) +#else +#define DC (void *) +#endif + enum cryptoerr des1_init (struct keystate *ks, u_int8_t *key, u_int16_t len) { - const EVP_CIPHER *evp; + /* des_set_key returns -1 for parity problems, and -2 for weak keys */ + des_set_odd_parity (DC key); + switch (des_set_key (DC key, ks->ks_des[0])) + { + case -2: + return EWEAKKEY; + default: + return EOKAY; + } +} - evp = EVP_des_cbc(); - return evp_init (ks, key, len, evp); +void +des1_encrypt (struct keystate *ks, u_int8_t *d, u_int16_t len) +{ + des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_ENCRYPT); +} + +void +des1_decrypt (struct keystate *ks, u_int8_t *d, u_int16_t len) +{ + des_cbc_encrypt (DC d, DC d, len, ks->ks_des[0], DC ks->riv, DES_DECRYPT); } -#endif #ifdef USE_TRIPLEDES enum cryptoerr des3_init (struct keystate *ks, u_int8_t *key, u_int16_t len) { - const EVP_CIPHER *evp; + des_set_odd_parity (DC key); + des_set_odd_parity (DC (key + 8)); + des_set_odd_parity (DC (key + 16)); + + /* As of the draft Tripe-DES does not check for weak keys */ + des_set_key (DC key, ks->ks_des[0]); + des_set_key (DC (key + 8), ks->ks_des[1]); + des_set_key (DC (key + 16), ks->ks_des[2]); - evp = EVP_des_ede3_cbc(); - return evp_init (ks, key, len, evp); + return EOKAY; } -#endif + +void +des3_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) +{ + u_int8_t iv[MAXBLK]; + + memcpy (iv, ks->riv, ks->xf->blocksize); + des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1], + ks->ks_des[2], DC iv, DES_ENCRYPT); +} + +void +des3_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) +{ + u_int8_t iv[MAXBLK]; + + memcpy (iv, ks->riv, ks->xf->blocksize); + des_ede3_cbc_encrypt (DC data, DC data, len, ks->ks_des[0], ks->ks_des[1], + ks->ks_des[2], DC iv, DES_DECRYPT); +} +#undef DC +#endif /* USE_TRIPLEDES */ #ifdef USE_BLOWFISH enum cryptoerr blf_init (struct keystate *ks, u_int8_t *key, u_int16_t len) { - const EVP_CIPHER *evp; + blf_key (&ks->ks_blf, key, len); - evp = EVP_bf_cbc(); - return evp_init (ks, key, len, evp); + return EOKAY; } -#endif -#ifdef USE_CAST -enum cryptoerr -cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len) +void +blf_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) { - const EVP_CIPHER *evp; + u_int16_t i, blocksize = ks->xf->blocksize; + u_int8_t *iv = ks->liv; + u_int32_t xl, xr; - evp = EVP_cast5_cbc(); - return evp_init (ks, key, len, evp); + memcpy (iv, ks->riv, blocksize); + + for (i = 0; i < len; data += blocksize, i += blocksize) + { + XOR64 (data, iv); + xl = GET_32BIT_BIG (data); + xr = GET_32BIT_BIG (data + 4); + Blowfish_encipher (&ks->ks_blf, &xl, &xr); + SET_32BIT_BIG (data, xl); + SET_32BIT_BIG (data + 4, xr); + SET64 (iv, data); + } } -#endif -#ifdef USE_AES -enum cryptoerr -aes_init (struct keystate *ks, u_int8_t *key, u_int16_t len) +void +blf_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) { - const EVP_CIPHER *evp; + u_int16_t i, blocksize = ks->xf->blocksize; + u_int32_t xl, xr; - switch (8 * len) + data += len - blocksize; + for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) { - case 128: - evp = EVP_aes_128_cbc(); - break; - case 192: - evp = EVP_aes_192_cbc(); - break; - case 256: - evp = EVP_aes_256_cbc(); - break; - default: - return EKEYLEN; + xl = GET_32BIT_BIG (data); + xr = GET_32BIT_BIG (data + 4); + Blowfish_decipher (&ks->ks_blf, &xl, &xr); + SET_32BIT_BIG (data, xl); + SET_32BIT_BIG (data + 4, xr); + XOR64 (data, data - blocksize); + } - return evp_init (ks, key, len, evp); + xl = GET_32BIT_BIG (data); + xr = GET_32BIT_BIG (data + 4); + Blowfish_decipher (&ks->ks_blf, &xl, &xr); + SET_32BIT_BIG (data, xl); + SET_32BIT_BIG (data + 4, xr); + XOR64 (data, ks->riv); } -#endif +#endif /* USE_BLOWFISH */ +#ifdef USE_CAST enum cryptoerr -evp_init (struct keystate *ks, u_int8_t *key, u_int16_t len, const EVP_CIPHER *evp) +cast_init (struct keystate *ks, u_int8_t *key, u_int16_t len) { - EVP_CIPHER_CTX_init(&ks->ks_evpenc); - EVP_CIPHER_CTX_init(&ks->ks_evpdec); - - if (EVP_CIPHER_key_length(evp) != len - && !(EVP_CIPHER_flags(evp) & EVP_CIPH_VARIABLE_LENGTH)) - return EKEYLEN; - if (EVP_CipherInit(&ks->ks_evpenc, evp, key, NULL, 1) <= 0) - return EKEYLEN; - if (EVP_CipherInit(&ks->ks_evpdec, evp, key, NULL, 0) <= 0) - return EKEYLEN; + cast_setkey (&ks->ks_cast, key, len); return EOKAY; } void -evp_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) +cast1_encrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) { - (void) EVP_CipherInit(&ks->ks_evpenc, NULL, NULL, ks->riv, -1); - EVP_Cipher(&ks->ks_evpenc, data, data, len); + u_int16_t i, blocksize = ks->xf->blocksize; + u_int8_t *iv = ks->liv; + + memcpy (iv, ks->riv, blocksize); + + for (i = 0; i < len; data += blocksize, i += blocksize) + { + XOR64 (data, iv); + cast_encrypt (&ks->ks_cast, data, data); + SET64 (iv, data); + } } void -evp_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) +cast1_decrypt (struct keystate *ks, u_int8_t *data, u_int16_t len) { - (void) EVP_CipherInit(&ks->ks_evpdec, NULL, NULL, ks->riv, -1); - EVP_Cipher(&ks->ks_evpdec, data, data, len); + u_int16_t i, blocksize = ks->xf->blocksize; + + data += len - blocksize; + for (i = len - blocksize; i >= blocksize; data -= blocksize, i -= blocksize) + { + cast_decrypt (&ks->ks_cast, data, data); + XOR64 (data, data - blocksize); + } + cast_decrypt (&ks->ks_cast, data, data); + XOR64 (data, ks->riv); } +#endif /* USE_CAST */ struct crypto_xf * crypto_get (enum transform id) diff --git a/sbin/isakmpd/crypto.h b/sbin/isakmpd/crypto.h index 6cce31f19e7..8de039b88a8 100644 --- a/sbin/isakmpd/crypto.h +++ b/sbin/isakmpd/crypto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.h,v 1.9 2003/08/28 14:43:35 markus Exp $ */ +/* $OpenBSD: crypto.h,v 1.10 2003/09/24 10:13:43 markus Exp $ */ /* $EOM: crypto.h,v 1.12 2000/10/15 21:56:41 niklas Exp $ */ /* @@ -32,7 +32,56 @@ #ifndef _CRYPTO_H_ #define _CRYPTO_H_ -#include <openssl/evp.h> +#if defined (__APPLE__) + +#include <openssl/des.h> +#ifdef USE_BLOWFISH +#include <openssl/blowfish.h> +#endif +#ifdef USE_CAST +#include <openssl/cast.h> +#endif + +#else + +#include <des.h> +#ifdef USE_BLOWFISH +#include <blf.h> +#endif +#ifdef USE_CAST +#include <cast.h> +#endif + +#endif /* __APPLE__ */ + +#define USE_32BIT +#if defined (USE_64BIT) + +#define XOR64(x,y) *(u_int64_t *)(x) ^= *(u_int64_t *)(y); +#define SET64(x,y) *(u_int64_t *)(x) = *(u_int64_t *)(y); + +#elif defined (USE_32BIT) + +#define XOR64(x,y) *(u_int32_t *)(x) ^= *(u_int32_t *)(y); \ + *(u_int32_t *)((u_int8_t *)(x) + 4) ^= *(u_int32_t *)((u_int8_t *)(y) + 4); +#define SET64(x,y) *(u_int32_t *)(x) = *(u_int32_t *)(y); \ + *(u_int32_t *)((u_int8_t *)(x) + 4) = *(u_int32_t *)((u_int8_t *)(y) + 4); + +#else + +#define XOR8(x,y,i) (x)[i] ^= (y)[i]; +#define XOR64(x,y) XOR8(x,y,0); XOR8(x,y,1); XOR8(x,y,2); XOR8(x,y,3); \ + XOR8(x,y,4); XOR8(x,y,5); XOR8(x,y,6); XOR8(x,y,7); +#define SET8(x,y,i) (x)[i] = (y)[i]; +#define SET64(x,y) SET8(x,y,0); SET8(x,y,1); SET8(x,y,2); SET8(x,y,3); \ + SET8(x,y,4); SET8(x,y,5); SET8(x,y,6); SET8(x,y,7); + +#endif /* USE_64BIT */ + +#define SET_32BIT_BIG(x,y) (x)[3]= (y); (x)[2]= (y) >> 8; \ + (x)[1] = (y) >> 16; (x)[0]= (y) >> 24; +#define GET_32BIT_BIG(x) (u_int32_t)(x)[3] | ((u_int32_t)(x)[2] << 8) | \ + ((u_int32_t)(x)[1] << 16)| ((u_int32_t)(x)[0] << 24); /* * This is standard for all block ciphers we use at the moment. @@ -41,7 +90,7 @@ */ #define BLOCKSIZE 8 -#define MAXBLK (2*BLOCKSIZE) +#define MAXBLK BLOCKSIZE struct keystate { struct crypto_xf *xf; /* Back pointer */ @@ -51,13 +100,20 @@ struct keystate { u_int8_t iv[MAXBLK]; /* Next IV to use */ u_int8_t iv2[MAXBLK]; u_int8_t *riv, *liv; - struct { - EVP_CIPHER_CTX enc, dec; - } evp; + union { + des_key_schedule desks[3]; +#ifdef USE_BLOWFISH + blf_ctx blfks; +#endif +#ifdef USE_CAST + cast_key castks; +#endif + } keydata; }; -#define ks_evpenc evp.enc -#define ks_evpdec evp.dec +#define ks_des keydata.desks +#define ks_blf keydata.blfks +#define ks_cast keydata.castks /* * Information about the cryptotransform. @@ -74,8 +130,7 @@ enum transform { BLOWFISH_CBC=3, RC5_R16_B64_CBC=4, /* Licensed, DONT use */ TRIPLEDES_CBC=5, /* This is a SHOULD */ - CAST_CBC=6, - AES_CBC=7 + CAST_CBC=6 }; enum cryptoerr { diff --git a/sbin/isakmpd/regress/crypto/cryptotest.c b/sbin/isakmpd/regress/crypto/cryptotest.c index 6a9940f84f6..806f5610e8c 100644 --- a/sbin/isakmpd/regress/crypto/cryptotest.c +++ b/sbin/isakmpd/regress/crypto/cryptotest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cryptotest.c,v 1.9 2003/08/28 14:43:35 markus Exp $ */ +/* $OpenBSD: cryptotest.c,v 1.10 2003/09/24 10:13:43 markus Exp $ */ /* $EOM: cryptotest.c,v 1.5 1998/10/07 16:40:49 niklas Exp $ */ /* @@ -125,8 +125,6 @@ main (void) test_crypto (CAST_CBC); - test_crypto (AES_CBC); - special_test_blf (); return 1; |