Repository: randombit/botan
Pull request #2902 (2022-02-06 13:35:56)

Remove the OpenSSL provider
It seems OpenSSL 3.0 breaks things (GH #2899 #2900)


Patch:
diff --git a/doc/dev_ref/contributing.rst b/doc/dev_ref/contributing.rst
index f6effb3f3..118e53377 100644
--- a/doc/dev_ref/contributing.rst
+++ b/doc/dev_ref/contributing.rst
@@ -45,7 +45,7 @@ Library Layout
 * ``filters`` is a filter/pipe API for data transforms
 * ``compression`` has the compression wrappers (zlib, bzip2, lzma)
 * ``ffi`` is the C99 API
-* ``prov`` contains bindings to external libraries like OpenSSL and PKCS #11
+* ``prov`` contains bindings to external libraries like PKCS #11
 * ``misc`` contains odds and ends: format preserving encryption, SRP, threshold
   secret sharing, all or nothing transform, and others
 
@@ -141,7 +141,7 @@ On Linux if you have the ``lcov`` and ``gcov`` tools installed, then running
 ``./src/scripts/ci_build.py coverage`` will produce a coverage enabled build,
 run the tests, test the fuzzers against a corpus, and produce an HTML report
 of total coverage. This coverage build requires the development headers for
-zlib, bzip2, liblzma, OpenSSL, TrouSerS (libtspi), and Sqlite3.
+zlib, bzip2, liblzma, TrouSerS (libtspi), and Sqlite3.
 
 Copyright Notice
 ----------------------------------------
@@ -256,12 +256,12 @@ additional lines of code in the library. That is, if the library really does
 need this functionality, and it can be done in the library for less than that,
 then it makes sense to just write the code. Yup.
 
-Currently the (optional) external dependencies of the library are OpenSSL (for
-access to fast and side channel hardened RSA, ECDSA, AES), some compression
-libraries (zlib, bzip2, lzma), sqlite3 database, Trousers (TPM integration),
-plus various operating system utilities like basic filesystem operations. These
-provide major pieces of functionality which seem worth the trouble of
-maintaining an integration with.
+Currently the (optional) external dependencies of the library are some
+common compression libraries (zlib, bzip2, lzma), sqlite3 database,
+Trousers (TPM integration), plus various operating system utilities
+like basic filesystem operations. These provide major pieces of
+functionality which seem worth the trouble of maintaining an
+integration with.
 
 At this point the most plausible examples of an appropriate new external
 dependency are all deeper integrations with system level cryptographic systems
diff --git a/doc/dev_ref/todo.rst b/doc/dev_ref/todo.rst
index ac717c623..1b800405c 100644
--- a/doc/dev_ref/todo.rst
+++ b/doc/dev_ref/todo.rst
@@ -67,8 +67,6 @@ External Providers, Hardware Support
 
 * Add support ARMv8.4-A SHA-512, SHA-3, SM3 and RNG
 * Aarch64 inline asm for BigInt
-* Extend OpenSSL provider (DH, HMAC, CMAC, GCM)
-* Support using BoringSSL instead of OpenSSL or LibreSSL
 * /dev/crypto provider (ciphers, hashes)
 * Windows CryptoNG provider (ciphers, hashes)
 * Extend Apple CommonCrypto provider (HMAC, CMAC, RSA, ECDSA, ECDH)
diff --git a/doc/packaging.rst b/doc/packaging.rst
index f77000b89..5413549b4 100644
--- a/doc/packaging.rst
+++ b/doc/packaging.rst
@@ -12,10 +12,14 @@ In most environments, zlib, bzip2, and sqlite are already installed, so there is
 no reason to not include support for them in Botan as well. Build with options
 ``--with-zlib --with-bzip2 --with-sqlite3`` to enable these features.
 
-Even though OpenSSL is also typically already installed, using
-``--with-openssl`` by default is *not recommended*. OpenSSL is sometimes faster
-and sometimes slower than Botan, and the relative speeds vary depending on the
-algorithm and CPU.
+Enable Linux Features
+-----------------------
+
+If you are building for a Linux distribution and know that the running
+kernel and glibc will be new enough, you can enable some features
+which are disabled by default::
+
+  ``--with-os-features=getrandom,getentropy``
 
 Set Path to the System CA bundle
 ---------------------------------
diff --git a/doc/side_channels.rst b/doc/side_channels.rst
index 1f94874f0..40d570ad1 100644
--- a/doc/side_channels.rst
+++ b/doc/side_channels.rst
@@ -67,9 +67,6 @@ operation.
 
 See blinding.cpp and rsa.cpp.
 
-If the OpenSSL provider is enabled, then no explicit blinding is done; we assume
-OpenSSL handles this. See openssl_rsa.cpp.
-
 Decryption of PKCS #1 v1.5 Ciphertexts
 ----------------------------------------
 
diff --git a/src/lib/block/block_cipher.cpp b/src/lib/block/block_cipher.cpp
index fb0564646..bb36d25e2 100644
--- a/src/lib/block/block_cipher.cpp
+++ b/src/lib/block/block_cipher.cpp
@@ -94,10 +94,6 @@
   #include <botan/xtea.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 #if defined(BOTAN_HAS_COMMONCRYPTO)
   #include <botan/internal/commoncrypto.h>
 #endif
@@ -119,17 +115,6 @@ BlockCipher::create(const std::string& algo,
       }
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider.empty() || provider == "openssl")
-      {
-      if(auto bc = make_openssl_block_cipher(algo))
-         return bc;
-
-      if(!provider.empty())
-         return nullptr;
-      }
-#endif
-
    // TODO: CryptoAPI
    // TODO: /dev/crypto
 
diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp
index 63218006c..67c1f8899 100644
--- a/src/lib/hash/hash.cpp
+++ b/src/lib/hash/hash.cpp
@@ -93,10 +93,6 @@
   #include <botan/blake2b.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 #if defined(BOTAN_HAS_COMMONCRYPTO)
   #include <botan/internal/commoncrypto.h>
 #endif
@@ -118,17 +114,6 @@ std::unique_ptr<HashFunction> HashFunction::create(const std::string& algo_spec,
       }
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider.empty() || provider == "openssl")
-      {
-      if(auto hash = make_openssl_hash(algo_spec))
-         return hash;
-
-      if(!provider.empty())
-         return nullptr;
-      }
-#endif
-
    if(provider.empty() == false && provider != "base")
       return nullptr; // unknown provider
 
diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp
index 4c3fc5230..1b411ddad 100644
--- a/src/lib/mac/mac.cpp
+++ b/src/lib/mac/mac.cpp
@@ -62,7 +62,6 @@ MessageAuthenticationCode::create(const std::string& algo_spec,
 #if defined(BOTAN_HAS_HMAC)
    if(req.algo_name() == "HMAC" && req.arg_count() == 1)
       {
-      // TODO OpenSSL
       if(provider.empty() || provider == "base")
          {
          if(auto h = HashFunction::create(req.arg(0)))
@@ -93,7 +92,6 @@ MessageAuthenticationCode::create(const std::string& algo_spec,
 #if defined(BOTAN_HAS_CMAC)
    if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1)
       {
-      // TODO: OpenSSL CMAC
       if(provider.empty() || provider == "base")
          {
          if(auto bc = BlockCipher::create(req.arg(0)))
diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp
index 710f16ba2..236043286 100644
--- a/src/lib/modes/cipher_mode.cpp
+++ b/src/lib/modes/cipher_mode.cpp
@@ -31,10 +31,6 @@
   #include <botan/xts.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 #if defined(BOTAN_HAS_COMMONCRYPTO)
   #include <botan/internal/commoncrypto.h>
 #endif
@@ -68,19 +64,6 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo,
       }
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider.empty() || provider == "openssl")
-      {
-      std::unique_ptr<Cipher_Mode> openssl_cipher(make_openssl_cipher_mode(algo, direction));
-
-      if(openssl_cipher)
-         return openssl_cipher;
-
-      if(!provider.empty())
-         return std::unique_ptr<Cipher_Mode>();
-      }
-#endif
-
 #if defined(BOTAN_HAS_STREAM_CIPHER)
    if(auto sc = StreamCipher::create(algo))
       {
diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp
index 73b482725..e127de3af 100644
--- a/src/lib/pbkdf/pbkdf.cpp
+++ b/src/lib/pbkdf/pbkdf.cpp
@@ -31,8 +31,6 @@ std::unique_ptr<PBKDF> PBKDF::create(const std::string& algo_spec,
 #if defined(BOTAN_HAS_PBKDF2)
    if(req.algo_name() == "PBKDF2")
       {
-      // TODO OpenSSL
-
       if(provider.empty() || provider == "base")
          {
          if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
diff --git a/src/lib/pbkdf/pwdhash.cpp b/src/lib/pbkdf/pwdhash.cpp
index 718024a22..2e22cccd6 100644
--- a/src/lib/pbkdf/pwdhash.cpp
+++ b/src/lib/pbkdf/pwdhash.cpp
@@ -38,8 +38,6 @@ std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(const std::string
 #if defined(BOTAN_HAS_PBKDF2)
    if(req.algo_name() == "PBKDF2")
       {
-      // TODO OpenSSL
-
       if(provider.empty() || provider == "base")
          {
          if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
diff --git a/src/lib/prov/openssl/info.txt b/src/lib/prov/openssl/info.txt
deleted file mode 100644
index 32e71a848..000000000
--- a/src/lib/prov/openssl/info.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-<defines>
-OPENSSL -> 20151219
-</defines>
-
-load_on vendor
-
-<header:internal>
-openssl.h
-</header:internal>
-
-<libs>
-all!windows -> crypto
-windows -> libeay32
-</libs>
-
-<requires>
-block
-stream
-modes
-pubkey
-</requires>
diff --git a/src/lib/prov/openssl/openssl.h b/src/lib/prov/openssl/openssl.h
deleted file mode 100644
index a68dda5af..000000000
--- a/src/lib/prov/openssl/openssl.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-* Utils for calling OpenSSL
-* (C) 2015,2016 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_INTERNAL_OPENSSL_H_
-#define BOTAN_INTERNAL_OPENSSL_H_
-
-#include <botan/pk_ops_fwd.h>
-#include <botan/secmem.h>
-#include <botan/exceptn.h>
-#include <memory>
-#include <string>
-
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
-#if defined(BOTAN_HAS_RC4)
-#include <openssl/rc4.h>
-#endif
-
-namespace Botan {
-
-class BlockCipher;
-class Cipher_Mode;
-class StreamCipher;
-class HashFunction;
-class RandomNumberGenerator;
-enum Cipher_Dir : int;
-
-class BOTAN_PUBLIC_API(2,0) OpenSSL_Error final : public Exception
-   {
-   public:
-      OpenSSL_Error(const std::string& what, int err) :
-         Exception(what + " failed: " + ERR_error_string(err, nullptr)),
-         m_err(err) {}
-
-      ErrorType error_type() const noexcept override { return ErrorType::OpenSSLError; }
-
-      int error_code() const noexcept override { return m_err; }
-
-   private:
-      int m_err;
-   };
-
-/* Block Ciphers */
-
-std::unique_ptr<BlockCipher>
-make_openssl_block_cipher(const std::string& name);
-
-/* Cipher Modes */
-
-Cipher_Mode*
-make_openssl_cipher_mode(const std::string& name, Cipher_Dir direction);
-
-/* Hash */
-
-std::unique_ptr<HashFunction>
-make_openssl_hash(const std::string& name);
-
-/* RSA */
-
-#if defined(BOTAN_HAS_RSA)
-
-class RSA_PublicKey;
-class RSA_PrivateKey;
-
-std::unique_ptr<PK_Ops::Encryption>
-make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params);
-std::unique_ptr<PK_Ops::Decryption>
-make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params);
-
-std::unique_ptr<PK_Ops::Verification>
-make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params);
-std::unique_ptr<PK_Ops::Signature>
-make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params);
-std::unique_ptr<RSA_PrivateKey>
-make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits);
-
-#endif
-
-/* ECDSA */
-
-#if defined(BOTAN_HAS_ECDSA)
-
-class ECDSA_PublicKey;
-class ECDSA_PrivateKey;
-
-std::unique_ptr<PK_Ops::Verification>
-make_openssl_ecdsa_ver_op(const ECDSA_PublicKey& key, const std::string& params);
-std::unique_ptr<PK_Ops::Signature>
-make_openssl_ecdsa_sig_op(const ECDSA_PrivateKey& key, const std::string& params);
-
-#endif
-
-/* ECDH */
-
-#if defined(BOTAN_HAS_ECDH)
-
-class ECDH_PrivateKey;
-
-std::unique_ptr<PK_Ops::Key_Agreement>
-make_openssl_ecdh_ka_op(const ECDH_PrivateKey& key, const std::string& params);
-
-#endif
-
-#if defined(BOTAN_HAS_RC4)
-
-std::unique_ptr<StreamCipher>
-make_openssl_rc4(size_t skip);
-
-#endif
-
-}
-
-#endif
diff --git a/src/lib/prov/openssl/openssl_block.cpp b/src/lib/prov/openssl/openssl_block.cpp
deleted file mode 100644
index 7f9bdcf6c..000000000
--- a/src/lib/prov/openssl/openssl_block.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
-* Block Ciphers via OpenSSL
-* (C) 1999-2010,2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/block_cipher.h>
-#include <botan/internal/openssl.h>
-#include <openssl/evp.h>
-
-namespace Botan {
-
-namespace {
-
-class OpenSSL_BlockCipher final : public BlockCipher
-   {
-   public:
-      OpenSSL_BlockCipher(const std::string& name,
-                          const EVP_CIPHER* cipher);
-
-      OpenSSL_BlockCipher(const std::string& name,
-                          const EVP_CIPHER* cipher,
-                          size_t kl_min, size_t kl_max, size_t kl_mod);
-
-      ~OpenSSL_BlockCipher();
-
-      void clear() override;
-      std::string provider() const override { return "openssl"; }
-      std::string name() const override { return m_cipher_name; }
-      BlockCipher* clone() const override;
-
-      size_t block_size() const override { return m_block_sz; }
-
-      Key_Length_Specification key_spec() const override { return m_cipher_key_spec; }
-
-      void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
-         {
-         verify_key_set(m_key_set);
-         int out_len = 0;
-         if(!EVP_EncryptUpdate(m_encrypt, out, &out_len, in, blocks * m_block_sz))
-            throw OpenSSL_Error("EVP_EncryptUpdate", ERR_get_error());
-         }
-
-      void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
-         {
-         verify_key_set(m_key_set);
-         int out_len = 0;
-         if(!EVP_DecryptUpdate(m_decrypt, out, &out_len, in, blocks * m_block_sz))
-            throw OpenSSL_Error("EVP_DecryptUpdate", ERR_get_error());
-         }
-
-      void key_schedule(const uint8_t key[], size_t key_len) override;
-
-      size_t m_block_sz;
-      Key_Length_Specification m_cipher_key_spec;
-      std::string m_cipher_name;
-      EVP_CIPHER_CTX *m_encrypt;
-      EVP_CIPHER_CTX *m_decrypt;
-      bool m_key_set;
-   };
-
-OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
-                                         const EVP_CIPHER* algo) :
-   m_block_sz(EVP_CIPHER_block_size(algo)),
-   m_cipher_key_spec(EVP_CIPHER_key_length(algo)),
-   m_cipher_name(algo_name),
-   m_key_set(false)
-   {
-   if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
-      throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
-
-   m_encrypt = EVP_CIPHER_CTX_new();
-   m_decrypt = EVP_CIPHER_CTX_new();
-   if (m_encrypt == nullptr || m_decrypt == nullptr)
-      throw OpenSSL_Error("Can't allocate new context", ERR_get_error());
-
-   EVP_CIPHER_CTX_init(m_encrypt);
-   EVP_CIPHER_CTX_init(m_decrypt);
-
-   if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
-      throw OpenSSL_Error("EVP_EncryptInit_ex", ERR_get_error());
-   if(!EVP_DecryptInit_ex(m_decrypt, algo, nullptr, nullptr, nullptr))
-      throw OpenSSL_Error("EVP_DecryptInit_ex", ERR_get_error());
-
-   if(!EVP_CIPHER_CTX_set_padding(m_encrypt, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding encrypt", ERR_get_error());
-   if(!EVP_CIPHER_CTX_set_padding(m_decrypt, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding decrypt", ERR_get_error());
-   }
-
-OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
-                                         const EVP_CIPHER* algo,
-                                         size_t key_min,
-                                         size_t key_max,
-                                         size_t key_mod) :
-   m_block_sz(EVP_CIPHER_block_size(algo)),
-   m_cipher_key_spec(key_min, key_max, key_mod),
-   m_cipher_name(algo_name),
-   m_key_set(false)
-   {
-   if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
-      throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
-
-   m_encrypt = EVP_CIPHER_CTX_new();
-   m_decrypt = EVP_CIPHER_CTX_new();
-   if (m_encrypt == nullptr || m_decrypt == nullptr)
-      throw OpenSSL_Error("Can't allocate new context", ERR_get_error());
-
-   EVP_CIPHER_CTX_init(m_encrypt);
-   EVP_CIPHER_CTX_init(m_decrypt);
-
-   if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
-      throw OpenSSL_Error("EVP_EncryptInit_ex", ERR_get_error());
-   if(!EVP_DecryptInit_ex(m_decrypt, algo, nullptr, nullptr, nullptr))
-      throw OpenSSL_Error("EVP_DecryptInit_ex", ERR_get_error());
-
-   if(!EVP_CIPHER_CTX_set_padding(m_encrypt, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding encrypt", ERR_get_error());
-   if(!EVP_CIPHER_CTX_set_padding(m_decrypt, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding decrypt", ERR_get_error());
-   }
-
-OpenSSL_BlockCipher::~OpenSSL_BlockCipher()
-   {
-   EVP_CIPHER_CTX_cleanup(m_encrypt);
-   EVP_CIPHER_CTX_cleanup(m_decrypt);
-
-   EVP_CIPHER_CTX_free(m_encrypt);
-   EVP_CIPHER_CTX_free(m_decrypt);
-   }
-
-/*
-* Set the key
-*/
-void OpenSSL_BlockCipher::key_schedule(const uint8_t key[], size_t length)
-   {
-   secure_vector<uint8_t> full_key(key, key + length);
-
-   if(m_cipher_name == "TripleDES" && length == 16)
-      {
-      full_key += std::make_pair(key, 8);
-      }
-   else
-      {
-      if(EVP_CIPHER_CTX_set_key_length(m_encrypt, length) == 0 ||
-         EVP_CIPHER_CTX_set_key_length(m_decrypt, length) == 0)
-         throw Invalid_Argument("OpenSSL_BlockCipher: Bad key length for " +
-                                m_cipher_name);
-      }
-
-   if(!EVP_EncryptInit_ex(m_encrypt, nullptr, nullptr, full_key.data(), nullptr))
-      throw OpenSSL_Error("EVP_EncryptInit_ex", ERR_get_error());
-   if(!EVP_DecryptInit_ex(m_decrypt, nullptr, nullptr, full_key.data(), nullptr))
-      throw OpenSSL_Error("EVP_DecryptInit_ex", ERR_get_error());
-
-   m_key_set = true;
-   }
-
-/*
-* Return a clone of this object
-*/
-BlockCipher* OpenSSL_BlockCipher::clone() const
-   {
-   return new OpenSSL_BlockCipher(m_cipher_name,
-                                  EVP_CIPHER_CTX_cipher(m_encrypt),
-                                  m_cipher_key_spec.minimum_keylength(),
-                                  m_cipher_key_spec.maximum_keylength(),
-                                  m_cipher_key_spec.keylength_multiple());
-   }
-
-/*
-* Clear memory of sensitive data
-*/
-void OpenSSL_BlockCipher::clear()
-   {
-   const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_encrypt);
-
-   m_key_set = false;
-
-   if(!EVP_CIPHER_CTX_cleanup(m_encrypt))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup encrypt", ERR_get_error());
-   if(!EVP_CIPHER_CTX_cleanup(m_decrypt))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup decrypt", ERR_get_error());
-   EVP_CIPHER_CTX_init(m_encrypt);
-   EVP_CIPHER_CTX_init(m_decrypt);
-   if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
-      throw OpenSSL_Error("EVP_EncryptInit_ex", ERR_get_error());
-   if(!EVP_DecryptInit_ex(m_decrypt, algo, nullptr, nullptr, nullptr))
-      throw OpenSSL_Error("EVP_DecryptInit_ex", ERR_get_error());
-   if(!EVP_CIPHER_CTX_set_padding(m_encrypt, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding encrypt", ERR_get_error());
-   if(!EVP_CIPHER_CTX_set_padding(m_decrypt, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding decrypt", ERR_get_error());
-   }
-
-}
-
-std::unique_ptr<BlockCipher>
-make_openssl_block_cipher(const std::string& name)
-   {
-#define MAKE_OPENSSL_BLOCK(evp_fn) \
-   std::unique_ptr<BlockCipher>(new OpenSSL_BlockCipher(name, evp_fn()))
-#define MAKE_OPENSSL_BLOCK_KEYLEN(evp_fn, kl_min, kl_max, kl_mod)       \
-   std::unique_ptr<BlockCipher>(new OpenSSL_BlockCipher(name, evp_fn(), kl_min, kl_max, kl_mod))
-
-#if defined(BOTAN_HAS_AES) && !defined(OPENSSL_NO_AES)
-   if(name == "AES-128")
-      return MAKE_OPENSSL_BLOCK(EVP_aes_128_ecb);
-   if(name == "AES-192")
-      return MAKE_OPENSSL_BLOCK(EVP_aes_192_ecb);
-   if(name == "AES-256")
-      return MAKE_OPENSSL_BLOCK(EVP_aes_256_ecb);
-#endif
-
-#if defined(BOTAN_HAS_CAMELLIA) && !defined(OPENSSL_NO_CAMELLIA)
-   if(name == "Camellia-128")
-      return MAKE_OPENSSL_BLOCK(EVP_camellia_128_ecb);
-   if(name == "Camellia-192")
-      return MAKE_OPENSSL_BLOCK(EVP_camellia_192_ecb);
-   if(name == "Camellia-256")
-      return MAKE_OPENSSL_BLOCK(EVP_camellia_256_ecb);
-#endif
-
-#if defined(BOTAN_HAS_DES) && !defined(OPENSSL_NO_DES)
-   if(name == "TripleDES")
-      return MAKE_OPENSSL_BLOCK_KEYLEN(EVP_des_ede3_ecb, 16, 24, 8);
-#endif
-
-   return nullptr;
-   }
-
-}
-
diff --git a/src/lib/prov/openssl/openssl_ec.cpp b/src/lib/prov/openssl/openssl_ec.cpp
deleted file mode 100644
index 3f691f68a..000000000
--- a/src/lib/prov/openssl/openssl_ec.cpp
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
-* ECDSA and ECDH via OpenSSL
-* (C) 2015,2016 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/openssl.h>
-
-#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
-  #include <botan/der_enc.h>
-  #include <botan/pkcs8.h>
-  #include <botan/internal/pk_ops_impl.h>
-#endif
-
-#if defined(BOTAN_HAS_ECDSA)
-  #include <botan/ecdsa.h>
-#endif
-
-#if defined(BOTAN_HAS_ECDH)
-  #include <botan/ecdh.h>
-#endif
-
-#include <openssl/x509.h>
-#include <openssl/objects.h>
-
-#if !defined(OPENSSL_NO_EC)
-  #include <openssl/ec.h>
-#endif
-
-#if !defined(OPENSSL_NO_ECDSA)
-  #include <openssl/ecdsa.h>
-#endif
-
-#if !defined(OPENSSL_NO_ECDH)
-  #include <openssl/ecdh.h>
-#endif
-
-namespace Botan {
-
-#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
-
-namespace {
-
-secure_vector<uint8_t> PKCS8_for_openssl(const EC_PrivateKey& ec)
-   {
-   const PointGFp& pub_key = ec.public_point();
-   const BigInt& priv_key = ec.private_value();
-
-   return DER_Encoder()
-     .start_cons(SEQUENCE)
-        .encode(static_cast<size_t>(1))
-        .encode(BigInt::encode_1363(priv_key, priv_key.bytes()), OCTET_STRING)
-      .start_cons(ASN1_Tag(0), PRIVATE)
-      .raw_bytes(ec.domain().DER_encode(EC_DOMPAR_ENC_OID))
-      .end_cons()
-      .start_cons(ASN1_Tag(1), PRIVATE)
-      .encode(pub_key.encode(PointGFp::UNCOMPRESSED), BIT_STRING)
-      .end_cons()
-      .end_cons()
-      .get_contents();
-   }
-
-int OpenSSL_EC_curve_builtin(int nid)
-   {
-   // the NID macro is still defined even though the curve may not be
-   // supported, so we need to check the list of builtin curves at runtime
-   EC_builtin_curve builtin_curves[100];
-   size_t num = 0;
-
-   if (!(num = EC_get_builtin_curves(builtin_curves, sizeof(builtin_curves))))
-      {
-      return -1;
-      }
-
-   for(size_t i = 0; i < num; ++i)
-      {
-      if(builtin_curves[i].nid == nid)
-         {
-         return nid;
-         }
-      }
-
-   return -1;
-   }
-
-int OpenSSL_EC_nid_for(const OID& oid)
-   {
-   if(oid.empty())
-      return -1;
-
-   const std::string name = oid.to_formatted_string();
-
-   if(name == "secp192r1")
-      return OpenSSL_EC_curve_builtin(NID_X9_62_prime192v1);
-   if(name == "secp224r1")
-      return OpenSSL_EC_curve_builtin(NID_secp224r1);
-   if(name == "secp256r1")
-      return OpenSSL_EC_curve_builtin(NID_X9_62_prime256v1);
-   if(name == "secp384r1")
-      return OpenSSL_EC_curve_builtin(NID_secp384r1);
-   if(name == "secp521r1")
-      return OpenSSL_EC_curve_builtin(NID_secp521r1);
-
-   // OpenSSL 1.0.2 added brainpool curves
-#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
-   if(name == "brainpool160r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP160r1);
-   if(name == "brainpool192r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP192r1);
-   if(name == "brainpool224r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP224r1);
-   if(name == "brainpool256r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP256r1);
-   if(name == "brainpool320r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP320r1);
-   if(name == "brainpool384r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP384r1);
-   if(name == "brainpool512r1")
-      return OpenSSL_EC_curve_builtin(NID_brainpoolP512r1);
-#endif
-
-   return -1;
-   }
-
-}
-
-#endif
-
-#if defined(BOTAN_HAS_ECDSA) && !defined(OPENSSL_NO_ECDSA)
-
-namespace {
-
-class OpenSSL_ECDSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
-   {
-   public:
-      OpenSSL_ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa, const std::string& emsa, int nid) :
-         PK_Ops::Verification_with_EMSA(emsa), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free)
-         {
-         std::unique_ptr<::EC_GROUP, std::function<void (::EC_GROUP*)>> grp(::EC_GROUP_new_by_curve_name(nid),
-                                                                            ::EC_GROUP_free);
-
-         if(!grp)
-            throw OpenSSL_Error("EC_GROUP_new_by_curve_name", ERR_get_error());
-
-         if(!::EC_KEY_set_group(m_ossl_ec.get(), grp.get()))
-            throw OpenSSL_Error("EC_KEY_set_group", ERR_get_error());
-
-         const std::vector<uint8_t> enc = ecdsa.public_point().encode(PointGFp::UNCOMPRESSED);
-         const uint8_t* enc_ptr = enc.data();
-         EC_KEY* key_ptr = m_ossl_ec.get();
-         if(!::o2i_ECPublicKey(&key_ptr, &enc_ptr, enc.size()))
-            throw OpenSSL_Error("o2i_ECPublicKey", ERR_get_error());
-
-         const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get());
-         m_order_bits = ::EC_GROUP_get_degree(group);
-         }
-
-      size_t max_input_bits() const override { return m_order_bits; }
-
-      bool with_recovery() const override { return false; }
-
-      bool verify(const uint8_t msg[], size_t msg_len,
-                  const uint8_t sig_bytes[], size_t sig_len) override
-         {
-         const size_t order_bytes = (m_order_bits + 7) / 8;
-         if(sig_len != 2 * order_bytes)
-            return false;
-
-         std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(nullptr, ECDSA_SIG_free);
-         sig.reset(::ECDSA_SIG_new());
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-         sig->r = BN_bin2bn(sig_bytes              , sig_len / 2, sig->r);
-         sig->s = BN_bin2bn(sig_bytes + sig_len / 2, sig_len / 2, sig->s);
-#else
-         BIGNUM* r = BN_bin2bn(sig_bytes              , sig_len / 2, nullptr);
-         BIGNUM* s = BN_bin2bn(sig_bytes + sig_len / 2, sig_len / 2, nullptr);
-         if(r == nullptr || s == nullptr)
-            throw OpenSSL_Error("BN_bin2bn sig s", ERR_get_error());
-
-         ECDSA_SIG_set0(sig.get(), r, s);
-#endif
-
-         const int res = ECDSA_do_verify(msg, msg_len, sig.get(), m_ossl_ec.get());
-         if(res < 0)
-            {
-            int err = ERR_get_error();
-
-            bool hard_error = true;
-
-#if defined(EC_R_BAD_SIGNATURE)
-            if(ERR_GET_REASON(err) == EC_R_BAD_SIGNATURE)
-               hard_error = false;
-#endif
-#if defined(EC_R_POINT_AT_INFINITY)
-            if(ERR_GET_REASON(err) == EC_R_POINT_AT_INFINITY)
-               hard_error = false;
-#endif
-#if defined(ECDSA_R_BAD_SIGNATURE)
-            if(ERR_GET_REASON(err) == ECDSA_R_BAD_SIGNATURE)
-               hard_error = false;
-#endif
-
-            if(hard_error)
-               throw OpenSSL_Error("ECDSA_do_verify", err);
-            }
-         return (res == 1);
-         }
-
-   private:
-      std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec;
-      size_t m_order_bits = 0;
-   };
-
-class OpenSSL_ECDSA_Signing_Operation final : public PK_Ops::Signature_with_EMSA
-   {
-   public:
-      OpenSSL_ECDSA_Signing_Operation(const ECDSA_PrivateKey& ecdsa, const std::string& emsa) :
-         PK_Ops::Signature_with_EMSA(emsa),
-         m_ossl_ec(nullptr, ::EC_KEY_free)
-         {
-         const secure_vector<uint8_t> der = PKCS8_for_openssl(ecdsa);
-         const uint8_t* der_ptr = der.data();
-         m_ossl_ec.reset(d2i_ECPrivateKey(nullptr, &der_ptr, der.size()));
-         if(!m_ossl_ec)
-            throw OpenSSL_Error("d2i_ECPrivateKey", ERR_get_error());
-
-         const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get());
-         m_order_bits = ::EC_GROUP_get_degree(group);
-         m_order_bytes = (m_order_bits + 7) / 8;
-         }
-
-      size_t signature_length() const override { return 2*m_order_bytes; }
-
-      secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
-                                   RandomNumberGenerator&) override
-         {
-         std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(nullptr, ECDSA_SIG_free);
-         sig.reset(::ECDSA_do_sign(msg, msg_len, m_ossl_ec.get()));
-
-         if(!sig)
-            throw OpenSSL_Error("ECDSA_do_sign", ERR_get_error());
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-         const BIGNUM* r = sig->r;
-         const BIGNUM* s = sig->s;
-#else
-         const BIGNUM* r;
-         const BIGNUM* s;
-         ECDSA_SIG_get0(sig.get(), &r, &s);
-#endif
-
-         const size_t r_bytes = BN_num_bytes(r);
-         const size_t s_bytes = BN_num_bytes(s);
-         secure_vector<uint8_t> sigval(2*m_order_bytes);
-         BN_bn2bin(r, &sigval[m_order_bytes - r_bytes]);
-         BN_bn2bin(s, &sigval[2*m_order_bytes - s_bytes]);
-         return sigval;
-         }
-
-      size_t max_input_bits() const override { return m_order_bits; }
-
-   private:
-      std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec;
-      size_t m_order_bits;
-      size_t m_order_bytes;
-   };
-
-}
-
-std::unique_ptr<PK_Ops::Verification>
-make_openssl_ecdsa_ver_op(const ECDSA_PublicKey& key, const std::string& params)
-   {
-   const int nid = OpenSSL_EC_nid_for(key.domain().get_curve_oid());
-   if(nid < 0)
-      {
-      throw Lookup_Error("OpenSSL ECDSA does not support this curve");
-      }
-
-   try
-      {
-      return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_ECDSA_Verification_Operation(key, params, nid));
-      }
-   catch(OpenSSL_Error&)
-      {
-      throw Lookup_Error("OpenSSL ECDSA does not support this key");
-      }
-   }
-
-std::unique_ptr<PK_Ops::Signature>
-make_openssl_ecdsa_sig_op(const ECDSA_PrivateKey& key, const std::string& params)
-   {
-   const int nid = OpenSSL_EC_nid_for(key.domain().get_curve_oid());
-   if(nid < 0)
-      {
-      throw Lookup_Error("OpenSSL ECDSA does not support this curve");
-      }
-   return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_ECDSA_Signing_Operation(key, params));
-   }
-
-#endif
-
-#if defined(BOTAN_HAS_ECDH) && !defined(OPENSSL_NO_ECDH)
-
-namespace {
-
-class OpenSSL_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
-   {
-   public:
-
-      OpenSSL_ECDH_KA_Operation(const ECDH_PrivateKey& ecdh, const std::string& kdf) :
-         PK_Ops::Key_Agreement_with_KDF(kdf), m_ossl_ec(::EC_KEY_new(), ::EC_KEY_free)
-         {
-         m_value_size = ecdh.domain().get_p_bytes();
-         const secure_vector<uint8_t> der = PKCS8_for_openssl(ecdh);
-         const uint8_t* der_ptr = der.data();
-         m_ossl_ec.reset(d2i_ECPrivateKey(nullptr, &der_ptr, der.size()));
-         if(!m_ossl_ec)
-            throw OpenSSL_Error("d2i_ECPrivateKey", ERR_get_error());
-         }
-
-      size_t agreed_value_size() const override { return m_value_size; }
-
-      secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
-         {
-         const EC_GROUP* group = ::EC_KEY_get0_group(m_ossl_ec.get());
-         const size_t out_len = (::EC_GROUP_get_degree(group) + 7) / 8;
-         secure_vector<uint8_t> out(out_len);
-
-         std::unique_ptr<EC_POINT, std::function<void (EC_POINT*)>> pub_key(
-            ::EC_POINT_new(group), ::EC_POINT_free);
-
-         if(!pub_key)
-            throw OpenSSL_Error("EC_POINT_new", ERR_get_error());
-
-         const int os2ecp_rc =
-            ::EC_POINT_oct2point(group, pub_key.get(), w, w_len, nullptr);
-
-         if(os2ecp_rc != 1)
-            throw OpenSSL_Error("EC_POINT_oct2point", ERR_get_error());
-
-         const int ecdh_rc = ::ECDH_compute_key(out.data(),
-                                                out.size(),
-                                                pub_key.get(),
-                                                m_ossl_ec.get(),
-                                                /*KDF*/nullptr);
-
-         if(ecdh_rc <= 0)
-            throw OpenSSL_Error("ECDH_compute_key", ERR_get_error());
-
-         const size_t ecdh_sz = static_cast<size_t>(ecdh_rc);
-
-         if(ecdh_sz > out.size())
-            throw Internal_Error("OpenSSL ECDH returned more than requested");
-
-         out.resize(ecdh_sz);
-         return out;
-         }
-
-   private:
-      std::unique_ptr<EC_KEY, std::function<void (EC_KEY*)>> m_ossl_ec;
-      size_t m_value_size;
-   };
-
-}
-
-std::unique_ptr<PK_Ops::Key_Agreement>
-make_openssl_ecdh_ka_op(const ECDH_PrivateKey& key, const std::string& params)
-   {
-   const int nid = OpenSSL_EC_nid_for(key.domain().get_curve_oid());
-   if(nid < 0)
-      {
-      throw Lookup_Error("OpenSSL ECDH does not support this curve");
-      }
-
-   return std::unique_ptr<PK_Ops::Key_Agreement>(new OpenSSL_ECDH_KA_Operation(key, params));
-   }
-
-#endif
-
-}
-
diff --git a/src/lib/prov/openssl/openssl_hash.cpp b/src/lib/prov/openssl/openssl_hash.cpp
deleted file mode 100644
index 9a56228c7..000000000
--- a/src/lib/prov/openssl/openssl_hash.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-* OpenSSL Hash Functions
-* (C) 1999-2007,2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/hash.h>
-#include <botan/internal/openssl.h>
-#include <openssl/evp.h>
-#include <unordered_map>
-
-namespace Botan {
-
-namespace {
-
-class OpenSSL_HashFunction final : public HashFunction
-   {
-   public:
-      void clear() override
-         {
-         const EVP_MD* algo = EVP_MD_CTX_md(m_md);
-         if(!EVP_DigestInit_ex(m_md, algo, nullptr))
-            throw OpenSSL_Error("EVP_DigestInit_ex", ERR_get_error());
-         }
-
-      std::string provider() const override { return "openssl"; }
-      std::string name() const override { return m_name; }
-
-      HashFunction* clone() const override
-         {
-         const EVP_MD* algo = EVP_MD_CTX_md(m_md);
-         return new OpenSSL_HashFunction(name(), algo);
-         }
-
-      std::unique_ptr<HashFunction> copy_state() const override
-         {
-         std::unique_ptr<OpenSSL_HashFunction> copy(new OpenSSL_HashFunction(m_name, nullptr));
-         EVP_MD_CTX_copy(copy->m_md, m_md);
-         return std::unique_ptr<HashFunction>(copy.release());
-         }
-
-      size_t output_length() const override
-         {
-         return EVP_MD_size(EVP_MD_CTX_md(m_md));
-         }
-
-      size_t hash_block_size() const override
-         {
-         return EVP_MD_block_size(EVP_MD_CTX_md(m_md));
-         }
-
-      OpenSSL_HashFunction(const std::string& name, const EVP_MD* md) : m_name(name)
-         {
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-         m_md = EVP_MD_CTX_create();
-#else
-         m_md = EVP_MD_CTX_new();
-#endif
-
-         if(m_md == nullptr)
-            throw OpenSSL_Error("Can't allocate new context", ERR_get_error());
-         EVP_MD_CTX_init(m_md);
-         if(md && !EVP_DigestInit_ex(m_md, md, nullptr))
-            throw OpenSSL_Error("EVP_DigestInit_ex", ERR_get_error());
-         }
-
-      OpenSSL_HashFunction(EVP_MD_CTX* ctx) : m_md(ctx)
-         {
-         }
-
-      ~OpenSSL_HashFunction()
-         {
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-         EVP_MD_CTX_destroy(m_md);
-#else
-         EVP_MD_CTX_free(m_md);
-#endif
-         }
-
-   private:
-      void add_data(const uint8_t input[], size_t length) override
-         {
-         if(!EVP_DigestUpdate(m_md, input, length))
-            throw OpenSSL_Error("EVP_DigestUpdate", ERR_get_error());
-         }
-
-      void final_result(uint8_t output[]) override
-         {
-         if(!EVP_DigestFinal_ex(m_md, output, nullptr))
-            throw OpenSSL_Error("EVP_DigestFinal_ex", ERR_get_error());
-         const EVP_MD* algo = EVP_MD_CTX_md(m_md);
-         if(!EVP_DigestInit_ex(m_md, algo, nullptr))
-            throw OpenSSL_Error("EVP_DigestInit_ex", ERR_get_error());
-         }
-
-      std::string m_name;
-      EVP_MD_CTX* m_md;
-   };
-
-}
-
-std::unique_ptr<HashFunction>
-make_openssl_hash(const std::string& name)
-   {
-#define MAKE_OPENSSL_HASH(fn)                                       \
-   std::unique_ptr<HashFunction>(new OpenSSL_HashFunction(name, fn ()))
-
-#if defined(BOTAN_HAS_SHA2_32) && !defined(OPENSSL_NO_SHA256)
-   if(name == "SHA-224")
-      return MAKE_OPENSSL_HASH(EVP_sha224);
-   if(name == "SHA-256")
-      return MAKE_OPENSSL_HASH(EVP_sha256);
-#endif
-
-#if defined(BOTAN_HAS_SHA2_64) && !defined(OPENSSL_NO_SHA512)
-   if(name == "SHA-384")
-      return MAKE_OPENSSL_HASH(EVP_sha384);
-   if(name == "SHA-512")
-      return MAKE_OPENSSL_HASH(EVP_sha512);
-#endif
-
-#if defined(BOTAN_HAS_SHA1) && !defined(OPENSSL_NO_SHA)
-   if(name == "SHA-160" || name == "SHA-1" || name == "SHA1")
-      return MAKE_OPENSSL_HASH(EVP_sha1);
-#endif
-
-#if defined(BOTAN_HAS_MD5) && !defined(OPENSSL_NO_MD5)
-   if(name == "MD5")
-      return MAKE_OPENSSL_HASH(EVP_md5);
-   #endif
-
-   return nullptr;
-   }
-
-}
diff --git a/src/lib/prov/openssl/openssl_mode.cpp b/src/lib/prov/openssl/openssl_mode.cpp
deleted file mode 100644
index 81f8413a2..000000000
--- a/src/lib/prov/openssl/openssl_mode.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
-* Cipher Modes via OpenSSL
-* (C) 1999-2010,2015 Jack Lloyd
-* (C) 2017 Alexander Bluhm (genua GmbH)
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/cipher_mode.h>
-#include <botan/internal/rounding.h>
-#include <botan/internal/openssl.h>
-#include <openssl/evp.h>
-#include <limits.h>
-
-namespace Botan {
-
-namespace {
-
-class OpenSSL_Cipher_Mode final : public Cipher_Mode
-   {
-   public:
-      OpenSSL_Cipher_Mode(const std::string& name,
-                          const EVP_CIPHER* cipher,
-                          Cipher_Dir direction);
-      ~OpenSSL_Cipher_Mode();
-
-      std::string provider() const override { return "openssl"; }
-      std::string name() const override { return m_mode_name; }
-
-      void start_msg(const uint8_t nonce[], size_t nonce_len) override;
-      size_t process(uint8_t msg[], size_t msg_len) override;
-      void finish(secure_vector<uint8_t>& final_block, size_t offset0) override;
-      size_t output_length(size_t input_length) const override;
-      size_t update_granularity() const override;
-      size_t minimum_final_size() const override;
-      size_t default_nonce_length() const override;
-      bool valid_nonce_length(size_t nonce_len) const override;
-      void clear() override;
-      void reset() override;
-      Key_Length_Specification key_spec() const override;
-
-   private:
-      void key_schedule(const uint8_t key[], size_t length) override;
-
-      const std::string m_mode_name;
-      const Cipher_Dir m_direction;
-      size_t m_block_size;
-      EVP_CIPHER_CTX* m_cipher;
-      bool m_key_set;
-      bool m_nonce_set;
-   };
-
-OpenSSL_Cipher_Mode::OpenSSL_Cipher_Mode(const std::string& name,
-                                         const EVP_CIPHER* algo,
-                                         Cipher_Dir direction) :
-   m_mode_name(name),
-   m_direction(direction),
-   m_key_set(false),
-   m_nonce_set(false)
-   {
-   m_block_size = EVP_CIPHER_block_size(algo);
-
-   if(EVP_CIPHER_mode(algo) != EVP_CIPH_CBC_MODE)
-      throw Invalid_Argument("OpenSSL_BlockCipher: Non-CBC EVP was passed in");
-
-   m_cipher = EVP_CIPHER_CTX_new();
-   if (m_cipher == nullptr)
-      throw OpenSSL_Error("Can't allocate new context", ERR_get_error());
-
-   EVP_CIPHER_CTX_init(m_cipher);
-   if(!EVP_CipherInit_ex(m_cipher, algo, nullptr, nullptr, nullptr,
-                         m_direction == ENCRYPTION ? 1 : 0))
-      throw OpenSSL_Error("EVP_CipherInit_ex", ERR_get_error());
-   if(!EVP_CIPHER_CTX_set_padding(m_cipher, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding", ERR_get_error());
-   }
-
-OpenSSL_Cipher_Mode::~OpenSSL_Cipher_Mode()
-   {
-   EVP_CIPHER_CTX_free(m_cipher);
-   }
-
-void OpenSSL_Cipher_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
-   {
-   verify_key_set(m_key_set);
-
-   if(!valid_nonce_length(nonce_len))
-      throw Invalid_IV_Length(name(), nonce_len);
-
-   if(nonce_len)
-      {
-      if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nonce, -1))
-         throw OpenSSL_Error("EVP_CipherInit_ex nonce", ERR_get_error());
-      }
-   else if(m_nonce_set == false)
-      {
-      const std::vector<uint8_t> zeros(m_block_size);
-      if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, zeros.data(), -1))
-         throw OpenSSL_Error("EVP_CipherInit_ex nonce", ERR_get_error());
-      }
-   // otherwise existing CBC state left unchanged
-
-   m_nonce_set = true;
-   }
-
-size_t OpenSSL_Cipher_Mode::process(uint8_t msg[], size_t msg_len)
-   {
-   verify_key_set(m_key_set);
-   BOTAN_STATE_CHECK(m_nonce_set);
-
-   if(msg_len == 0)
-      return 0;
-   if(msg_len > INT_MAX)
-      throw Internal_Error("msg_len overflow");
-   int outl = msg_len;
-   secure_vector<uint8_t> out(outl);
-
-   if(!EVP_CipherUpdate(m_cipher, out.data(), &outl, msg, msg_len))
-      throw OpenSSL_Error("EVP_CipherUpdate", ERR_get_error());
-   copy_mem(msg, out.data(), outl);
-   return outl;
-   }
-
-void OpenSSL_Cipher_Mode::finish(secure_vector<uint8_t>& buffer,
-                                 size_t offset)
-   {
-   verify_key_set(m_key_set);
-   BOTAN_STATE_CHECK(m_nonce_set);
-
-   BOTAN_ASSERT(buffer.size() >= offset, "Offset ok");
-   uint8_t* buf = buffer.data() + offset;
-   const size_t buf_size = buffer.size() - offset;
-
-   size_t written = process(buf, buf_size);
-   int outl = buf_size - written;
-   secure_vector<uint8_t> out(outl);
-
-   if(!EVP_CipherFinal_ex(m_cipher, out.data(), &outl))
-      throw OpenSSL_Error("EVP_CipherFinal_ex", ERR_get_error());
-   copy_mem(buf + written, out.data(), outl);
-   written += outl;
-   buffer.resize(offset + written);
-   }
-
-size_t OpenSSL_Cipher_Mode::update_granularity() const
-   {
-   return m_block_size * BOTAN_BLOCK_CIPHER_PAR_MULT;
-   }
-
-size_t OpenSSL_Cipher_Mode::minimum_final_size() const
-   {
-   return 0; // no padding
-   }
-
-size_t OpenSSL_Cipher_Mode::default_nonce_length() const
-   {
-   return m_block_size;
-   }
-
-bool OpenSSL_Cipher_Mode::valid_nonce_length(size_t nonce_len) const
-   {
-   return (nonce_len == 0 || nonce_len == m_block_size);
-   }
-
-size_t OpenSSL_Cipher_Mode::output_length(size_t input_length) const
-   {
-   if(input_length == 0)
-      return m_block_size;
-   else
-      return round_up(input_length, m_block_size);
-   }
-
-void OpenSSL_Cipher_Mode::clear()
-   {
-   m_key_set = false;
-   m_nonce_set = false;
-
-   const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_cipher);
-
-   if(!EVP_CIPHER_CTX_cleanup(m_cipher))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup", ERR_get_error());
-   EVP_CIPHER_CTX_init(m_cipher);
-   if(!EVP_CipherInit_ex(m_cipher, algo, nullptr, nullptr, nullptr,
-                         m_direction == ENCRYPTION ? 1 : 0))
-      throw OpenSSL_Error("EVP_CipherInit_ex clear", ERR_get_error());
-   if(!EVP_CIPHER_CTX_set_padding(m_cipher, 0))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding clear", ERR_get_error());
-   }
-
-void OpenSSL_Cipher_Mode::reset()
-   {
-   if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nullptr, -1))
-      throw OpenSSL_Error("EVP_CipherInit_ex clear", ERR_get_error());
-   m_nonce_set = false;
-   }
-
-Key_Length_Specification OpenSSL_Cipher_Mode::key_spec() const
-   {
-   return Key_Length_Specification(EVP_CIPHER_CTX_key_length(m_cipher));
-   }
-
-void OpenSSL_Cipher_Mode::key_schedule(const uint8_t key[], size_t length)
-   {
-   if(!EVP_CIPHER_CTX_set_key_length(m_cipher, length))
-      throw OpenSSL_Error("EVP_CIPHER_CTX_set_key_length", ERR_get_error());
-   if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, key, nullptr, -1))
-      throw OpenSSL_Error("EVP_CipherInit_ex key", ERR_get_error());
-   m_key_set = true;
-   m_nonce_set = false;
-   }
-
-}
-
-Cipher_Mode*
-make_openssl_cipher_mode(const std::string& name, Cipher_Dir direction)
-   {
-#define MAKE_OPENSSL_MODE(evp_fn) \
-   new OpenSSL_Cipher_Mode(name, (evp_fn)(), direction)
-
-#if defined(BOTAN_HAS_AES) && defined(BOTAN_HAS_MODE_CBC) && !defined(OPENSSL_NO_AES)
-   if(name == "AES-128/CBC/NoPadding")
-      return MAKE_OPENSSL_MODE(EVP_aes_128_cbc);
-   if(name == "AES-192/CBC/NoPadding")
-      return MAKE_OPENSSL_MODE(EVP_aes_192_cbc);
-   if(name == "AES-256/CBC/NoPadding")
-      return MAKE_OPENSSL_MODE(EVP_aes_256_cbc);
-#endif
-
-#undef MAKE_OPENSSL_MODE
-   return nullptr;
-   }
-
-}
diff --git a/src/lib/prov/openssl/openssl_rc4.cpp b/src/lib/prov/openssl/openssl_rc4.cpp
deleted file mode 100644
index dbda890f8..000000000
--- a/src/lib/prov/openssl/openssl_rc4.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-* OpenSSL RC4
-* (C) 1999-2007,2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/stream_cipher.h>
-
-#if defined(BOTAN_HAS_OPENSSL) && defined(BOTAN_HAS_RC4)
-
-#include <botan/internal/openssl.h>
-#include <botan/parsing.h>
-#include <botan/exceptn.h>
-#include <openssl/rc4.h>
-
-namespace Botan {
-
-namespace {
-
-class OpenSSL_RC4 final : public StreamCipher
-   {
-   public:
-      void clear() override { clear_mem(&m_rc4, 1); m_key_set = false; }
-
-      std::string provider() const override { return "openssl"; }
-
-      std::string name() const override
-         {
-         switch(m_skip)
-            {
-            case 0:
-               return "RC4";
-            case 256:
-               return "MARK-4";
-            default:
-               return "RC4(" + std::to_string(m_skip) + ")";
-            }
-         }
-
-      StreamCipher* clone() const override { return new OpenSSL_RC4(m_skip); }
-
-      Key_Length_Specification key_spec() const override
-         {
-         return Key_Length_Specification(1, 32);
-         }
-
-      explicit OpenSSL_RC4(size_t skip = 0) : m_skip(skip) { clear(); }
-      ~OpenSSL_RC4() { clear(); }
-
-      void set_iv(const uint8_t*, size_t len) override
-         {
-         if(len > 0)
-            throw Invalid_IV_Length("RC4", len);
-         }
-
-      void seek(uint64_t) override
-         {
-         throw Not_Implemented("RC4 does not support seeking");
-         }
-   private:
-      void cipher(const uint8_t in[], uint8_t out[], size_t length) override
-         {
-         verify_key_set(m_key_set);
-         ::RC4(&m_rc4, length, in, out);
-         }
-
-      void key_schedule(const uint8_t key[], size_t length) override
-         {
-         ::RC4_set_key(&m_rc4, length, key);
-         uint8_t d = 0;
-         for(size_t i = 0; i != m_skip; ++i)
-            ::RC4(&m_rc4, 1, &d, &d);
-         m_key_set = true;
-         }
-
-      size_t m_skip;
-      RC4_KEY m_rc4;
-      bool m_key_set;
-   };
-
-}
-
-std::unique_ptr<StreamCipher>
-make_openssl_rc4(size_t skip)
-   {
-   return std::unique_ptr<StreamCipher>(new OpenSSL_RC4(skip));
-   }
-
-
-}
-
-#endif
diff --git a/src/lib/prov/openssl/openssl_rsa.cpp b/src/lib/prov/openssl/openssl_rsa.cpp
deleted file mode 100644
index 6744b35b2..000000000
--- a/src/lib/prov/openssl/openssl_rsa.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
-* RSA operations provided by OpenSSL
-* (C) 2015 Jack Lloyd
-* (C) 2017 Alexander Bluhm
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/openssl.h>
-
-#if defined(BOTAN_HAS_RSA)
-
-#include <botan/rsa.h>
-#include <botan/rng.h>
-#include <botan/internal/pk_ops_impl.h>
-#include <botan/internal/ct_utils.h>
-
-#include <functional>
-#include <memory>
-#include <cstdlib>
-
-#include <openssl/rsa.h>
-#include <openssl/x509.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include <limits.h>
-
-namespace Botan {
-
-namespace {
-
-std::pair<int, size_t> get_openssl_enc_pad(const std::string& eme)
-   {
-   if(eme == "Raw")
-      return std::make_pair(RSA_NO_PADDING, 0);
-   else if(eme == "EME-PKCS1-v1_5")
-      return std::make_pair(RSA_PKCS1_PADDING, 11);
-   else if(eme == "OAEP(SHA-1)" || eme == "EME1(SHA-1)")
-      return std::make_pair(RSA_PKCS1_OAEP_PADDING, 41);
-   else
-      throw Lookup_Error("OpenSSL RSA does not support EME " + eme);
-   }
-
-class OpenSSL_RSA_Encryption_Operation final : public PK_Ops::Encryption
-   {
-   public:
-
-      OpenSSL_RSA_Encryption_Operation(const RSA_PublicKey& rsa, int pad, size_t pad_overhead) :
-         m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
-         {
-         const std::vector<uint8_t> der = rsa.public_key_bits();
-         const uint8_t* der_ptr = der.data();
-         m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
-         if(!m_openssl_rsa)
-            throw OpenSSL_Error("d2i_RSAPublicKey", ERR_get_error());
-
-         m_bits = 8 * (n_size() - pad_overhead) - 1;
-         }
-
-      size_t ciphertext_length(size_t) const override { return ::RSA_size(m_openssl_rsa.get()); }
-
-      size_t max_input_bits() const override { return m_bits; };
-
-      secure_vector<uint8_t> encrypt(const uint8_t msg[], size_t msg_len,
-                                  RandomNumberGenerator&) override
-         {
-         const size_t mod_sz = n_size();
-
-         if(msg_len > mod_sz)
-            throw Invalid_Argument("Input too large for RSA key");
-
-         secure_vector<uint8_t> outbuf(mod_sz);
-
-         secure_vector<uint8_t> inbuf;
-
-         if(m_padding == RSA_NO_PADDING)
-            {
-            inbuf.resize(mod_sz);
-            copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
-            }
-         else
-            {
-            inbuf.assign(msg, msg + msg_len);
-            }
-
-         int rc = ::RSA_public_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
-                                       m_openssl_rsa.get(), m_padding);
-         if(rc < 0)
-            throw OpenSSL_Error("RSA_public_encrypt", ERR_get_error());
-
-         return outbuf;
-         }
-
-   private:
-      size_t n_size() const { return ::RSA_size(m_openssl_rsa.get()); }
-      std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
-      size_t m_bits = 0;
-      int m_padding = 0;
-   };
-
-class OpenSSL_RSA_Decryption_Operation final : public PK_Ops::Decryption
-   {
-   public:
-
-      OpenSSL_RSA_Decryption_Operation(const RSA_PrivateKey& rsa, int pad) :
-         m_openssl_rsa(nullptr, ::RSA_free), m_padding(pad)
-         {
-         const secure_vector<uint8_t> der = rsa.private_key_bits();
-         const uint8_t* der_ptr = der.data();
-         m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
-         if(!m_openssl_rsa)
-            throw OpenSSL_Error("d2i_RSAPrivateKey", ERR_get_error());
-         }
-
-      size_t plaintext_length(size_t) const override { return ::RSA_size(m_openssl_rsa.get()); }
-
-      secure_vector<uint8_t> decrypt(uint8_t& valid_mask,
-                                  const uint8_t msg[], size_t msg_len) override
-         {
-         secure_vector<uint8_t> buf(::RSA_size(m_openssl_rsa.get()));
-         int rc = ::RSA_private_decrypt(msg_len, msg, buf.data(), m_openssl_rsa.get(), m_padding);
-         if(rc < 0 || static_cast<size_t>(rc) > buf.size())
-            {
-            valid_mask = 0;
-            buf.resize(0);
-            }
-         else
-            {
-            valid_mask = 0xFF;
-            buf.resize(rc);
-            }
-
-         if(m_padding == RSA_NO_PADDING)
-            {
-            return CT::strip_leading_zeros(buf);
-            }
-
-         return buf;
-         }
-
-   private:
-      std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
-      int m_padding = 0;
-   };
-
-class OpenSSL_RSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
-   {
-   public:
-
-      OpenSSL_RSA_Verification_Operation(const RSA_PublicKey& rsa, const std::string& emsa) :
-         PK_Ops::Verification_with_EMSA(emsa),
-         m_openssl_rsa(nullptr, ::RSA_free)
-         {
-         const std::vector<uint8_t> der = rsa.public_key_bits();
-         const uint8_t* der_ptr = der.data();
-         m_openssl_rsa.reset(::d2i_RSAPublicKey(nullptr, &der_ptr, der.size()));
-         if(!m_openssl_rsa)
-            throw OpenSSL_Error("d2i_RSAPublicKey", ERR_get_error());
-         }
-
-      size_t max_input_bits() const override
-         {
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-         return ::BN_num_bits(m_openssl_rsa->n) - 1;
-#else
-         return ::RSA_bits(m_openssl_rsa.get()) - 1;
-#endif
-         }
-
-      bool with_recovery() const override { return true; }
-
-      secure_vector<uint8_t> verify_mr(const uint8_t msg[], size_t msg_len) override
-         {
-         const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
-
-         if(msg_len > mod_sz)
-            throw Invalid_Argument("OpenSSL RSA verify input too large");
-
-         secure_vector<uint8_t> inbuf(mod_sz);
-
-         if(msg_len > 0)
-            copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
-
-         secure_vector<uint8_t> outbuf(mod_sz);
-
-         int rc = ::RSA_public_decrypt(inbuf.size(), inbuf.data(), outbuf.data(),
-                                       m_openssl_rsa.get(), RSA_NO_PADDING);
-         if(rc < 0)
-            throw Invalid_Argument("RSA_public_decrypt");
-
-         return CT::strip_leading_zeros(outbuf);
-         }
-   private:
-      std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
-   };
-
-class OpenSSL_RSA_Signing_Operation final : public PK_Ops::Signature_with_EMSA
-   {
-   public:
-
-      OpenSSL_RSA_Signing_Operation(const RSA_PrivateKey& rsa, const std::string& emsa) :
-         PK_Ops::Signature_with_EMSA(emsa),
-         m_openssl_rsa(nullptr, ::RSA_free)
-         {
-         const secure_vector<uint8_t> der = rsa.private_key_bits();
-         const uint8_t* der_ptr = der.data();
-         m_openssl_rsa.reset(d2i_RSAPrivateKey(nullptr, &der_ptr, der.size()));
-         if(!m_openssl_rsa)
-            throw OpenSSL_Error("d2i_RSAPrivateKey", ERR_get_error());
-         }
-
-      size_t signature_length() const override { return ::RSA_size(m_openssl_rsa.get()); }
-
-      secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
-                                   RandomNumberGenerator&) override
-         {
-         const size_t mod_sz = ::RSA_size(m_openssl_rsa.get());
-
-         if(msg_len > mod_sz)
-            throw Invalid_Argument("OpenSSL RSA sign input too large");
-
-         secure_vector<uint8_t> inbuf(mod_sz);
-         copy_mem(&inbuf[mod_sz - msg_len], msg, msg_len);
-
-         secure_vector<uint8_t> outbuf(mod_sz);
-
-         int rc = ::RSA_private_encrypt(inbuf.size(), inbuf.data(), outbuf.data(),
-                                        m_openssl_rsa.get(), RSA_NO_PADDING);
-         if(rc < 0)
-            throw OpenSSL_Error("RSA_private_encrypt", ERR_get_error());
-
-         return outbuf;
-         }
-
-      size_t max_input_bits() const override
-         {
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-         return ::BN_num_bits(m_openssl_rsa->n) - 1;
-#else
-         return ::RSA_bits(m_openssl_rsa.get()) - 1;
-#endif
-         }
-
-   private:
-      std::unique_ptr<RSA, std::function<void (RSA*)>> m_openssl_rsa;
-   };
-
-}
-
-std::unique_ptr<PK_Ops::Encryption>
-make_openssl_rsa_enc_op(const RSA_PublicKey& key, const std::string& params)
-   {
-   auto pad_info = get_openssl_enc_pad(params);
-   return std::unique_ptr<PK_Ops::Encryption>(
-      new OpenSSL_RSA_Encryption_Operation(key, pad_info.first, pad_info.second));
-   }
-
-std::unique_ptr<PK_Ops::Decryption>
-make_openssl_rsa_dec_op(const RSA_PrivateKey& key, const std::string& params)
-   {
-   auto pad_info = get_openssl_enc_pad(params);
-   return std::unique_ptr<PK_Ops::Decryption>(new OpenSSL_RSA_Decryption_Operation(key, pad_info.first));
-   }
-
-std::unique_ptr<PK_Ops::Verification>
-make_openssl_rsa_ver_op(const RSA_PublicKey& key, const std::string& params)
-   {
-   return std::unique_ptr<PK_Ops::Verification>(new OpenSSL_RSA_Verification_Operation(key, params));
-   }
-
-std::unique_ptr<PK_Ops::Signature>
-make_openssl_rsa_sig_op(const RSA_PrivateKey& key, const std::string& params)
-   {
-   return std::unique_ptr<PK_Ops::Signature>(new OpenSSL_RSA_Signing_Operation(key, params));
-   }
-
-std::unique_ptr<RSA_PrivateKey>
-make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits)
-   {
-   if (rsa_bits > INT_MAX)
-      throw Internal_Error("rsa_bits overflow");
-
-   secure_vector<uint8_t> seed(BOTAN_SYSTEM_RNG_POLL_REQUEST);
-   rng.randomize(seed.data(), seed.size());
-   RAND_seed(seed.data(), seed.size());
-
-   std::unique_ptr<BIGNUM, std::function<void (BIGNUM*)>> bn(BN_new(), BN_free);
-   if(!bn)
-      throw OpenSSL_Error("BN_new", ERR_get_error());
-   if(!BN_set_word(bn.get(), RSA_F4))
-      throw OpenSSL_Error("BN_set_word", ERR_get_error());
-
-   std::unique_ptr<RSA, std::function<void (RSA*)>> rsa(RSA_new(), RSA_free);
-   if(!rsa)
-      throw OpenSSL_Error("RSA_new", ERR_get_error());
-   if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), nullptr))
-      throw OpenSSL_Error("RSA_generate_key_ex", ERR_get_error());
-
-   uint8_t* der = nullptr;
-   int bytes = i2d_RSAPrivateKey(rsa.get(), &der);
-   if(bytes < 0)
-      throw OpenSSL_Error("i2d_RSAPrivateKey", ERR_get_error());
-
-   const secure_vector<uint8_t> keydata(der, der + bytes);
-   secure_scrub_memory(der, bytes);
-   std::free(der);
-   return std::unique_ptr<Botan::RSA_PrivateKey>
-      (new RSA_PrivateKey(AlgorithmIdentifier(), keydata));
-   }
-}
-
-#endif // BOTAN_HAS_RSA
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index e7e49a74f..fe8764679 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -11,10 +11,6 @@
 #include <botan/numthry.h>
 #include <botan/internal/pk_ops_impl.h>
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 namespace Botan {
 
 namespace {
@@ -62,21 +58,6 @@ ECDH_PrivateKey::create_key_agreement_op(RandomNumberGenerator& rng,
                                          const std::string& params,
                                          const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      try
-         {
-         return make_openssl_ecdh_ka_op(*this, params);
-         }
-      catch(Lookup_Error&)
-         {
-         if(provider == "openssl")
-            throw;
-         }
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Key_Agreement>(new ECDH_KA_Operation(*this, params, rng));
 
diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp
index ebe9268cc..54a9adc85 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.cpp
+++ b/src/lib/pubkey/ecdsa/ecdsa.cpp
@@ -19,10 +19,6 @@
   #include <botan/rfc6979.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 namespace Botan {
 
 namespace {
@@ -258,21 +254,6 @@ std::unique_ptr<PK_Ops::Verification>
 ECDSA_PublicKey::create_verification_op(const std::string& params,
                                         const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      try
-         {
-         return make_openssl_ecdsa_ver_op(*this, params);
-         }
-      catch(Lookup_Error& e)
-         {
-         if(provider == "openssl")
-            throw;
-         }
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Verification>(new ECDSA_Verification_Operation(*this, params));
 
@@ -284,21 +265,6 @@ ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng,
                                       const std::string& params,
                                       const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      try
-         {
-         return make_openssl_ecdsa_sig_op(*this, params);
-         }
-      catch(Lookup_Error& e)
-         {
-         if(provider == "openssl")
-            throw;
-         }
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Signature>(new ECDSA_Signature_Operation(*this, params, rng));
 
diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp
index fc8697585..3577d4f06 100644
--- a/src/lib/pubkey/pk_algs.cpp
+++ b/src/lib/pubkey/pk_algs.cpp
@@ -72,10 +72,6 @@
   #include <botan/sm2.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 namespace Botan {
 
 std::unique_ptr<Public_Key>
@@ -279,17 +275,6 @@ create_private_key(const std::string& alg_name,
    if(alg_name == "RSA")
       {
       const size_t rsa_bits = (params.empty() ? 3072 : to_u32bit(params));
-#if defined(BOTAN_HAS_OPENSSL)
-      if(provider.empty() || provider == "openssl")
-         {
-         std::unique_ptr<Botan::Private_Key> pk;
-         if((pk = make_openssl_rsa_private_key(rng, rsa_bits)))
-            return pk;
-
-         if(!provider.empty())
-            return nullptr;
-         }
-#endif
       return std::unique_ptr<Private_Key>(new RSA_PrivateKey(rng, rsa_bits));
       }
 #endif
@@ -409,11 +394,7 @@ probe_provider_private_key(const std::string& alg_name,
    std::vector<std::string> providers;
    for(auto&& prov : possible)
       {
-      if(prov == "base" ||
-#if defined(BOTAN_HAS_OPENSSL)
-         (prov == "openssl" && alg_name == "RSA") ||
-#endif
-         0)
+      if(prov == "base")
          {
          providers.push_back(prov); // available
          }
diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp
index 96f405892..43e4b052d 100644
--- a/src/lib/pubkey/rsa/rsa.cpp
+++ b/src/lib/pubkey/rsa/rsa.cpp
@@ -17,10 +17,6 @@
 #include <botan/divide.h>
 #include <botan/internal/monty_exp.h>
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 #if defined(BOTAN_HAS_THREAD_UTILS)
   #include <botan/internal/thread_pool.h>
 #endif
@@ -639,26 +635,6 @@ RSA_PublicKey::create_encryption_op(RandomNumberGenerator& /*rng*/,
                                     const std::string& params,
                                     const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      try
-         {
-         return make_openssl_rsa_enc_op(*this, params);
-         }
-      catch(Exception& e)
-         {
-         /*
-         * If OpenSSL for some reason could not handle this (eg due to OAEP params),
-         * throw if openssl was specifically requested but otherwise just fall back
-         * to the normal version.
-         */
-         if(provider == "openssl")
-            throw Lookup_Error("OpenSSL RSA provider rejected key:" + std::string(e.what()));
-         }
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Encryption>(new RSA_Encryption_Operation(*this, params));
    throw Provider_Not_Found(algo_name(), provider);
@@ -678,15 +654,6 @@ std::unique_ptr<PK_Ops::Verification>
 RSA_PublicKey::create_verification_op(const std::string& params,
                                       const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      std::unique_ptr<PK_Ops::Verification> res = make_openssl_rsa_ver_op(*this, params);
-      if(res)
-         return res;
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Verification>(new RSA_Verify_Operation(*this, params));
 
@@ -698,21 +665,6 @@ RSA_PrivateKey::create_decryption_op(RandomNumberGenerator& rng,
                                      const std::string& params,
                                      const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      try
-         {
-         return make_openssl_rsa_dec_op(*this, params);
-         }
-      catch(Exception& e)
-         {
-         if(provider == "openssl")
-            throw Lookup_Error("OpenSSL RSA provider rejected key:" + std::string(e.what()));
-         }
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Decryption>(new RSA_Decryption_Operation(*this, params, rng));
 
@@ -735,15 +687,6 @@ RSA_PrivateKey::create_signature_op(RandomNumberGenerator& rng,
                                     const std::string& params,
                                     const std::string& provider) const
    {
-#if defined(BOTAN_HAS_OPENSSL)
-   if(provider == "openssl" || provider.empty())
-      {
-      std::unique_ptr<PK_Ops::Signature> res = make_openssl_rsa_sig_op(*this, params);
-      if(res)
-         return res;
-      }
-#endif
-
    if(provider == "base" || provider.empty())
       return std::unique_ptr<PK_Ops::Signature>(new RSA_Signature_Operation(*this, params, rng));
 
diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp
index 340682ce2..0ce62634f 100644
--- a/src/lib/stream/stream_cipher.cpp
+++ b/src/lib/stream/stream_cipher.cpp
@@ -33,10 +33,6 @@
   #include <botan/rc4.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 namespace Botan {
 
 std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec,
@@ -108,13 +104,6 @@ std::unique_ptr<StreamCipher> StreamCipher::create(const std::string& algo_spec,
       {
       const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
 
-#if defined(BOTAN_HAS_OPENSSL)
-      if(provider.empty() || provider == "openssl")
-         {
-         return std::unique_ptr<StreamCipher>(make_openssl_rc4(skip));
-         }
-#endif
-
       if(provider.empty() || provider == "base")
          {
          return std::unique_ptr<StreamCipher>(new RC4(skip));
@@ -143,7 +132,7 @@ StreamCipher::create_or_throw(const std::string& algo,
 
 std::vector<std::string> StreamCipher::providers(const std::string& algo_spec)
    {
-   return probe_providers_of<StreamCipher>(algo_spec, {"base", "openssl"});
+   return probe_providers_of<StreamCipher>(algo_spec, {"base"});
    }
 
 }
diff --git a/src/scripts/ci/lgtm.yml b/src/scripts/ci/lgtm.yml
index fa2423858..a7f4fcaf9 100644
--- a/src/scripts/ci/lgtm.yml
+++ b/src/scripts/ci/lgtm.yml
@@ -28,4 +28,4 @@ extraction:
   cpp:
     configure:
       command:
-        - ./configure.py --build-targets="static,shared,cli,tests,bogo_shim" --build-fuzzers=test --with-zlib --with-bzip2 --with-lzma --with-openssl --with-sqlite3 --no-store-vc-rev
+        - ./configure.py --build-targets="static,shared,cli,tests,bogo_shim" --build-fuzzers=test --with-zlib --with-bzip2 --with-lzma --with-sqlite3 --no-store-vc-rev
diff --git a/src/scripts/ci_build.py b/src/scripts/ci_build.py
index 97a3f66e5..b600d6b2b 100755
--- a/src/scripts/ci_build.py
+++ b/src/scripts/ci_build.py
@@ -255,12 +255,6 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin,
         if target_os == 'linux':
             flags += ['--with-lzma']
 
-        if target_os == 'linux':
-            if target not in ['sanitizer', 'valgrind', 'minimized']:
-                # Avoid OpenSSL when using dynamic checkers, or on OS X where it sporadically
-                # is not installed on the CI image
-                flags += ['--with-openssl']
-
         if target in ['coverage']:
             flags += ['--with-tpm']
             test_cmd += ['--run-online-tests']


Test patch:
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index 6f511bcf2..a2d65b05d 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -14,10 +14,6 @@
 
 #include <botan/version.h>
 
-#if defined(BOTAN_HAS_OPENSSL)
-   #include <botan/internal/openssl.h>
-#endif
-
 namespace {
 
 std::string help_text(const std::string& spec)
@@ -100,26 +96,9 @@ int main(int argc, char* argv[])
          parser.flag_set("run-long-tests"),
          parser.flag_set("abort-on-first-fail"));
 
-#if defined(BOTAN_HAS_OPENSSL)
-      if(opts.provider().empty() || opts.provider() == "openssl")
-         {
-         ::ERR_load_crypto_strings();
-         }
-#endif
-
       Botan_Tests::Test_Runner tests(std::cout);
 
-      int rc = tests.run(opts);
-
-#if defined(BOTAN_HAS_OPENSSL) && defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER < 0x01010000)
-      if(opts.provider().empty() || opts.provider() == "openssl")
-         {
-         ERR_free_strings();
-         ::ERR_remove_thread_state(nullptr);
-         }
-#endif
-
-      return rc;
+      return tests.run(opts);
       }
    catch(std::exception& e)
       {