Repository: randombit/botan
Pull request #2827 (2021-10-23 18:40:10)

Remove the OpenSSL provider
Starting in OpenSSL 3.0, most of the functionality which we need to implement the OpenSSL provider is deprecated. Rather than reimplement the whole provider in order to allow it to continue to work in the future, just remove it. Efforts would be better spent doing more optimization work rather than chasing OpenSSL's API changes.



Patch:
diff --git a/configure.py b/configure.py
index 9b0255625..7e40af668 100755
--- a/configure.py
+++ b/configure.py
@@ -563,7 +563,7 @@ def process_command_line(args): # pylint: disable=too-many-locals,too-many-state
                           help='minimize build')
 
     # Should be derived from info.txt but this runs too early
-    third_party = ['boost', 'bzip2', 'lzma', 'openssl', 'commoncrypto', 'sqlite3', 'zlib', 'tpm']
+    third_party = ['boost', 'bzip2', 'lzma', 'commoncrypto', 'sqlite3', 'zlib', 'tpm']
 
     for mod in third_party:
         mods_group.add_option('--with-%s' % (mod),
diff --git a/doc/api_ref/threads.rst b/doc/api_ref/threads.rst
new file mode 100644
index 000000000..9ed9ad6d3
--- /dev/null
+++ b/doc/api_ref/threads.rst
@@ -0,0 +1,3 @@
+Multithreading Notes
+======================
+
diff --git a/doc/building.rst b/doc/building.rst
index 667b9354c..ec9653698 100644
--- a/doc/building.rst
+++ b/doc/building.rst
@@ -60,7 +60,7 @@ we might see lines like::
    INFO: Skipping (incompatible OS): darwin_secrandom getentropy win32_stats
    INFO: Skipping (incompatible compiler): aes_armv8 pmull sha1_armv8 sha2_32_armv8
    INFO: Skipping (no enabled compression schemes): compression
-   INFO: Skipping (requires external dependency): boost bzip2 lzma openssl sqlite3 tpm zlib
+   INFO: Skipping (requires external dependency): boost bzip2 lzma sqlite3 tpm zlib
 
 The ones that are skipped because they are require an external
 dependency have to be explicitly asked for, because they rely on third
@@ -356,10 +356,6 @@ by the user using
  - ``--with-sqlite3`` enables using sqlite3 databases in various contexts
    (TLS session cache, PSK database, etc).
 
- - ``--with-openssl`` adds an engine that uses OpenSSL for some ciphers, hashes,
-   and public key operations. OpenSSL 1.0.2 or later is supported. LibreSSL can
-   also be used.
-
  - ``--with-tpm`` adds support for using TPM hardware via the TrouSerS library.
 
  - ``--with-boost`` enables using some Boost libraries. In particular
@@ -960,11 +956,6 @@ Enable lzma compression
 
 Enable using zlib compression
 
-``--with-openssl``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Enable using OpenSSL for certain operations
-
 ``--with-commoncrypto``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/doc/dev_ref/contributing.rst b/doc/dev_ref/contributing.rst
index d29161c8e..098297676 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 such as 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,11 @@ 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 several
+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 7ab2fe732..fa531329a 100644
--- a/doc/dev_ref/todo.rst
+++ b/doc/dev_ref/todo.rst
@@ -75,8 +75,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..3d3c13840 100644
--- a/doc/packaging.rst
+++ b/doc/packaging.rst
@@ -12,11 +12,6 @@ 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.
-
 Set Path to the System CA bundle
 ---------------------------------
 
diff --git a/doc/side_channels.rst b/doc/side_channels.rst
index 0448e1497..c394e5633 100644
--- a/doc/side_channels.rst
+++ b/doc/side_channels.rst
@@ -80,9 +80,6 @@ inversions are combined using the CRT. This process does leak the value of
 
 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 8c47d6a65..09df412d2 100644
--- a/src/lib/block/block_cipher.cpp
+++ b/src/lib/block/block_cipher.cpp
@@ -77,10 +77,6 @@
   #include <botan/internal/threefish_512.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 #if defined(BOTAN_HAS_COMMONCRYPTO)
   #include <botan/internal/commoncrypto.h>
 #endif
@@ -102,17 +98,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
 
@@ -307,7 +292,7 @@ BlockCipher::create_or_throw(const std::string& algo,
 
 std::vector<std::string> BlockCipher::providers(const std::string& algo)
    {
-   return probe_providers_of<BlockCipher>(algo, { "base", "openssl", "commoncrypto" });
+   return probe_providers_of<BlockCipher>(algo, { "base", "commoncrypto" });
    }
 
 }
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index eb7342aa8..1a6ce5e55 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -41,7 +41,6 @@ int ffi_map_error_type(Botan::ErrorType err)
 
       case Botan::ErrorType::SystemError:
       case Botan::ErrorType::IoError:
-      case Botan::ErrorType::OpenSSLError:
       case Botan::ErrorType::Pkcs11Error:
       case Botan::ErrorType::CommonCryptoError:
       case Botan::ErrorType::TPMError:
diff --git a/src/lib/hash/hash.cpp b/src/lib/hash/hash.cpp
index 4b681bcc8..194535ff6 100644
--- a/src/lib/hash/hash.cpp
+++ b/src/lib/hash/hash.cpp
@@ -89,10 +89,6 @@
   #include <botan/internal/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
@@ -114,17 +110,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
 
@@ -336,7 +321,7 @@ HashFunction::create_or_throw(const std::string& algo,
 
 std::vector<std::string> HashFunction::providers(const std::string& algo_spec)
    {
-   return probe_providers_of<HashFunction>(algo_spec, {"base", "openssl", "commoncrypto"});
+   return probe_providers_of<HashFunction>(algo_spec, {"base", "commoncrypto"});
    }
 
 }
diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp
index 08f96de7c..9ea30004d 100644
--- a/src/lib/kdf/kdf.cpp
+++ b/src/lib/kdf/kdf.cpp
@@ -221,7 +221,7 @@ KDF::create_or_throw(const std::string& algo,
 
 std::vector<std::string> KDF::providers(const std::string& algo_spec)
    {
-   return probe_providers_of<KDF>(algo_spec, { "base" });
+   return probe_providers_of<KDF>(algo_spec);
    }
 
 }
diff --git a/src/lib/mac/mac.cpp b/src/lib/mac/mac.cpp
index e87380a67..55814a9b7 100644
--- a/src/lib/mac/mac.cpp
+++ b/src/lib/mac/mac.cpp
@@ -69,7 +69,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 hash = HashFunction::create(req.arg(0)))
@@ -99,7 +98,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)))
@@ -128,7 +126,7 @@ MessageAuthenticationCode::create(const std::string& algo_spec,
 std::vector<std::string>
 MessageAuthenticationCode::providers(const std::string& algo_spec)
    {
-   return probe_providers_of<MessageAuthenticationCode>(algo_spec, {"base", "openssl"});
+   return probe_providers_of<MessageAuthenticationCode>(algo_spec);
    }
 
 //static
diff --git a/src/lib/modes/cipher_mode.cpp b/src/lib/modes/cipher_mode.cpp
index b3fe5e86a..79b297c37 100644
--- a/src/lib/modes/cipher_mode.cpp
+++ b/src/lib/modes/cipher_mode.cpp
@@ -31,10 +31,6 @@
   #include <botan/internal/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))
       {
@@ -188,7 +171,7 @@ std::unique_ptr<Cipher_Mode> Cipher_Mode::create(const std::string& algo,
 //static
 std::vector<std::string> Cipher_Mode::providers(const std::string& algo_spec)
    {
-   const std::vector<std::string>& possible = { "base", "openssl", "commoncrypto" };
+   const std::vector<std::string>& possible = { "base", "commoncrypto" };
    std::vector<std::string> providers;
    for(auto&& prov : possible)
       {
diff --git a/src/lib/pbkdf/pbkdf.cpp b/src/lib/pbkdf/pbkdf.cpp
index e80f46cfe..5c668d6b8 100644
--- a/src/lib/pbkdf/pbkdf.cpp
+++ b/src/lib/pbkdf/pbkdf.cpp
@@ -70,7 +70,7 @@ PBKDF::create_or_throw(const std::string& algo,
 
 std::vector<std::string> PBKDF::providers(const std::string& algo_spec)
    {
-   return probe_providers_of<PBKDF>(algo_spec, { "base", "openssl" });
+   return probe_providers_of<PBKDF>(algo_spec);
    }
 
 void PBKDF::pbkdf_timed(uint8_t out[], size_t out_len,
diff --git a/src/lib/pbkdf/pwdhash.cpp b/src/lib/pbkdf/pwdhash.cpp
index 27ec699bb..a7911547e 100644
--- a/src/lib/pbkdf/pwdhash.cpp
+++ b/src/lib/pbkdf/pwdhash.cpp
@@ -54,8 +54,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("HMAC(" + req.arg(0) + ")"))
@@ -128,7 +126,7 @@ PasswordHashFamily::create_or_throw(const std::string& algo,
 
 std::vector<std::string> PasswordHashFamily::providers(const std::string& algo_spec)
    {
-   return probe_providers_of<PasswordHashFamily>(algo_spec, { "base", "openssl" });
+   return probe_providers_of<PasswordHashFamily>(algo_spec);
    }
 
 }
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 20cd44159..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, unsigned long 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 static_cast<int>(m_err); }
-
-   private:
-      unsigned long m_err;
-   };
-
-/* Block Ciphers */
-
-std::unique_ptr<BlockCipher>
-make_openssl_block_cipher(const std::string& name);
-
-/* Cipher Modes */
-
-std::unique_ptr<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 7b5022b7b..000000000
--- a/src/lib/prov/openssl/openssl_block.cpp
+++ /dev/null
@@ -1,241 +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/safeint.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; }
-      std::unique_ptr<BlockCipher> new_object() 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;
-         const size_t total_bytes = blocks * m_block_sz;
-         const int itotal_bytes = checked_cast_to<int>(total_bytes);
-         if(!EVP_EncryptUpdate(m_encrypt, out, &out_len, in, itotal_bytes))
-            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;
-         const size_t total_bytes = blocks * m_block_sz;
-         const int itotal_bytes = checked_cast_to<int>(total_bytes);
-         if(!EVP_DecryptUpdate(m_decrypt, out, &out_len, in, itotal_bytes))
-            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
-      {
-      const int ilength = checked_cast_to<int>(length);
-      if(EVP_CIPHER_CTX_set_key_length(m_encrypt, ilength) == 0 ||
-         EVP_CIPHER_CTX_set_key_length(m_decrypt, ilength) == 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
-*/
-std::unique_ptr<BlockCipher> OpenSSL_BlockCipher::new_object() const
-   {
-   return std::make_unique<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::make_unique<OpenSSL_BlockCipher>(name, evp_fn())
-#define MAKE_OPENSSL_BLOCK_KEYLEN(evp_fn, kl_min, kl_max, kl_mod)       \
-   std::make_unique<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 88004ebe0..000000000
--- a/src/lib/prov/openssl/openssl_ec.cpp
+++ /dev/null
@@ -1,378 +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_sequence()
-        .encode(static_cast<size_t>(1))
-        .encode(BigInt::encode_1363(priv_key, priv_key.bytes()), ASN1_Type::OctetString)
-      .start_explicit_context_specific(0)
-        .raw_bytes(ec.domain().DER_encode(EC_Group_Encoding::NamedCurve))
-      .end_cons()
-      .start_explicit_context_specific(1)
-        .encode(pub_key.encode(PointGFp::UNCOMPRESSED), ASN1_Type::BitString)
-      .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());
-
-         BIGNUM* r = BN_bin2bn(sig_bytes              , static_cast<int>(sig_len / 2), nullptr);
-         BIGNUM* s = BN_bin2bn(sig_bytes + sig_len / 2, static_cast<int>(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);
-
-         const int res = ECDSA_do_verify(msg, static_cast<int>(msg_len), sig.get(), m_ossl_ec.get());
-         if(res < 0)
-            {
-            auto 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, static_cast<int>(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::make_unique<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::make_unique<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::make_unique<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 32ba318eb..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; }
-
-      std::unique_ptr<HashFunction> new_object() const override
-         {
-         const EVP_MD* algo = EVP_MD_CTX_md(m_md);
-         return std::make_unique<OpenSSL_HashFunction>(name(), algo);
-         }
-
-      std::unique_ptr<HashFunction> copy_state() const override
-         {
-         auto copy = std::make_unique<OpenSSL_HashFunction>(m_name, nullptr);
-         EVP_MD_CTX_copy(copy->m_md, m_md);
-         return copy;
-         }
-
-      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::make_unique<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 eed6670aa..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 = static_cast<int>(msg_len);
-   secure_vector<uint8_t> out(outl);
-
-   if(!EVP_CipherUpdate(m_cipher, out.data(), &outl, msg, outl))
-      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 = static_cast<int>(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, static_cast<int>(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;
-   }
-
-}
-
-std::unique_ptr<Cipher_Mode>
-make_openssl_cipher_mode(const std::string& name, Cipher_Dir direction)
-   {
-#define MAKE_OPENSSL_MODE(evp_fn) \
-   std::make_unique<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 8a09f6bfc..000000000
--- a/src/lib/prov/openssl/openssl_rc4.cpp
+++ /dev/null
@@ -1,96 +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/internal/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) + ")";
-            }
-         }
-
-      std::unique_ptr<StreamCipher> new_object() const override
-         {
-         return std::make_unique<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, static_cast<int>(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::make_unique<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 4fc9b15b9..000000000
--- a/src/lib/prov/openssl/openssl_rsa.cpp
+++ /dev/null
@@ -1,316 +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(static_cast<int>(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(static_cast<int>(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, true),
-         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(static_cast<int>(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, true),
-         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(static_cast<int>(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::make_unique<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::make_unique<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::make_unique<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(128);
-   rng.randomize(seed.data(), seed.size());
-   RAND_seed(seed.data(), static_cast<int>(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(), static_cast<int>(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 6775a2545..585bc4a87 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 {
 
 std::unique_ptr<Public_Key> ECDH_PrivateKey::public_key() const
@@ -67,21 +63,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::make_unique<ECDH_KA_Operation>(*this, params, rng);
 
diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp
index 2c81fa3ad..9b17b183e 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.cpp
+++ b/src/lib/pubkey/ecdsa/ecdsa.cpp
@@ -19,10 +19,6 @@
   #include <botan/internal/rfc6979.h>
 #endif
 
-#if defined(BOTAN_HAS_OPENSSL)
-  #include <botan/internal/openssl.h>
-#endif
-
 namespace Botan {
 
 namespace {
@@ -272,21 +268,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::make_unique<ECDSA_Verification_Operation>(*this, params);
 
@@ -298,21 +279,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::make_unique<ECDSA_Signature_Operation>(*this, params, rng);
 
diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp
index f1f6c5974..eec6a147c 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>
@@ -318,16 +314,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")
-         {
-         auto pk = make_openssl_rsa_private_key(rng, rsa_bits);
-
-         // Return nullptr if openssl was specifically requested
-         if(pk || !provider.empty())
-            return pk;
-         }
-#endif
       return std::make_unique<RSA_PrivateKey>(rng, rsa_bits);
       }
 #endif
@@ -420,11 +406,6 @@ probe_provider_private_key(const std::string& alg_name,
       {
       if(prov == "base")
          providers.push_back(prov);
-
-#if defined(BOTAN_HAS_OPENSSL)
-      if(prov == "openssl" && alg_name == "RSA")
-         providers.push_back(prov);
-#endif
       }
 
    BOTAN_UNUSED(alg_name);
diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp
index b551a33c8..32979acc9 100644
--- a/src/lib/pubkey/rsa/rsa.cpp
+++ b/src/lib/pubkey/rsa/rsa.cpp
@@ -17,10 +17,6 @@
 #include <botan/internal/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
@@ -655,26 +651,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::make_unique<RSA_Encryption_Operation>(*this, params);
    throw Provider_Not_Found(algo_name(), provider);
@@ -694,15 +670,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::make_unique<RSA_Verify_Operation>(*this, params);
 
@@ -714,21 +681,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::make_unique<RSA_Decryption_Operation>(*this, params, rng);
 
@@ -751,15 +703,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::make_unique<RSA_Signature_Operation>(*this, params, rng);
 
diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp
index ce463181e..227627e73 100644
--- a/src/lib/stream/stream_cipher.cpp
+++ b/src/lib/stream/stream_cipher.cpp
@@ -33,10 +33,6 @@
   #include <botan/internal/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::make_unique<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);
    }
 
 }
diff --git a/src/lib/stream/stream_cipher.h b/src/lib/stream/stream_cipher.h
index 497d89943..f13397818 100644
--- a/src/lib/stream/stream_cipher.h
+++ b/src/lib/stream/stream_cipher.h
@@ -145,7 +145,7 @@ class BOTAN_PUBLIC_API(2,0) StreamCipher : public SymmetricAlgorithm
 
       /**
       * @return provider information about this implementation. Default is "base",
-      * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
+      * might also return "sse2", "avx2" or some other arbitrary string.
       */
       virtual std::string provider() const { return "base"; }
    };
diff --git a/src/lib/utils/exceptn.cpp b/src/lib/utils/exceptn.cpp
index 56c70daaa..6b5b5d385 100644
--- a/src/lib/utils/exceptn.cpp
+++ b/src/lib/utils/exceptn.cpp
@@ -48,8 +48,6 @@ std::string to_string(ErrorType type)
          return "InvalidTag";
       case ErrorType::RoughtimeError:
          return "RoughtimeError";
-      case ErrorType::OpenSSLError :
-         return "OpenSSLError";
       case ErrorType::CommonCryptoError:
          return "CommonCryptoError";
       case ErrorType::Pkcs11Error:
diff --git a/src/lib/utils/exceptn.h b/src/lib/utils/exceptn.h
index beb52cab8..30fce9427 100644
--- a/src/lib/utils/exceptn.h
+++ b/src/lib/utils/exceptn.h
@@ -56,10 +56,8 @@ enum class ErrorType {
    /** An error during Roughtime validation */
    RoughtimeError,
 
-   /** An error when calling OpenSSL */
-   OpenSSLError = 200,
    /** An error when interacting with CommonCrypto API */
-   CommonCryptoError,
+   CommonCryptoError = 201,
    /** An error when interacting with a PKCS11 device */
    Pkcs11Error,
    /** An error when interacting with a TPM device */
@@ -105,9 +103,7 @@ class BOTAN_PUBLIC_API(2,0) Exception : public std::exception
       *
       * The domain of this error varies depending on the source, for example on
       * POSIX systems it might be errno, while on a Windows system it might be
-      * the result of GetLastError or WSAGetLastError. For error_type() is
-      * OpenSSLError, it will (if nonzero) be an OpenSSL error code from
-      * ERR_get_error.
+      * the result of GetLastError or WSAGetLastError.
       */
       virtual int error_code() const noexcept { return 0; }
 
diff --git a/src/lib/utils/scan_name.h b/src/lib/utils/scan_name.h
index f1868c6da..7135a0eb3 100644
--- a/src/lib/utils/scan_name.h
+++ b/src/lib/utils/scan_name.h
@@ -104,7 +104,7 @@ class SCAN_Name final
 // This is unrelated but it is convenient to stash it here
 template<typename T>
 std::vector<std::string> probe_providers_of(const std::string& algo_spec,
-                                            const std::vector<std::string>& possible)
+                                            const std::vector<std::string>& possible = { "base" })
    {
    std::vector<std::string> providers;
    for(auto&& prov : possible)
diff --git a/src/scripts/ci/lgtm.yml b/src/scripts/ci/lgtm.yml
index c1111e40f..f88f9d409 100644
--- a/src/scripts/ci/lgtm.yml
+++ b/src/scripts/ci/lgtm.yml
@@ -30,4 +30,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 --without-documentation
+        - ./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 --without-documentation
diff --git a/src/scripts/ci_build.py b/src/scripts/ci_build.py
index 9e99f2d1a..04303980e 100755
--- a/src/scripts/ci_build.py
+++ b/src/scripts/ci_build.py
@@ -250,12 +250,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)
       {