diff options
Diffstat (limited to 'src/openvpn/crypto_openssl.c')
-rw-r--r-- | src/openvpn/crypto_openssl.c | 86 |
1 files changed, 52 insertions, 34 deletions
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index 1501bc8..348bdee 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -40,6 +40,7 @@ #include "basic.h" #include "buffer.h" #include "integer.h" +#include "crypto.h" #include "crypto_backend.h" #include <openssl/objects.h> #include <openssl/evp.h> @@ -84,24 +85,6 @@ #endif -static inline int -EVP_CipherInit_ov (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, uint8_t *key, uint8_t *iv, int enc) -{ - return EVP_CipherInit (ctx, type, key, iv, enc); -} - -static inline int -EVP_CipherUpdate_ov (EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, uint8_t *in, int inl) -{ - return EVP_CipherUpdate (ctx, out, outl, in, inl); -} - -static inline bool -cipher_ok (const char* name) -{ - return true; -} - #ifndef EVP_CIPHER_name #define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) #endif @@ -306,25 +289,30 @@ show_available_ciphers () "used as a parameter to the --cipher option. The default\n" "key size is shown as well as whether or not it can be\n" "changed with the --keysize directive. Using a CBC mode\n" - "is recommended.\n\n"); + "is recommended. In static key mode only CBC mode is allowed.\n\n"); #endif for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */ { const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid); - if (cipher && cipher_ok (OBJ_nid2sn (nid))) + if (cipher) { - const unsigned int mode = EVP_CIPHER_mode (cipher); - if (mode == EVP_CIPH_CBC_MODE -#ifdef ALLOW_NON_CBC_CIPHERS - || mode == EVP_CIPH_CFB_MODE || mode == EVP_CIPH_OFB_MODE + if (cipher_kt_mode_cbc(cipher) +#ifdef ENABLE_OFB_CFB_MODE + || cipher_kt_mode_ofb_cfb(cipher) #endif ) - printf ("%s %d bit default key (%s)\n", - OBJ_nid2sn (nid), - EVP_CIPHER_key_length (cipher) * 8, - ((EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? - "variable" : "fixed")); + { + const char *var_key_size = + (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? + "variable" : "fixed"; + const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ? + " (TLS client/server mode)" : ""; + + printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid), + EVP_CIPHER_key_length (cipher) * 8, var_key_size, + ssl_only); + } } } printf ("\n"); @@ -491,7 +479,7 @@ cipher_kt_get (const char *ciphername) cipher = EVP_get_cipherbyname (ciphername); - if ((NULL == cipher) || !cipher_ok (OBJ_nid2sn (EVP_CIPHER_nid (cipher)))) + if (NULL == cipher) msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername); if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH) @@ -536,6 +524,29 @@ cipher_kt_mode (const EVP_CIPHER *cipher_kt) return EVP_CIPHER_mode (cipher_kt); } +bool +cipher_kt_mode_cbc(const cipher_kt_t *cipher) +{ + return cipher && cipher_kt_mode(cipher) == OPENVPN_MODE_CBC +#ifdef EVP_CIPH_FLAG_AEAD_CIPHER + /* Exclude AEAD cipher modes, they require a different API */ + && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) +#endif + ; +} + +bool +cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher) +{ + return cipher && (cipher_kt_mode(cipher) == OPENVPN_MODE_OFB || + cipher_kt_mode(cipher) == OPENVPN_MODE_CFB) +#ifdef EVP_CIPH_FLAG_AEAD_CIPHER + /* Exclude AEAD cipher modes, they require a different API */ + && !(EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) +#endif + ; +} + /* * * Generic cipher context functions @@ -552,13 +563,13 @@ cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len, CLEAR (*ctx); EVP_CIPHER_CTX_init (ctx); - if (!EVP_CipherInit_ov (ctx, kt, NULL, NULL, enc)) + if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc)) msg (M_SSLERR, "EVP cipher init #1"); #ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len)) msg (M_SSLERR, "EVP set key size"); #endif - if (!EVP_CipherInit_ov (ctx, NULL, key, NULL, enc)) + if (!EVP_CipherInit (ctx, NULL, key, NULL, enc)) msg (M_SSLERR, "EVP cipher init #2"); /* make sure we used a big enough key */ @@ -589,17 +600,24 @@ cipher_ctx_mode (const EVP_CIPHER_CTX *ctx) return EVP_CIPHER_CTX_mode (ctx); } +const cipher_kt_t * +cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx) +{ + return EVP_CIPHER_CTX_cipher(ctx); +} + + int cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf) { - return EVP_CipherInit_ov (ctx, NULL, NULL, iv_buf, -1); + return EVP_CipherInit (ctx, NULL, NULL, iv_buf, -1); } int cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len, uint8_t *src, int src_len) { - return EVP_CipherUpdate_ov (ctx, dst, dst_len, src, src_len); + return EVP_CipherUpdate (ctx, dst, dst_len, src, src_len); } int |