Repository: randombit/botan
Pull request #2697 (2021-04-04 23:53:22)

More raw pointer removal

codecov-io: # [Codecov](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=h1) Report
> Merging [#2697](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=desc) (f354ace) into [master](https://codecov.io/gh/randombit/botan/commit/262681832f7b58287b17a3d33754f5dc4699b660?el=desc) (2626818) will **increase** coverage by `0.01%`.
> The diff coverage is `87.64%`.

[![Impacted file tree graph](https://codecov.io/gh/randombit/botan/pull/2697/graphs/tree.svg?width=650&height=150&src=pr&token=VR6iYmSPH8)](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #2697      +/-   ##
==========================================
+ Coverage   92.38%   92.40%   +0.01%     
==========================================
  Files         564      564              
  Lines       62730    62722       -8     
  Branches     6143     6141       -2     
==========================================
+ Hits        57953    57956       +3     
+ Misses       4745     4734      -11     
  Partials       32       32              
```


| [Impacted Files](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/lib/pk\_pad/emsa\_pssr/pssr.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wa19wYWQvZW1zYV9wc3NyL3Bzc3IuY3Bw) | `93.70% <0.00%> (ø)` | |
| [src/lib/pk\_pad/iso9796/iso9796.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wa19wYWQvaXNvOTc5Ni9pc285Nzk2LmNwcA==) | `95.41% <0.00%> (ø)` | |
| [src/lib/prov/tpm/tpm.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wcm92L3RwbS90cG0uY3Bw) | `5.26% <0.00%> (ø)` | |
| [src/lib/utils/os\_utils.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi91dGlscy9vc191dGlscy5jcHA=) | `65.66% <0.00%> (ø)` | |
| [src/tests/test\_ecdsa.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL3Rlc3RzL3Rlc3RfZWNkc2EuY3Bw) | `97.89% <ø> (ø)` | |
| [src/lib/entropy/entropy\_srcs.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9lbnRyb3B5L2VudHJvcHlfc3Jjcy5jcHA=) | `100.00% <100.00%> (ø)` | |
| [src/lib/pbkdf/pbkdf2/pbkdf2.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wYmtkZi9wYmtkZjIvcGJrZGYyLmNwcA==) | `85.88% <100.00%> (+0.16%)` | :arrow_up: |
| [src/lib/pk\_pad/eme.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wa19wYWQvZW1lLmNwcA==) | `88.00% <100.00%> (ø)` | |
| [src/lib/pk\_pad/emsa.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wa19wYWQvZW1zYS5jcHA=) | `97.22% <100.00%> (+0.20%)` | :arrow_up: |
| [src/lib/pk\_pad/emsa1/emsa1.cpp](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree#diff-c3JjL2xpYi9wa19wYWQvZW1zYTEvZW1zYTEuY3Bw) | `90.74% <100.00%> (ø)` | |
| ... and [27 more](https://codecov.io/gh/randombit/botan/pull/2697/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=footer). Last update [2626818...f354ace](https://codecov.io/gh/randombit/botan/pull/2697?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp
index 8eadfd9c2..46b025ef2 100644
--- a/src/lib/entropy/entropy_srcs.cpp
+++ b/src/lib/entropy/entropy_srcs.cpp
@@ -92,7 +92,7 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
 #if defined(BOTAN_HAS_SYSTEM_RNG)
    if(name == "system_rng")
       {
-      return std::unique_ptr<Entropy_Source>(new System_RNG_EntropySource);
+      return std::make_unique<System_RNG_EntropySource>();
       }
 #endif
 
@@ -101,7 +101,7 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
       {
       if(Processor_RNG::available())
          {
-         return std::unique_ptr<Entropy_Source>(new Processor_RNG_EntropySource);
+         return std::make_unique<Processor_RNG_EntropySource>();
          }
       }
 #endif
@@ -109,26 +109,26 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
 #if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
    if(name == "rdseed")
       {
-      return std::unique_ptr<Entropy_Source>(new Intel_Rdseed);
+      return std::make_unique<Intel_Rdseed>();
       }
 #endif
 
 #if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
    if(name == "getentropy")
       {
-      return std::unique_ptr<Entropy_Source>(new Getentropy);
+      return std::make_unique<Getentropy>();
       }
 #endif
 
 #if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
    if(name == "system_stats")
       {
-      return std::unique_ptr<Entropy_Source>(new Win32_EntropySource);
+      return std::make_unique<Win32_EntropySource>();
       }
 #endif
 
    BOTAN_UNUSED(name);
-   return std::unique_ptr<Entropy_Source>();
+   return nullptr;
    }
 
 void Entropy_Sources::add_source(std::unique_ptr<Entropy_Source> src)
diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
index 1b3c0be5c..51dfa2fdd 100644
--- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
+++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
@@ -182,7 +182,7 @@ PBKDF* PKCS5_PBKDF2::clone() const
 // PasswordHash interface
 
 PBKDF2::PBKDF2(const MessageAuthenticationCode& prf, size_t olen, std::chrono::milliseconds msec) :
-   m_prf(prf.clone()),
+   m_prf(prf.new_object()),
    m_iterations(tune_pbkdf2(*m_prf, olen, static_cast<uint32_t>(msec.count())))
    {}
 
diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.h b/src/lib/pbkdf/pbkdf2/pbkdf2.h
index 9f90799c4..bea5893f3 100644
--- a/src/lib/pbkdf/pbkdf2/pbkdf2.h
+++ b/src/lib/pbkdf/pbkdf2/pbkdf2.h
@@ -40,7 +40,7 @@ class BOTAN_PUBLIC_API(2,8) PBKDF2 final : public PasswordHash
    {
    public:
       PBKDF2(const MessageAuthenticationCode& prf, size_t iter) :
-         m_prf(prf.clone()),
+         m_prf(prf.new_object()),
          m_iterations(iter)
          {}
 
diff --git a/src/lib/pk_pad/eme.cpp b/src/lib/pk_pad/eme.cpp
index 042db3fab..d30cd11f8 100644
--- a/src/lib/pk_pad/eme.cpp
+++ b/src/lib/pk_pad/eme.cpp
@@ -24,16 +24,16 @@
 
 namespace Botan {
 
-EME* get_eme(const std::string& algo_spec)
+std::unique_ptr<EME> EME::create(const std::string& algo_spec)
    {
 #if defined(BOTAN_HAS_EME_RAW)
    if(algo_spec == "Raw")
-      return new EME_Raw;
+      return std::make_unique<EME_Raw>();
 #endif
 
 #if defined(BOTAN_HAS_EME_PKCS1)
    if(algo_spec == "PKCS1v15" || algo_spec == "EME-PKCS1-v1_5")
-      return new EME_PKCS1v15;
+      return std::make_unique<EME_PKCS1v15>();
 #endif
 
 #if defined(BOTAN_HAS_EME_OAEP)
@@ -47,7 +47,7 @@ EME* get_eme(const std::string& algo_spec)
          ((req.arg_count() == 2 || req.arg_count() == 3) && req.arg(1) == "MGF1"))
          {
          if(auto hash = HashFunction::create(req.arg(0)))
-            return new OAEP(hash.release(), req.arg(2, ""));
+            return std::make_unique<OAEP>(hash.release(), req.arg(2, ""));
          }
       else if(req.arg_count() == 2 || req.arg_count() == 3)
          {
@@ -60,7 +60,7 @@ EME* get_eme(const std::string& algo_spec)
 
             if(hash && mgf1_hash)
                {
-               return new OAEP(hash.release(), mgf1_hash.release(), req.arg(2, ""));
+               return std::make_unique<OAEP>(hash.release(), mgf1_hash.release(), req.arg(2, ""));
                }
             }
          }
diff --git a/src/lib/pk_pad/eme.h b/src/lib/pk_pad/eme.h
index c21dfde45..c913492a9 100644
--- a/src/lib/pk_pad/eme.h
+++ b/src/lib/pk_pad/eme.h
@@ -23,6 +23,13 @@ class EME
    public:
       virtual ~EME() = default;
 
+      /**
+      * Factory method for EME (message-encoding methods for encryption) objects
+      * @param algo_spec the name of the EME to create
+      * @return pointer to newly allocated object of that type
+      */
+      static std::unique_ptr<EME> create(const std::string& algo_spec);
+
       /**
       * Return the maximum input size in bytes we can support
       * @param keybits the size of the key in bits
@@ -80,13 +87,6 @@ class EME
                                       RandomNumberGenerator& rng) const = 0;
    };
 
-/**
-* Factory method for EME (message-encoding methods for encryption) objects
-* @param algo_spec the name of the EME to create
-* @return pointer to newly allocated object of that type
-*/
-EME*  get_eme(const std::string& algo_spec);
-
 }
 
 #endif
diff --git a/src/lib/pk_pad/emsa.cpp b/src/lib/pk_pad/emsa.cpp
index 63a0488d9..25a954233 100644
--- a/src/lib/pk_pad/emsa.cpp
+++ b/src/lib/pk_pad/emsa.cpp
@@ -41,7 +41,7 @@ AlgorithmIdentifier EMSA::config_for_x509(const Private_Key&,
    throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects");
    }
 
-EMSA* get_emsa(const std::string& algo_spec)
+std::unique_ptr<EMSA> EMSA::create(const std::string& algo_spec)
    {
    SCAN_Name req(algo_spec);
 
@@ -49,7 +49,7 @@ EMSA* get_emsa(const std::string& algo_spec)
    if(req.algo_name() == "EMSA1" && req.arg_count() == 1)
       {
       if(auto hash = HashFunction::create(req.arg(0)))
-         return new EMSA1(hash.release());
+         return std::make_unique<EMSA1>(hash.release());
       }
 #endif
 
@@ -61,19 +61,19 @@ EMSA* get_emsa(const std::string& algo_spec)
       {
       if(req.arg_count() == 2 && req.arg(0) == "Raw")
          {
-         return new EMSA_PKCS1v15_Raw(req.arg(1));
+         return std::make_unique<EMSA_PKCS1v15_Raw>(req.arg(1));
          }
       else if(req.arg_count() == 1)
          {
          if(req.arg(0) == "Raw")
             {
-            return new EMSA_PKCS1v15_Raw;
+            return std::make_unique<EMSA_PKCS1v15_Raw>();
             }
          else
             {
             if(auto hash = HashFunction::create(req.arg(0)))
                {
-               return new EMSA_PKCS1v15(hash.release());
+               return std::make_unique<EMSA_PKCS1v15>(hash.release());
                }
             }
          }
@@ -91,11 +91,11 @@ EMSA* get_emsa(const std::string& algo_spec)
             if(req.arg_count() == 3)
                {
                const size_t salt_size = req.arg_as_integer(2, 0);
-               return new PSSR_Raw(h.release(), salt_size);
+               return std::make_unique<PSSR_Raw>(h.release(), salt_size);
                }
             else
                {
-               return new PSSR_Raw(h.release());
+               return std::make_unique<PSSR_Raw>(h.release());
                }
             }
          }
@@ -114,11 +114,11 @@ EMSA* get_emsa(const std::string& algo_spec)
             if(req.arg_count() == 3)
                {
                const size_t salt_size = req.arg_as_integer(2, 0);
-               return new PSSR(h.release(), salt_size);
+               return std::make_unique<PSSR>(h.release(), salt_size);
                }
             else
                {
-               return new PSSR(h.release());
+               return std::make_unique<PSSR>(h.release());
                }
             }
          }
@@ -134,7 +134,7 @@ EMSA* get_emsa(const std::string& algo_spec)
             {
             const size_t salt_size = req.arg_as_integer(2, h->output_length());
             const bool implicit = req.arg(1, "exp") == "imp";
-            return new ISO_9796_DS2(h.release(), implicit, salt_size);
+            return std::make_unique<ISO_9796_DS2>(h.release(), implicit, salt_size);
             }
          }
       }
@@ -146,7 +146,7 @@ EMSA* get_emsa(const std::string& algo_spec)
          if(auto h = HashFunction::create(req.arg(0)))
             {
             const bool implicit = req.arg(1, "exp") == "imp";
-            return new ISO_9796_DS3(h.release(), implicit);
+            return std::make_unique<ISO_9796_DS3>(h.release(), implicit);
             }
          }
       }
@@ -161,7 +161,7 @@ EMSA* get_emsa(const std::string& algo_spec)
          {
          if(auto hash = HashFunction::create(req.arg(0)))
             {
-            return new EMSA_X931(hash.release());
+            return std::make_unique<EMSA_X931>(hash.release());
             }
          }
       }
@@ -172,17 +172,25 @@ EMSA* get_emsa(const std::string& algo_spec)
       {
       if(req.arg_count() == 0)
          {
-         return new EMSA_Raw;
+         return std::make_unique<EMSA_Raw>();
          }
       else
          {
          auto hash = HashFunction::create(req.arg(0));
          if(hash)
-            return new EMSA_Raw(hash->output_length());
+            return std::make_unique<EMSA_Raw>(hash->output_length());
          }
       }
 #endif
 
+   return nullptr;
+   }
+
+std::unique_ptr<EMSA> EMSA::create_or_throw(const std::string& algo_spec)
+   {
+   auto emsa = EMSA::create(algo_spec);
+   if(emsa)
+      return emsa;
    throw Algorithm_Not_Found(algo_spec);
    }
 
diff --git a/src/lib/pk_pad/emsa.h b/src/lib/pk_pad/emsa.h
index c2e352325..5a8f0daec 100644
--- a/src/lib/pk_pad/emsa.h
+++ b/src/lib/pk_pad/emsa.h
@@ -22,11 +22,27 @@ class RandomNumberGenerator;
 *
 * Any way of encoding/padding signatures
 */
-class EMSA
+class BOTAN_TEST_API EMSA
    {
    public:
       virtual ~EMSA() = default;
 
+      /**
+      * Factory method for EMSA (message-encoding methods for signatures
+      * with appendix) objects
+      * @param algo_spec the name of the EMSA to create
+      * @return pointer to newly allocated object of that type, or nullptr
+      */
+      static std::unique_ptr<EMSA> create(const std::string& algo_spec);
+
+      /**
+      * Factory method for EMSA (message-encoding methods for signatures
+      * with appendix) objects
+      * @param algo_spec the name of the EMSA to create
+      * @return pointer to newly allocated object of that type, or throws
+      */
+      static std::unique_ptr<EMSA> create_or_throw(const std::string& algo_spec);
+
       /**
       * Add more data to the signature computation
       * @param input some data
@@ -75,7 +91,7 @@ class EMSA
       /**
       * @return a new object representing the same encoding method as *this
       */
-      virtual EMSA* clone() = 0;
+      virtual std::unique_ptr<EMSA> new_object() = 0;
 
       /**
       * @return the SCAN name of the encoding/padding scheme
diff --git a/src/lib/pk_pad/emsa1/emsa1.cpp b/src/lib/pk_pad/emsa1/emsa1.cpp
index 42228e8fd..706806152 100644
--- a/src/lib/pk_pad/emsa1/emsa1.cpp
+++ b/src/lib/pk_pad/emsa1/emsa1.cpp
@@ -48,9 +48,9 @@ std::string EMSA1::name() const
    return "EMSA1(" + m_hash->name() + ")";
    }
 
-EMSA* EMSA1::clone()
+std::unique_ptr<EMSA> EMSA1::new_object()
    {
-   return new EMSA1(m_hash->clone());
+   return std::make_unique<EMSA1>(m_hash->clone());
    }
 
 void EMSA1::update(const uint8_t input[], size_t length)
diff --git a/src/lib/pk_pad/emsa1/emsa1.h b/src/lib/pk_pad/emsa1/emsa1.h
index cf5068240..06ffea2e2 100644
--- a/src/lib/pk_pad/emsa1/emsa1.h
+++ b/src/lib/pk_pad/emsa1/emsa1.h
@@ -25,7 +25,7 @@ class EMSA1 final : public EMSA
       */
       explicit EMSA1(HashFunction* hash) : m_hash(hash) {}
 
-      EMSA* clone() override;
+      std::unique_ptr<EMSA> new_object() override;
 
       std::string name() const override;
 
diff --git a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h
index 7a9b169c4..1e582832e 100644
--- a/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h
+++ b/src/lib/pk_pad/emsa_pkcs1/emsa_pkcs1.h
@@ -26,7 +26,7 @@ class EMSA_PKCS1v15 final : public EMSA
       */
       explicit EMSA_PKCS1v15(HashFunction* hash);
 
-      EMSA* clone() override { return new EMSA_PKCS1v15(m_hash->clone()); }
+      std::unique_ptr<EMSA> new_object() override { return std::make_unique<EMSA_PKCS1v15>(m_hash->clone()); }
 
       void update(const uint8_t[], size_t) override;
 
@@ -56,7 +56,7 @@ class EMSA_PKCS1v15 final : public EMSA
 class EMSA_PKCS1v15_Raw final : public EMSA
    {
    public:
-      EMSA* clone() override { return new EMSA_PKCS1v15_Raw(); }
+      std::unique_ptr<EMSA> new_object() override { return std::make_unique<EMSA_PKCS1v15_Raw>(); }
 
       void update(const uint8_t[], size_t) override;
 
diff --git a/src/lib/pk_pad/emsa_pssr/pssr.cpp b/src/lib/pk_pad/emsa_pssr/pssr.cpp
index cf7312900..d9b2ec30b 100644
--- a/src/lib/pk_pad/emsa_pssr/pssr.cpp
+++ b/src/lib/pk_pad/emsa_pssr/pssr.cpp
@@ -179,9 +179,9 @@ bool PSSR::verify(const secure_vector<uint8_t>& coded,
    return ok;
    }
 
-EMSA* PSSR::clone()
+std::unique_ptr<EMSA> PSSR::new_object()
    {
-   return new PSSR(m_hash->clone(), m_salt_size);
+   return std::make_unique<PSSR>(m_hash->clone(), m_salt_size);
    }
 
 std::string PSSR::name() const
@@ -278,9 +278,9 @@ bool PSSR_Raw::verify(const secure_vector<uint8_t>& coded,
    return ok;
    }
 
-EMSA* PSSR_Raw::clone()
+std::unique_ptr<EMSA> PSSR_Raw::new_object()
    {
-   return new PSSR_Raw(m_hash->clone(), m_salt_size);
+   return std::make_unique<PSSR_Raw>(m_hash->clone(), m_salt_size);
    }
 
 std::string PSSR_Raw::name() const
diff --git a/src/lib/pk_pad/emsa_pssr/pssr.h b/src/lib/pk_pad/emsa_pssr/pssr.h
index a33cf42a0..9deec7c03 100644
--- a/src/lib/pk_pad/emsa_pssr/pssr.h
+++ b/src/lib/pk_pad/emsa_pssr/pssr.h
@@ -31,7 +31,7 @@ class PSSR final : public EMSA
       */
       PSSR(HashFunction* hash, size_t salt_size);
 
-      EMSA* clone() override;
+      std::unique_ptr<EMSA> new_object() override;
 
       std::string name() const override;
 
@@ -74,7 +74,7 @@ class PSSR_Raw final : public EMSA
       */
       PSSR_Raw(HashFunction* hash, size_t salt_size);
 
-      EMSA* clone() override;
+      std::unique_ptr<EMSA> new_object() override;
 
       std::string name() const override;
    private:
diff --git a/src/lib/pk_pad/emsa_raw/emsa_raw.h b/src/lib/pk_pad/emsa_raw/emsa_raw.h
index fdcd89aa9..10c39bd35 100644
--- a/src/lib/pk_pad/emsa_raw/emsa_raw.h
+++ b/src/lib/pk_pad/emsa_raw/emsa_raw.h
@@ -19,7 +19,7 @@ namespace Botan {
 class EMSA_Raw final : public EMSA
    {
    public:
-      EMSA* clone() override { return new EMSA_Raw(); }
+      std::unique_ptr<EMSA> new_object() override { return std::make_unique<EMSA_Raw>(); }
 
       explicit EMSA_Raw(size_t expected_hash_size = 0) :
          m_expected_size(expected_hash_size) {}
diff --git a/src/lib/pk_pad/emsa_x931/emsa_x931.h b/src/lib/pk_pad/emsa_x931/emsa_x931.h
index 9c8fdc07a..a7075a74e 100644
--- a/src/lib/pk_pad/emsa_x931/emsa_x931.h
+++ b/src/lib/pk_pad/emsa_x931/emsa_x931.h
@@ -26,7 +26,7 @@ class EMSA_X931 final : public EMSA
       */
       explicit EMSA_X931(HashFunction* hash);
 
-      EMSA* clone() override { return new EMSA_X931(m_hash->clone()); }
+      std::unique_ptr<EMSA> new_object() override { return std::make_unique<EMSA_X931>(m_hash->clone()); }
 
       std::string name() const override;
 
diff --git a/src/lib/pk_pad/iso9796/iso9796.cpp b/src/lib/pk_pad/iso9796/iso9796.cpp
index 1025be521..9931ab2fa 100644
--- a/src/lib/pk_pad/iso9796/iso9796.cpp
+++ b/src/lib/pk_pad/iso9796/iso9796.cpp
@@ -216,9 +216,9 @@ bool iso9796_verification(const secure_vector<uint8_t>& const_coded,
 
 }
 
-EMSA* ISO_9796_DS2::clone()
+std::unique_ptr<EMSA> ISO_9796_DS2::new_object()
    {
-   return new ISO_9796_DS2(m_hash->clone(), m_implicit, m_SALT_SIZE);
+   return std::make_unique<ISO_9796_DS2>(m_hash->clone(), m_implicit, m_SALT_SIZE);
    }
 
 /*
@@ -269,9 +269,9 @@ std::string ISO_9796_DS2::name() const
          + (m_implicit ? "imp" : "exp") + "," + std::to_string(m_SALT_SIZE) + ")";
    }
 
-EMSA* ISO_9796_DS3::clone()
+std::unique_ptr<EMSA> ISO_9796_DS3::new_object()
    {
-   return new ISO_9796_DS3(m_hash->clone(), m_implicit);
+   return std::make_unique<ISO_9796_DS3>(m_hash->clone(), m_implicit);
    }
 
 /*
diff --git a/src/lib/pk_pad/iso9796/iso9796.h b/src/lib/pk_pad/iso9796/iso9796.h
index 1ce696a77..92a93f54f 100644
--- a/src/lib/pk_pad/iso9796/iso9796.h
+++ b/src/lib/pk_pad/iso9796/iso9796.h
@@ -34,7 +34,7 @@ class ISO_9796_DS2 final : public EMSA
       ISO_9796_DS2(HashFunction* hash, bool implicit, size_t salt_size) : m_hash(hash), m_implicit(implicit),
          m_SALT_SIZE(salt_size) {}
 
-      EMSA* clone() override;
+      std::unique_ptr<EMSA> new_object() override;
 
       std::string name() const override;
    private:
@@ -69,7 +69,7 @@ class ISO_9796_DS3 final : public EMSA
       ISO_9796_DS3(HashFunction* hash, bool implicit = false) : m_hash(hash), m_implicit(implicit)
          {}
 
-      EMSA* clone() override;
+      std::unique_ptr<EMSA> new_object() override;
 
       std::string name() const override;
    private:
diff --git a/src/lib/prov/commoncrypto/commoncrypto_block.cpp b/src/lib/prov/commoncrypto/commoncrypto_block.cpp
index 053b195f7..55ddd276b 100644
--- a/src/lib/prov/commoncrypto/commoncrypto_block.cpp
+++ b/src/lib/prov/commoncrypto/commoncrypto_block.cpp
@@ -153,7 +153,7 @@ make_commoncrypto_block_cipher(const std::string& name)
    try
       {
       CommonCryptor_Opts opts = commoncrypto_opts_from_algo_name(name);
-      return std::unique_ptr<BlockCipher>(new CommonCrypto_BlockCipher(name, opts));
+      return std::make_unique<CommonCrypto_BlockCipher>(name, opts);
       }
    catch(CommonCrypto_Error& e)
       {
diff --git a/src/lib/prov/tpm/tpm.cpp b/src/lib/prov/tpm/tpm.cpp
index d131c1a92..b98dee56d 100644
--- a/src/lib/prov/tpm/tpm.cpp
+++ b/src/lib/prov/tpm/tpm.cpp
@@ -375,7 +375,7 @@ std::vector<uint8_t> TPM_PrivateKey::export_blob() const
 
 std::unique_ptr<Public_Key> TPM_PrivateKey::public_key() const
    {
-   return std::unique_ptr<Public_Key>(new RSA_PublicKey(get_n(), get_e()));
+   return std::make_unique<RSA_PublicKey>(get_n(), get_e());
    }
 
 bool TPM_PrivateKey::check_key(RandomNumberGenerator&, bool) const
@@ -454,7 +454,7 @@ TPM_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
                                     const std::string& params,
                                     const std::string& /*provider*/) const
    {
-   return std::unique_ptr<PK_Ops::Signature>(new TPM_Signing_Operation(*this, params));
+   return std::make_unique<TPM_Signing_Operation>(*this, params);
    }
 
 }
diff --git a/src/lib/pubkey/pk_ops.cpp b/src/lib/pubkey/pk_ops.cpp
index 025836878..59e553530 100644
--- a/src/lib/pubkey/pk_ops.cpp
+++ b/src/lib/pubkey/pk_ops.cpp
@@ -11,11 +11,9 @@
 
 namespace Botan {
 
-PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme)
+PK_Ops::Encryption_with_EME::Encryption_with_EME(const std::string& eme) :
+   m_eme(EME::create(eme))
    {
-   m_eme.reset(get_eme(eme));
-   if(!m_eme.get())
-      throw Algorithm_Not_Found(eme);
    }
 
 size_t PK_Ops::Encryption_with_EME::max_input_bits() const
@@ -31,11 +29,9 @@ secure_vector<uint8_t> PK_Ops::Encryption_with_EME::encrypt(const uint8_t msg[],
    return raw_encrypt(encoded.data(), encoded.size(), rng);
    }
 
-PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme)
+PK_Ops::Decryption_with_EME::Decryption_with_EME(const std::string& eme) :
+   m_eme(EME::create(eme))
    {
-   m_eme.reset(get_eme(eme));
-   if(!m_eme.get())
-      throw Algorithm_Not_Found(eme);
    }
 
 secure_vector<uint8_t>
@@ -65,12 +61,10 @@ secure_vector<uint8_t> PK_Ops::Key_Agreement_with_KDF::agree(size_t key_len,
 
 PK_Ops::Signature_with_EMSA::Signature_with_EMSA(const std::string& emsa) :
    Signature(),
-   m_emsa(get_emsa(emsa)),
+   m_emsa(EMSA::create_or_throw(emsa)),
    m_hash(hash_for_emsa(emsa)),
    m_prefix_used(false)
    {
-   if(!m_emsa)
-      throw Algorithm_Not_Found(emsa);
    }
 
 void PK_Ops::Signature_with_EMSA::update(const uint8_t msg[], size_t msg_len)
@@ -94,12 +88,10 @@ secure_vector<uint8_t> PK_Ops::Signature_with_EMSA::sign(RandomNumberGenerator&
 
 PK_Ops::Verification_with_EMSA::Verification_with_EMSA(const std::string& emsa) :
    Verification(),
-   m_emsa(get_emsa(emsa)),
+   m_emsa(EMSA::create_or_throw(emsa)),
    m_hash(hash_for_emsa(emsa)),
    m_prefix_used(false)
    {
-   if(!m_emsa)
-      throw Algorithm_Not_Found(emsa);
    }
 
 void PK_Ops::Verification_with_EMSA::update(const uint8_t msg[], size_t msg_len)
diff --git a/src/lib/pubkey/pk_ops_impl.h b/src/lib/pubkey/pk_ops_impl.h
index 65604e598..fffcc87f8 100644
--- a/src/lib/pubkey/pk_ops_impl.h
+++ b/src/lib/pubkey/pk_ops_impl.h
@@ -116,7 +116,7 @@ class Verification_with_EMSA : public Verification
          throw Invalid_State("Message recovery not supported");
          }
 
-      std::unique_ptr<EMSA> clone_emsa() const { return std::unique_ptr<EMSA>(m_emsa->clone()); }
+      std::unique_ptr<EMSA> clone_emsa() const { return m_emsa->new_object(); }
 
    private:
       std::unique_ptr<EMSA> m_emsa;
@@ -148,7 +148,7 @@ class Signature_with_EMSA : public Signature
       */
       virtual secure_vector<uint8_t> message_prefix() const { throw Invalid_State("No prefix"); }
 
-      std::unique_ptr<EMSA> clone_emsa() const { return std::unique_ptr<EMSA>(m_emsa->clone()); }
+      std::unique_ptr<EMSA> clone_emsa() const { return m_emsa->new_object(); }
 
    private:
 
diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp
index 23869e1f7..f04b80989 100644
--- a/src/lib/tls/msg_client_hello.cpp
+++ b/src/lib/tls/msg_client_hello.cpp
@@ -35,7 +35,7 @@ std::vector<uint8_t> make_hello_random(RandomNumberGenerator& rng,
    std::vector<uint8_t> buf(32);
    rng.randomize(buf.data(), buf.size());
 
-   std::unique_ptr<HashFunction> sha256 = HashFunction::create_or_throw("SHA-256");
+   auto sha256 = HashFunction::create_or_throw("SHA-256");
    sha256->update(buf);
    sha256->final(buf);
 
@@ -123,7 +123,7 @@ Client_Hello::Client_Hello(Handshake_IO& io,
    if(m_version.is_datagram_protocol())
       m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles()));
 
-   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
+   auto supported_groups = std::make_unique<Supported_Groups>(policy.key_exchange_groups());
 
    if(supported_groups->ec_groups().size() > 0)
       {
@@ -175,7 +175,7 @@ Client_Hello::Client_Hello(Handshake_IO& io,
    if(policy.support_cert_status_message())
       m_extensions.add(new Certificate_Status_Request({}, {}));
 
-   std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups()));
+   auto supported_groups = std::make_unique<Supported_Groups>(policy.key_exchange_groups());
 
    if(supported_groups->ec_groups().size() > 0)
       {
diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp
index 7a2054acb..54f341e5b 100644
--- a/src/lib/tls/msg_server_kex.cpp
+++ b/src/lib/tls/msg_server_kex.cpp
@@ -78,7 +78,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
       BOTAN_ASSERT(group_param_is_dh(shared_group), "DH groups for the DH ciphersuites god");
 
       const std::string group_name = state.callbacks().tls_decode_group_param(shared_group);
-      std::unique_ptr<DH_PrivateKey> dh(new DH_PrivateKey(rng, DL_Group(group_name)));
+      auto dh = std::make_unique<DH_PrivateKey>(rng, DL_Group(group_name));
 
       append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_p()), 2);
       append_tls_length_value(m_params, BigInt::encode(dh->get_domain().get_g()), 2);
@@ -102,7 +102,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
       if(shared_group == Group_Params::X25519)
          {
 #if defined(BOTAN_HAS_CURVE_25519)
-         std::unique_ptr<Curve25519_PrivateKey> x25519(new Curve25519_PrivateKey(rng));
+         auto x25519 = std::make_unique<X25519_PrivateKey>(rng);
          ecdh_public_val = x25519->public_value();
          m_kex_key.reset(x25519.release());
 #else
@@ -116,7 +116,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
          const std::string curve_name = state.callbacks().tls_decode_group_param(curve);
 
          EC_Group ec_group(curve_name);
-         std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
+         auto ecdh = std::make_unique<ECDH_PrivateKey>(rng, ec_group);
 
          // follow client's preference for point compression
          ecdh_public_val = ecdh->public_value(
diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp
index 59a092867..43b7278cb 100644
--- a/src/lib/tls/tls_client.cpp
+++ b/src/lib/tls/tls_client.cpp
@@ -120,7 +120,7 @@ void Client::send_client_hello(Handshake_State& state_base,
 
    if(!force_full_renegotiation && !m_info.empty())
       {
-      std::unique_ptr<Session> session_info(new Session);;
+      auto session_info = std::make_unique<Session>();
       if(session_manager().load_from_server_info(m_info, *session_info))
          {
          /*
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp
index 8fd3cd4f4..e278a6d07 100644
--- a/src/lib/utils/os_utils.cpp
+++ b/src/lib/utils/os_utils.cpp
@@ -754,7 +754,7 @@ std::unique_ptr<OS::Echo_Suppression> OS::suppress_echo_on_terminal()
          struct termios m_old_termios;
       };
 
-   return std::unique_ptr<Echo_Suppression>(new POSIX_Echo_Suppression);
+   return std::make_unique<POSIX_Echo_Suppression>();
 
 #elif defined(BOTAN_TARGET_OS_HAS_WIN32)
 
@@ -798,12 +798,12 @@ std::unique_ptr<OS::Echo_Suppression> OS::suppress_echo_on_terminal()
          DWORD m_console_state;
       };
 
-   return std::unique_ptr<Echo_Suppression>(new Win32_Echo_Suppression);
+   return std::make_unique<Win32_Echo_Suppression>();
 
 #else
 
    // Not supported on this platform, return null
-   return std::unique_ptr<Echo_Suppression>();
+   return nullptr;
 #endif
    }
 
diff --git a/src/lib/x509/crl_ent.cpp b/src/lib/x509/crl_ent.cpp
index 138590f59..affae3184 100644
--- a/src/lib/x509/crl_ent.cpp
+++ b/src/lib/x509/crl_ent.cpp
@@ -27,7 +27,7 @@ struct CRL_Entry_Data
 */
 CRL_Entry::CRL_Entry(const X509_Certificate& cert, CRL_Code why)
    {
-   m_data.reset(new CRL_Entry_Data);
+   m_data = std::make_shared<CRL_Entry_Data>();
    m_data->m_serial = cert.serial_number();
    m_data->m_time = X509_Time(std::chrono::system_clock::now());
    m_data->m_reason = why;
@@ -81,7 +81,7 @@ void CRL_Entry::decode_from(BER_Decoder& source)
    {
    BigInt serial_number_bn;
 
-   std::unique_ptr<CRL_Entry_Data> data(new CRL_Entry_Data);
+   auto data = std::make_unique<CRL_Entry_Data>();
 
    BER_Decoder entry = source.start_sequence();
 
@@ -103,7 +103,7 @@ void CRL_Entry::decode_from(BER_Decoder& source)
 
    entry.end_cons();
 
-   m_data.reset(data.release());
+   m_data = std::move(data);
    }
 
 const CRL_Entry_Data& CRL_Entry::data() const
diff --git a/src/lib/x509/pkcs10.cpp b/src/lib/x509/pkcs10.cpp
index 8b24d6493..936653e33 100644
--- a/src/lib/x509/pkcs10.cpp
+++ b/src/lib/x509/pkcs10.cpp
@@ -105,7 +105,7 @@ namespace {
 
 std::unique_ptr<PKCS10_Data> decode_pkcs10(const std::vector<uint8_t>& body)
    {
-   std::unique_ptr<PKCS10_Data> data(new PKCS10_Data);
+   auto data = std::make_unique<PKCS10_Data>();
 
    BER_Decoder cert_req_info(body);
 
diff --git a/src/lib/x509/pkix_types.h b/src/lib/x509/pkix_types.h
index 609c6c796..9d4183caa 100644
--- a/src/lib/x509/pkix_types.h
+++ b/src/lib/x509/pkix_types.h
@@ -523,7 +523,7 @@ class BOTAN_PUBLIC_API(2,0) Extensions final : public ASN1_Object
             // Unknown_Extension oid_name is empty
             if(extn_info->second.obj().oid_name() == "")
                {
-               std::unique_ptr<T> ext(new T);
+               auto ext = std::make_unique<T>();
                ext->decode_inner(extn_info->second.bits());
                return ext;
                }
diff --git a/src/lib/x509/x509_crl.cpp b/src/lib/x509/x509_crl.cpp
index a8f3b0a2c..3dcdeb108 100644
--- a/src/lib/x509/x509_crl.cpp
+++ b/src/lib/x509/x509_crl.cpp
@@ -63,7 +63,7 @@ X509_CRL::X509_CRL(const X509_DN& issuer,
                    const std::vector<CRL_Entry>& revoked) :
    X509_Object()
    {
-   m_data.reset(new CRL_Data);
+   m_data = std::make_shared<CRL_Data>();
    m_data->m_issuer = issuer;
    m_data->m_this_update = this_update;
    m_data->m_next_update = next_update;
@@ -118,7 +118,7 @@ namespace {
 std::unique_ptr<CRL_Data> decode_crl_body(const std::vector<uint8_t>& body,
                                           const AlgorithmIdentifier& sig_algo)
    {
-   std::unique_ptr<CRL_Data> data(new CRL_Data);
+   auto data = std::make_unique<CRL_Data>();
 
    BER_Decoder tbs_crl(body);
 
diff --git a/src/lib/x509/x509_obj.cpp b/src/lib/x509/x509_obj.cpp
index 43d37da44..1ac7f8279 100644
--- a/src/lib/x509/x509_obj.cpp
+++ b/src/lib/x509/x509_obj.cpp
@@ -374,10 +374,10 @@ std::string choose_sig_algo(AlgorithmIdentifier& sig_algo,
       std::unique_ptr<EMSA> emsa;
       try
          {
-         emsa.reset(get_emsa(padding));
+         emsa = EMSA::create_or_throw(padding);
          }
       /*
-      * get_emsa will throw if opts contains {"padding",<valid_padding>} but
+      * EMSA::create will throw if opts contains {"padding",<valid_padding>} but
       * <valid_padding> does not specify a hash function.
       * Omitting it is valid since it needs to be identical to hash_fn.
       * If it still throws, something happened that we cannot repair here,
@@ -385,7 +385,7 @@ std::string choose_sig_algo(AlgorithmIdentifier& sig_algo,
       */
       catch(...)
          {
-         emsa.reset(get_emsa(padding + "(" + hash_fn + ")"));
+         emsa = EMSA::create(padding + "(" + hash_fn + ")");
          }
 
       if(!emsa)
@@ -415,10 +415,8 @@ std::unique_ptr<PK_Signer> X509_Object::choose_sig_format(AlgorithmIdentifier& s
                                                           const std::string& padding_algo)
    {
    const Signature_Format format = key.default_x509_signature_format();
-
    const std::string emsa = choose_sig_algo(sig_algo, key, hash_fn, padding_algo);
-
-   return std::unique_ptr<PK_Signer>(new PK_Signer(key, rng, emsa, format));
+   return std::make_unique<PK_Signer>(key, rng, emsa, format);
    }
 
 }
diff --git a/src/lib/x509/x509cert.cpp b/src/lib/x509/x509cert.cpp
index 336790336..c742a688f 100644
--- a/src/lib/x509/x509cert.cpp
+++ b/src/lib/x509/x509cert.cpp
@@ -107,7 +107,7 @@ namespace {
 
 std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& obj)
    {
-   std::unique_ptr<X509_Certificate_Data> data(new X509_Certificate_Data);
+   auto data = std::make_unique<X509_Certificate_Data>();
 
    BigInt serial_bn;
    BER_Object public_key;
@@ -366,10 +366,7 @@ std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& o
 void X509_Certificate::force_decode()
    {
    m_data.reset();
-
-   std::unique_ptr<X509_Certificate_Data> data = parse_x509_cert_body(*this);
-
-   m_data.reset(data.release());
+   m_data = parse_x509_cert_body(*this);
    }
 
 const X509_Certificate_Data& X509_Certificate::data() const


Test patch:
diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp
index 7dcfb26af..ca05dc83a 100644
--- a/src/tests/test_ecdsa.cpp
+++ b/src/tests/test_ecdsa.cpp
@@ -128,11 +128,11 @@ class ECDSA_Signature_KAT_Tests final : public PK_Signature_Generation_Test
          }
 
 #if !defined(BOTAN_HAS_RFC6979_GENERATOR)
-      Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const override
+      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override
          {
          // probabilistic ecdsa signature generation extracts more random than just the nonce,
          // but the nonce is extracted first
-         return new Fixed_Output_Position_RNG(nonce, 1);
+         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
          }
 #endif
    };
diff --git a/src/tests/test_ecgdsa.cpp b/src/tests/test_ecgdsa.cpp
index 6483a806f..df8e03194 100644
--- a/src/tests/test_ecgdsa.cpp
+++ b/src/tests/test_ecgdsa.cpp
@@ -46,11 +46,11 @@ class ECGDSA_Signature_KAT_Tests final : public PK_Signature_Generation_Test
          return "EMSA1(" + vars.get_req_str("Hash") + ")";
          }
 
-      Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const override
+      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override
          {
          // ecgdsa signature generation extracts more random than just the nonce,
          // but the nonce is extracted first
-         return new Fixed_Output_Position_RNG(nonce, 1);
+         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
          }
    };
 
diff --git a/src/tests/test_eckcdsa.cpp b/src/tests/test_eckcdsa.cpp
index b168a7d24..fe2b14b21 100644
--- a/src/tests/test_eckcdsa.cpp
+++ b/src/tests/test_eckcdsa.cpp
@@ -47,11 +47,11 @@ class ECKCDSA_Signature_KAT_Tests final : public PK_Signature_Generation_Test
          return "EMSA1(" + vars.get_req_str("Hash") + ")";
          }
 
-      Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const override
+      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override
          {
          // eckcdsa signature generation extracts more random than just the nonce,
          // but the nonce is extracted first
-         return new Fixed_Output_Position_RNG(nonce, 1);
+         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
          }
    };
 
diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp
index 0c5e0c45c..1b8b46e44 100644
--- a/src/tests/test_gost_3410.cpp
+++ b/src/tests/test_gost_3410.cpp
@@ -89,9 +89,9 @@ class GOST_3410_2001_Signature_Tests final : public PK_Signature_Generation_Test
          return "EMSA1(" + hash + ")";
          }
 
-      Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const override
+      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override
          {
-         return new Fixed_Output_Position_RNG(nonce, 1);
+         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
          }
    };
 
diff --git a/src/tests/test_pk_pad.cpp b/src/tests/test_pk_pad.cpp
index 7daa45a32..f809562ff 100644
--- a/src/tests/test_pk_pad.cpp
+++ b/src/tests/test_pk_pad.cpp
@@ -116,9 +116,8 @@ class EMSA_unit_tests final : public Test
             try
                {
                const std::string hash_to_use = Botan::hash_for_emsa(pad);
-               std::unique_ptr<Botan::EMSA> emsa_1(
-                  Botan::get_emsa(pad + "(" + hash_to_use + ")"));
-               std::unique_ptr<Botan::EMSA> emsa_2(Botan::get_emsa(emsa_1->name()));
+               auto emsa_1 = Botan::EMSA::create(pad + "(" + hash_to_use + ")");
+               auto emsa_2 = Botan::EMSA::create(emsa_1->name());
                name_tests.test_eq("EMSA_name_test for " + pad,
                      emsa_1->name(), emsa_2->name());
                }
@@ -137,8 +136,7 @@ class EMSA_unit_tests final : public Test
             std::string algo_name = pad + "(YYZ)";
             try
                {
-               std::unique_ptr<Botan::EMSA> emsa(
-                  Botan::get_emsa(algo_name));
+               auto emsa = Botan::EMSA::create_or_throw(algo_name);
                name_tests.test_failure("EMSA_name_test for " + pad + ": " +
                    "Could create EMSA with fantasy hash YYZ");
                }
@@ -158,8 +156,8 @@ class EMSA_unit_tests final : public Test
             {
             try
                {
-               std::unique_ptr<Botan::EMSA> emsa_1(Botan::get_emsa(pad));
-               std::unique_ptr<Botan::EMSA> emsa_2(Botan::get_emsa(emsa_1->name()));
+               auto emsa_1 = Botan::EMSA::create(pad);
+               auto emsa_2 = Botan::EMSA::create(emsa_1->name());
                name_tests.test_eq("EMSA_name_test for " + pad,
                      emsa_1->name(), emsa_2->name());
                }
diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp
index 7156ad534..103c70ce0 100644
--- a/src/tests/test_pubkey.cpp
+++ b/src/tests/test_pubkey.cpp
@@ -152,7 +152,7 @@ PK_Signature_Generation_Test::run_one_test(const std::string& pad_hdr, const Var
 
          if(vars.has_key("Nonce"))
             {
-            std::unique_ptr<Botan::RandomNumberGenerator> rng(test_rng(vars.get_req_bin("Nonce")));
+            auto rng = test_rng(vars.get_req_bin("Nonce"));
             generated_signature = signer->sign_message(message, *rng);
             }
          else
@@ -402,7 +402,7 @@ PK_Encryption_Decryption_Test::run_one_test(const std::string& pad_hdr, const Va
       std::unique_ptr<Botan::RandomNumberGenerator> kat_rng;
       if(vars.has_key("Nonce"))
          {
-         kat_rng.reset(test_rng(vars.get_req_bin("Nonce")));
+         kat_rng = test_rng(vars.get_req_bin("Nonce"));
          }
 
       if(padding == "Raw")
diff --git a/src/tests/test_pubkey.h b/src/tests/test_pubkey.h
index ad859abbc..8d6cbe75a 100644
--- a/src/tests/test_pubkey.h
+++ b/src/tests/test_pubkey.h
@@ -58,9 +58,9 @@ class PK_Signature_Generation_Test : public PK_Test
 
       virtual std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) = 0;
 
-      virtual Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const
+      virtual std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const
          {
-         return new Fixed_Output_RNG(nonce);
+         return std::make_unique<Fixed_Output_RNG>(nonce);
          }
 
    private:
@@ -146,9 +146,9 @@ class PK_Encryption_Decryption_Test : public PK_Test
          return "Raw";
          }
 
-      virtual Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const
+      virtual std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const
          {
-         return new Fixed_Output_RNG(nonce);
+         return std::make_unique<Fixed_Output_RNG>(nonce);
          }
 
    private:
diff --git a/src/tests/test_sm2.cpp b/src/tests/test_sm2.cpp
index 7d3f30526..cec71c6be 100644
--- a/src/tests/test_sm2.cpp
+++ b/src/tests/test_sm2.cpp
@@ -53,9 +53,9 @@ class SM2_Signature_KAT_Tests final : public PK_Signature_Generation_Test
          return vars.get_req_str("Ident") + "," + vars.get_opt_str("Hash", "SM3");
          }
 
-      Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const override
+      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override
          {
-         return new Fixed_Output_Position_RNG(nonce, 1);
+         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
          }
 
       std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
@@ -83,9 +83,9 @@ class SM2_Encryption_KAT_Tests final : public PK_Encryption_Decryption_Test
 
       bool clear_between_callbacks() const override { return false; }
 
-      Botan::RandomNumberGenerator* test_rng(const std::vector<uint8_t>& nonce) const override
+      std::unique_ptr<Botan::RandomNumberGenerator> test_rng(const std::vector<uint8_t>& nonce) const override
          {
-         return new Fixed_Output_Position_RNG(nonce, 1);
+         return std::make_unique<Fixed_Output_Position_RNG>(nonce, 1);
          }
 
       std::unique_ptr<Botan::Private_Key> load_private_key(const VarMap& vars) override
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
index 838d864d7..f9305354f 100644
--- a/src/tests/tests.cpp
+++ b/src/tests/tests.cpp
@@ -473,16 +473,16 @@ std::string Test::Result::result_string() const
 
 // static Test:: functions
 //static
-std::map<std::string, std::function<Test* ()>>& Test::global_registry()
+std::map<std::string, std::function<std::unique_ptr<Test> ()>>& Test::global_registry()
    {
-   static std::map<std::string, std::function<Test* ()>> g_test_registry;
+   static std::map<std::string, std::function<std::unique_ptr<Test> ()>> g_test_registry;
    return g_test_registry;
    }
 
 //static
 void Test::register_test(const std::string& category,
                          const std::string& name,
-                         std::function<Test* ()> maker_fn)
+                         std::function<std::unique_ptr<Test> ()> maker_fn)
    {
    BOTAN_UNUSED(category);
    if(Test::global_registry().count(name) != 0)
diff --git a/src/tests/tests.h b/src/tests/tests.h
index bcd91bd5c..d05e22d4f 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -444,9 +444,9 @@ class Test
 
       static void register_test(const std::string& category,
                                 const std::string& name,
-                                std::function<Test* ()> maker_fn);
+                                std::function<std::unique_ptr<Test> ()> maker_fn);
 
-      static std::map<std::string, std::function<Test* ()>>& global_registry();
+      static std::map<std::string, std::function<std::unique_ptr<Test> ()>>& global_registry();
 
       static std::set<std::string> registered_tests();
 
@@ -519,7 +519,7 @@ class TestClassRegistration
    public:
       TestClassRegistration(const std::string& category, const std::string& name)
          {
-         auto test_maker = []() -> Test* { return new Test_Class; };
+         auto test_maker = []() -> std::unique_ptr<Test> { return std::make_unique<Test_Class>(); };
          Test::register_test(category, name, test_maker);
          }
    };
@@ -548,7 +548,7 @@ class TestFnRegistration
    public:
       TestFnRegistration(const std::string& category, const std::string& name, test_fn fn)
          {
-         auto test_maker = [=]() -> Test* { return new FnTest(fn); };
+         auto test_maker = [=]() -> std::unique_ptr<Test> { return std::make_unique<FnTest>(fn); };
          Test::register_test(category, name, test_maker);
          }
    };