diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c
index c00486cc232281784eda0031ec7c9a367233023f..11f6270919349cc8ab8717fd579a08b24e9727c3 100644
--- a/examples/nettle-benchmark.c
+++ b/examples/nettle-benchmark.c
@@ -723,6 +723,10 @@ main(int argc, char **argv)
   int c;
   const char *alg;
 
+#if WITH_OPENSSL
+  nettle_openssl_init();
+#endif
+
   const struct nettle_hash *hashes[] =
     {
       &nettle_md2, &nettle_md4, &nettle_md5,
diff --git a/examples/nettle-openssl.c b/examples/nettle-openssl.c
index 86c5321c6dbb37db3d4df158b5f9361d92948c7d..3d7d4fa395bf94511348179976d5a2c762ffe7d2 100644
--- a/examples/nettle-openssl.c
+++ b/examples/nettle-openssl.c
@@ -45,11 +45,9 @@
 
 #include <assert.h>
 
-#include <openssl/aes.h>
-#include <openssl/blowfish.h>
-#include <openssl/des.h>
-#include <openssl/cast.h>
-#include <openssl/rc4.h>
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
 
 #include <openssl/md5.h>
 #include <openssl/sha.h>
@@ -64,273 +62,202 @@ static nettle_set_key_func openssl_aes192_set_encrypt_key;
 static nettle_set_key_func openssl_aes192_set_decrypt_key;
 static nettle_set_key_func openssl_aes256_set_encrypt_key;
 static nettle_set_key_func openssl_aes256_set_decrypt_key;
+
+struct AESCipher {
+  EVP_CIPHER_CTX *ctx;
+};
+
+void
+nettle_openssl_init(void)
+{
+  ERR_load_crypto_strings();
+  OpenSSL_add_all_algorithms();
+#if OPENSSL_VERSION_NUMBER >= 0x1010000
+  CONF_modules_load_file(NULL, NULL, 0);
+#else
+  OPENSSL_config(NULL);
+#endif
+}
+
+static void
+openssl_evp_set_encrypt_key(void *ctx, const uint8_t *key, const EVP_CIPHER *cipher)
+{
+  EVP_CIPHER_CTX **ctxptr = ctx;
+  *ctxptr = EVP_CIPHER_CTX_new();
+  assert(EVP_EncryptInit_ex(*ctxptr, cipher, NULL, key, NULL) == 1);
+  EVP_CIPHER_CTX_set_padding(*ctxptr, 0);
+}
+static void
+openssl_evp_set_decrypt_key(void *ctx, const uint8_t *key, const EVP_CIPHER *cipher)
+{
+  EVP_CIPHER_CTX **ctxptr = ctx;
+  *ctxptr = EVP_CIPHER_CTX_new();
+  assert(EVP_DecryptInit_ex(*ctxptr, cipher, NULL, key, NULL) == 1);
+  EVP_CIPHER_CTX_set_padding(*ctxptr, 0);
+}
 static void
 openssl_aes128_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_encrypt_key(key, 128, ctx);
+  openssl_evp_set_encrypt_key(ctx, key, EVP_aes_128_ecb());
 }
 static void
 openssl_aes128_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_decrypt_key(key, 128, ctx);
+  openssl_evp_set_decrypt_key(ctx, key, EVP_aes_128_ecb());
 }
 
 static void
 openssl_aes192_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_encrypt_key(key, 192, ctx);
+  openssl_evp_set_encrypt_key(ctx, key, EVP_aes_192_ecb());
 }
 static void
 openssl_aes192_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_decrypt_key(key, 192, ctx);
+  openssl_evp_set_decrypt_key(ctx, key, EVP_aes_192_ecb());
 }
 
 static void
 openssl_aes256_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_encrypt_key(key, 256, ctx);
+  openssl_evp_set_encrypt_key(ctx, key, EVP_aes_256_ecb());
 }
 static void
 openssl_aes256_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  AES_set_decrypt_key(key, 256, ctx);
+  openssl_evp_set_decrypt_key(ctx, key, EVP_aes_256_ecb());
 }
 
-static nettle_cipher_func openssl_aes_encrypt;
 static void
-openssl_aes_encrypt(const void *ctx, size_t length,
+openssl_evp_encrypt(const void *ctx, size_t length,
 		    uint8_t *dst, const uint8_t *src)
 {
-  assert (!(length % AES_BLOCK_SIZE));
-  while (length)
-    {
-      AES_ecb_encrypt(src, dst, ctx, AES_ENCRYPT);
-      length -= AES_BLOCK_SIZE;
-      dst += AES_BLOCK_SIZE;
-      src += AES_BLOCK_SIZE;
-    }
+  EVP_CIPHER_CTX * const*ctxptr = ctx;
+  int len;
+  assert(EVP_EncryptUpdate(*ctxptr, dst, &len, src, length) == 1);
 }
 
-static nettle_cipher_func openssl_aes_decrypt;
 static void
-openssl_aes_decrypt(const void *ctx, size_t length,
+openssl_evp_decrypt(const void *ctx, size_t length,
 		    uint8_t *dst, const uint8_t *src)
 {
-  assert (!(length % AES_BLOCK_SIZE));
-  while (length)
-    {
-      AES_ecb_encrypt(src, dst, ctx, AES_DECRYPT);
-      length -= AES_BLOCK_SIZE;
-      dst += AES_BLOCK_SIZE;
-      src += AES_BLOCK_SIZE;
-    }
+  EVP_CIPHER_CTX * const*ctxptr = ctx;
+  int len;
+  assert(EVP_DecryptUpdate(*ctxptr, dst, &len, src, length) == 1);
 }
 
 const struct nettle_cipher
 nettle_openssl_aes128 = {
-  "openssl aes128", sizeof(AES_KEY),
+  "openssl aes128", sizeof(EVP_CIPHER_CTX **),
   16, 16,
   openssl_aes128_set_encrypt_key, openssl_aes128_set_decrypt_key,
-  openssl_aes_encrypt, openssl_aes_decrypt
+  openssl_evp_encrypt, openssl_evp_decrypt
 };
 
 const struct nettle_cipher
 nettle_openssl_aes192 = {
-  "openssl aes192", sizeof(AES_KEY),
-  /* Claim no block size, so that the benchmark doesn't try CBC mode
-   * (as openssl cipher + nettle cbc is somewhat pointless to
-   * benchmark). */
+  "openssl aes192", sizeof(EVP_CIPHER_CTX **),
   16, 24,
   openssl_aes192_set_encrypt_key, openssl_aes192_set_decrypt_key,
-  openssl_aes_encrypt, openssl_aes_decrypt
+  openssl_evp_encrypt, openssl_evp_decrypt
 };
 
 const struct nettle_cipher
 nettle_openssl_aes256 = {
-  "openssl aes256", sizeof(AES_KEY),
-  /* Claim no block size, so that the benchmark doesn't try CBC mode
-   * (as openssl cipher + nettle cbc is somewhat pointless to
-   * benchmark). */
+  "openssl aes256", sizeof(EVP_CIPHER_CTX **),
   16, 32,
   openssl_aes256_set_encrypt_key, openssl_aes256_set_decrypt_key,
-  openssl_aes_encrypt, openssl_aes_decrypt
+  openssl_evp_encrypt, openssl_evp_decrypt
 };
 
 /* Arcfour */
-static nettle_set_key_func openssl_arcfour128_set_key;
 static void
-openssl_arcfour128_set_key(void *ctx, const uint8_t *key)
+openssl_arcfour128_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  RC4_set_key(ctx, 16, key);
+  openssl_evp_set_encrypt_key(ctx, key, EVP_rc4());
 }
 
-static nettle_crypt_func openssl_arcfour_crypt;
 static void
-openssl_arcfour_crypt(void *ctx, size_t length,
-		      uint8_t *dst, const uint8_t *src)
+openssl_arcfour128_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  RC4(ctx, length, src, dst);
+  openssl_evp_set_decrypt_key(ctx, key, EVP_rc4());
 }
 
 const struct nettle_aead
 nettle_openssl_arcfour128 = {
-  "openssl arcfour128", sizeof(RC4_KEY),
+  "openssl arcfour128", sizeof(EVP_CIPHER_CTX **),
   1, 16, 0, 0,
-  openssl_arcfour128_set_key,
-  openssl_arcfour128_set_key,
+  openssl_arcfour128_set_encrypt_key,
+  openssl_arcfour128_set_decrypt_key,
   NULL, NULL,
-  openssl_arcfour_crypt,
-  openssl_arcfour_crypt,
+  (nettle_crypt_func *)openssl_evp_encrypt,
+  (nettle_crypt_func *)openssl_evp_decrypt,
   NULL,  
 };
 
 /* Blowfish */
-static nettle_set_key_func openssl_bf128_set_key;
 static void
-openssl_bf128_set_key(void *ctx, const uint8_t *key)
+openssl_bf128_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  BF_set_key(ctx, 16, key);
+  openssl_evp_set_encrypt_key(ctx, key, EVP_bf_ecb());
 }
 
-static nettle_cipher_func openssl_bf_encrypt;
 static void
-openssl_bf_encrypt(const void *ctx, size_t length,
-		   uint8_t *dst, const uint8_t *src)
+openssl_bf128_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  assert (!(length % BF_BLOCK));
-  while (length)
-    {
-      BF_ecb_encrypt(src, dst, ctx, BF_ENCRYPT);
-      length -= BF_BLOCK;
-      dst += BF_BLOCK;
-      src += BF_BLOCK;
-    }
-}
-
-static nettle_cipher_func openssl_bf_decrypt;
-static void
-openssl_bf_decrypt(const void *ctx, size_t length,
-		   uint8_t *dst, const uint8_t *src)
-{
-  assert (!(length % BF_BLOCK));
-  while (length)
-    {
-      BF_ecb_encrypt(src, dst, ctx, BF_DECRYPT);
-      length -= BF_BLOCK;
-      dst += BF_BLOCK;
-      src += BF_BLOCK;
-    }
+  openssl_evp_set_decrypt_key(ctx, key, EVP_bf_ecb());
 }
 
 const struct nettle_cipher
 nettle_openssl_blowfish128 = {
-  "openssl bf128", sizeof(BF_KEY),
+  "openssl bf128", sizeof(EVP_CIPHER_CTX **),
   8, 16,
-  openssl_bf128_set_key, openssl_bf128_set_key,
-  openssl_bf_encrypt, openssl_bf_decrypt
+  openssl_bf128_set_encrypt_key, openssl_bf128_set_decrypt_key,
+  openssl_evp_encrypt, openssl_evp_decrypt
 };
 
 
 /* DES */
-static nettle_set_key_func openssl_des_set_key;
-static void
-openssl_des_set_key(void *ctx, const uint8_t *key)
-{
-  /* Not sure what "unchecked" means. We want to ignore parity bits,
-     but it would still make sense to check for weak keys. */
-  /* Explicit cast used as I don't want to care about openssl's broken
-     array typedefs DES_cblock and const_DES_cblock. */
-  DES_set_key_unchecked( (void *) key, ctx);
-}
-
-#define DES_BLOCK_SIZE 8
-
-static nettle_cipher_func openssl_des_encrypt;
 static void
-openssl_des_encrypt(const void *ctx, size_t length,
-		    uint8_t *dst, const uint8_t *src)
+openssl_des_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  assert (!(length % DES_BLOCK_SIZE));
-  while (length)
-    {
-      DES_ecb_encrypt((void *) src, (void *) dst,
-		      (void *) ctx, DES_ENCRYPT);
-      length -= DES_BLOCK_SIZE;
-      dst += DES_BLOCK_SIZE;
-      src += DES_BLOCK_SIZE;
-    }
+  openssl_evp_set_encrypt_key(ctx, key, EVP_des_ecb());
 }
 
-static nettle_cipher_func openssl_des_decrypt;
 static void
-openssl_des_decrypt(const void *ctx, size_t length,
-		    uint8_t *dst, const uint8_t *src)
+openssl_des_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  assert (!(length % DES_BLOCK_SIZE));
-  while (length)
-    {
-      DES_ecb_encrypt((void *) src, (void *) dst,
-		      (void *) ctx, DES_DECRYPT);
-      length -= DES_BLOCK_SIZE;
-      dst += DES_BLOCK_SIZE;
-      src += DES_BLOCK_SIZE;
-    }
+  openssl_evp_set_decrypt_key(ctx, key, EVP_des_ecb());
 }
 
 const struct nettle_cipher
 nettle_openssl_des = {
-  "openssl des", sizeof(DES_key_schedule),
+  "openssl des", sizeof(EVP_CIPHER_CTX **),
   8, 8,
-  openssl_des_set_key, openssl_des_set_key,
-  openssl_des_encrypt, openssl_des_decrypt
+  openssl_des_set_encrypt_key, openssl_des_set_decrypt_key,
+  openssl_evp_encrypt, openssl_evp_decrypt
 };
 
 
 /* Cast128 */
-static nettle_set_key_func openssl_cast128_set_key;
 static void
-openssl_cast128_set_key(void *ctx, const uint8_t *key)
+openssl_cast128_set_encrypt_key(void *ctx, const uint8_t *key)
 {
-  CAST_set_key(ctx, 16, key);
+  openssl_evp_set_encrypt_key(ctx, key, EVP_cast5_ecb());
 }
 
-static nettle_cipher_func openssl_cast_encrypt;
 static void
-openssl_cast_encrypt(const void *ctx, size_t length,
-		     uint8_t *dst, const uint8_t *src)
+openssl_cast128_set_decrypt_key(void *ctx, const uint8_t *key)
 {
-  assert (!(length % CAST_BLOCK));
-  while (length)
-    {
-      CAST_ecb_encrypt(src, dst, ctx, CAST_ENCRYPT);
-      length -= CAST_BLOCK;
-      dst += CAST_BLOCK;
-      src += CAST_BLOCK;
-    }
-}
-
-static nettle_cipher_func openssl_cast_decrypt;
-static void
-openssl_cast_decrypt(const void *ctx, size_t length,
-		     uint8_t *dst, const uint8_t *src)
-{
-  assert (!(length % CAST_BLOCK));
-  while (length)
-    {
-      CAST_ecb_encrypt(src, dst, ctx, CAST_DECRYPT);
-      length -= CAST_BLOCK;
-      dst += CAST_BLOCK;
-      src += CAST_BLOCK;
-    }
+  openssl_evp_set_decrypt_key(ctx, key, EVP_cast5_ecb());
 }
 
 const struct nettle_cipher
 nettle_openssl_cast128 = {
-  "openssl cast128", sizeof(CAST_KEY),
-  8, CAST_KEY_LENGTH,
-  openssl_cast128_set_key, openssl_cast128_set_key,
-  openssl_cast_encrypt, openssl_cast_decrypt
+  "openssl cast128", sizeof(EVP_CIPHER_CTX **),
+  8, 16,
+  openssl_cast128_set_encrypt_key, openssl_cast128_set_decrypt_key,
+  openssl_evp_encrypt, openssl_evp_decrypt
 };
 
 /* Hash functions */
diff --git a/nettle-internal.h b/nettle-internal.h
index 9c4c699df0d7b1eb72df58ba64ddedffac2cb416..0b0d25c90efa16d1ebfb6fdab2db22a71075a232 100644
--- a/nettle-internal.h
+++ b/nettle-internal.h
@@ -79,6 +79,7 @@ extern const struct nettle_aead nettle_salsa20r12;
 
 /* Glue to openssl, for comparative benchmarking. Code in
  * examples/nettle-openssl.c. */
+extern void nettle_openssl_init(void);
 extern const struct nettle_cipher nettle_openssl_aes128;
 extern const struct nettle_cipher nettle_openssl_aes192;
 extern const struct nettle_cipher nettle_openssl_aes256;