aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-05-22 22:18:21 -0400
committerJack Lloyd <[email protected]>2017-05-22 22:18:21 -0400
commitcb91be3967edab3688b744e150a98d96db89b2fd (patch)
treead818dc31b2a6b2c1fb894cbf3cfcf2a70213bca
parent22797129ff2f746f96d3725ab45e043c506664f3 (diff)
parentb136d4e7ca350bb388a1a6d638b1010a2b1e5b73 (diff)
Merge GH #1056 Add HashFunction::copy_state and port to OpenSSL 1.1.0
-rw-r--r--src/lib/hash/blake2/blake2b.cpp5
-rw-r--r--src/lib/hash/blake2/blake2b.h2
-rw-r--r--src/lib/hash/checksum/adler32/adler32.cpp5
-rw-r--r--src/lib/hash/checksum/adler32/adler32.h1
-rw-r--r--src/lib/hash/checksum/crc24/crc24.cpp5
-rw-r--r--src/lib/hash/checksum/crc24/crc24.h1
-rw-r--r--src/lib/hash/checksum/crc32/crc32.cpp5
-rw-r--r--src/lib/hash/checksum/crc32/crc32.h1
-rw-r--r--src/lib/hash/comb4p/comb4p.cpp8
-rw-r--r--src/lib/hash/comb4p/comb4p.h4
-rw-r--r--src/lib/hash/gost_3411/gost_3411.cpp5
-rw-r--r--src/lib/hash/gost_3411/gost_3411.h1
-rw-r--r--src/lib/hash/hash.h11
-rw-r--r--src/lib/hash/keccak/keccak.cpp5
-rw-r--r--src/lib/hash/keccak/keccak.h1
-rw-r--r--src/lib/hash/md4/md4.cpp5
-rw-r--r--src/lib/hash/md4/md4.h1
-rw-r--r--src/lib/hash/md5/md5.cpp5
-rw-r--r--src/lib/hash/md5/md5.h1
-rw-r--r--src/lib/hash/par_hash/par_hash.cpp12
-rw-r--r--src/lib/hash/par_hash/par_hash.h1
-rw-r--r--src/lib/hash/rmd160/rmd160.cpp5
-rw-r--r--src/lib/hash/rmd160/rmd160.h1
-rw-r--r--src/lib/hash/sha1/sha160.cpp5
-rw-r--r--src/lib/hash/sha1/sha160.h1
-rw-r--r--src/lib/hash/sha2_32/sha2_32.cpp35
-rw-r--r--src/lib/hash/sha2_32/sha2_32.h2
-rw-r--r--src/lib/hash/sha2_64/sha2_64.cpp15
-rw-r--r--src/lib/hash/sha2_64/sha2_64.h3
-rw-r--r--src/lib/hash/sha3/sha3.cpp5
-rw-r--r--src/lib/hash/sha3/sha3.h1
-rw-r--r--src/lib/hash/shake/shake.cpp10
-rw-r--r--src/lib/hash/shake/shake.h2
-rw-r--r--src/lib/hash/skein/skein_512.cpp12
-rw-r--r--src/lib/hash/skein/skein_512.h1
-rw-r--r--src/lib/hash/sm3/sm3.cpp5
-rw-r--r--src/lib/hash/sm3/sm3.h1
-rw-r--r--src/lib/hash/tiger/tiger.cpp5
-rw-r--r--src/lib/hash/tiger/tiger.h2
-rw-r--r--src/lib/hash/whirlpool/whirlpool.cpp5
-rw-r--r--src/lib/hash/whirlpool/whrlpool.h1
-rw-r--r--src/lib/prov/openssl/openssl_block.cpp67
-rw-r--r--src/lib/prov/openssl/openssl_ec.cpp33
-rw-r--r--src/lib/prov/openssl/openssl_hash.cpp47
-rw-r--r--src/lib/prov/openssl/openssl_mode.cpp35
-rw-r--r--src/lib/prov/openssl/openssl_rsa.cpp22
-rw-r--r--src/tests/test_hash.cpp10
47 files changed, 341 insertions, 75 deletions
diff --git a/src/lib/hash/blake2/blake2b.cpp b/src/lib/hash/blake2/blake2b.cpp
index b478af106..85171b16b 100644
--- a/src/lib/hash/blake2/blake2b.cpp
+++ b/src/lib/hash/blake2/blake2b.cpp
@@ -208,6 +208,11 @@ HashFunction* Blake2b::clone() const
return new Blake2b(m_output_bits);
}
+std::unique_ptr<HashFunction> Blake2b::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new Blake2b(*this));
+ }
+
void Blake2b::clear()
{
zeroise(m_H);
diff --git a/src/lib/hash/blake2/blake2b.h b/src/lib/hash/blake2/blake2b.h
index 473352174..c7ceac01e 100644
--- a/src/lib/hash/blake2/blake2b.h
+++ b/src/lib/hash/blake2/blake2b.h
@@ -38,6 +38,8 @@ class BOTAN_DLL Blake2b final : public HashFunction
std::string name() const override;
void clear() override;
+ std::unique_ptr<HashFunction> copy_state() const override;
+
private:
void add_data(const uint8_t input[], size_t length) override;
void final_result(uint8_t out[]) override;
diff --git a/src/lib/hash/checksum/adler32/adler32.cpp b/src/lib/hash/checksum/adler32/adler32.cpp
index b7f6356c4..329ba99a8 100644
--- a/src/lib/hash/checksum/adler32/adler32.cpp
+++ b/src/lib/hash/checksum/adler32/adler32.cpp
@@ -78,4 +78,9 @@ void Adler32::final_result(uint8_t output[])
clear();
}
+std::unique_ptr<HashFunction> Adler32::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new Adler32(*this));
+ }
+
}
diff --git a/src/lib/hash/checksum/adler32/adler32.h b/src/lib/hash/checksum/adler32/adler32.h
index eaf57c656..98ba4f91a 100644
--- a/src/lib/hash/checksum/adler32/adler32.h
+++ b/src/lib/hash/checksum/adler32/adler32.h
@@ -21,6 +21,7 @@ class BOTAN_DLL Adler32 final : public HashFunction
std::string name() const override { return "Adler32"; }
size_t output_length() const override { return 4; }
HashFunction* clone() const override { return new Adler32; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override { m_S1 = 1; m_S2 = 0; }
diff --git a/src/lib/hash/checksum/crc24/crc24.cpp b/src/lib/hash/checksum/crc24/crc24.cpp
index 923433d7e..bed456177 100644
--- a/src/lib/hash/checksum/crc24/crc24.cpp
+++ b/src/lib/hash/checksum/crc24/crc24.cpp
@@ -10,6 +10,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> CRC24::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new CRC24(*this));
+ }
+
/*
* Update a CRC24 Checksum
*/
diff --git a/src/lib/hash/checksum/crc24/crc24.h b/src/lib/hash/checksum/crc24/crc24.h
index 95977bc48..203611b8f 100644
--- a/src/lib/hash/checksum/crc24/crc24.h
+++ b/src/lib/hash/checksum/crc24/crc24.h
@@ -21,6 +21,7 @@ class BOTAN_DLL CRC24 final : public HashFunction
std::string name() const override { return "CRC24"; }
size_t output_length() const override { return 3; }
HashFunction* clone() const override { return new CRC24; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override { m_crc = 0xB704CE; }
diff --git a/src/lib/hash/checksum/crc32/crc32.cpp b/src/lib/hash/checksum/crc32/crc32.cpp
index 1bbc35ac8..c69c8f80b 100644
--- a/src/lib/hash/checksum/crc32/crc32.cpp
+++ b/src/lib/hash/checksum/crc32/crc32.cpp
@@ -10,6 +10,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> CRC32::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new CRC32(*this));
+ }
+
/*
* Update a CRC32 Checksum
*/
diff --git a/src/lib/hash/checksum/crc32/crc32.h b/src/lib/hash/checksum/crc32/crc32.h
index fd9db1b3e..e1e266de3 100644
--- a/src/lib/hash/checksum/crc32/crc32.h
+++ b/src/lib/hash/checksum/crc32/crc32.h
@@ -21,6 +21,7 @@ class BOTAN_DLL CRC32 final : public HashFunction
std::string name() const override { return "CRC32"; }
size_t output_length() const override { return 4; }
HashFunction* clone() const override { return new CRC32; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override { m_crc = 0xFFFFFFFF; }
diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp
index ece8c9051..f6c20f35e 100644
--- a/src/lib/hash/comb4p/comb4p.cpp
+++ b/src/lib/hash/comb4p/comb4p.cpp
@@ -69,6 +69,14 @@ void Comb4P::clear()
m_hash2->update(0);
}
+std::unique_ptr<HashFunction> Comb4P::copy_state() const
+ {
+ std::unique_ptr<Comb4P> copy(new Comb4P);
+ copy->m_hash1 = m_hash1->copy_state();
+ copy->m_hash2 = m_hash2->copy_state();
+ return std::move(copy);
+ }
+
void Comb4P::add_data(const uint8_t input[], size_t length)
{
m_hash1->update(input, length);
diff --git a/src/lib/hash/comb4p/comb4p.h b/src/lib/hash/comb4p/comb4p.h
index a578b56c8..9579db0ab 100644
--- a/src/lib/hash/comb4p/comb4p.h
+++ b/src/lib/hash/comb4p/comb4p.h
@@ -37,6 +37,8 @@ class BOTAN_DLL Comb4P final : public HashFunction
return new Comb4P(m_hash1->clone(), m_hash2->clone());
}
+ std::unique_ptr<HashFunction> copy_state() const override;
+
std::string name() const override
{
return "Comb4P(" + m_hash1->name() + "," + m_hash2->name() + ")";
@@ -44,6 +46,8 @@ class BOTAN_DLL Comb4P final : public HashFunction
void clear() override;
private:
+ Comb4P() {}
+
void add_data(const uint8_t input[], size_t length) override;
void final_result(uint8_t out[]) override;
diff --git a/src/lib/hash/gost_3411/gost_3411.cpp b/src/lib/hash/gost_3411/gost_3411.cpp
index 62028e496..2e2ed962d 100644
--- a/src/lib/hash/gost_3411/gost_3411.cpp
+++ b/src/lib/hash/gost_3411/gost_3411.cpp
@@ -31,6 +31,11 @@ void GOST_34_11::clear()
m_position = 0;
}
+std::unique_ptr<HashFunction> GOST_34_11::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new GOST_34_11(*this));
+ }
+
/**
* Hash additional inputs
*/
diff --git a/src/lib/hash/gost_3411/gost_3411.h b/src/lib/hash/gost_3411/gost_3411.h
index e18ab56fa..51f010afb 100644
--- a/src/lib/hash/gost_3411/gost_3411.h
+++ b/src/lib/hash/gost_3411/gost_3411.h
@@ -23,6 +23,7 @@ class BOTAN_DLL GOST_34_11 final : public HashFunction
size_t output_length() const override { return 32; }
size_t hash_block_size() const override { return 32; }
HashFunction* clone() const override { return new GOST_34_11; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h
index 5cb290499..db049989a 100644
--- a/src/lib/hash/hash.h
+++ b/src/lib/hash/hash.h
@@ -72,6 +72,17 @@ class BOTAN_DLL HashFunction : public Buffered_Computation
* @return hash block size as defined for this algorithm
*/
virtual size_t hash_block_size() const { return 0; }
+
+ /**
+ * Return a new hash object with the same state as *this. This
+ * allows computing the hash of several messages with a common
+ * prefix more efficiently than would otherwise be possible.
+ *
+ * This function should be called `clone` but that was already
+ * used for the case of returning an uninitialized object.
+ * @return new hash object
+ */
+ virtual std::unique_ptr<HashFunction> copy_state() const = 0;
};
}
diff --git a/src/lib/hash/keccak/keccak.cpp b/src/lib/hash/keccak/keccak.cpp
index 1d2747ff2..f51b53e06 100644
--- a/src/lib/hash/keccak/keccak.cpp
+++ b/src/lib/hash/keccak/keccak.cpp
@@ -12,6 +12,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> Keccak_1600::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new Keccak_1600(*this));
+ }
+
Keccak_1600::Keccak_1600(size_t output_bits) :
m_output_bits(output_bits),
m_bitrate(1600 - 2*output_bits),
diff --git a/src/lib/hash/keccak/keccak.h b/src/lib/hash/keccak/keccak.h
index a2c14c65a..36e1ad9fe 100644
--- a/src/lib/hash/keccak/keccak.h
+++ b/src/lib/hash/keccak/keccak.h
@@ -31,6 +31,7 @@ class BOTAN_DLL Keccak_1600 final : public HashFunction
size_t output_length() const override { return m_output_bits / 8; }
HashFunction* clone() const override;
+ std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;
diff --git a/src/lib/hash/md4/md4.cpp b/src/lib/hash/md4/md4.cpp
index 014ba8c2c..79f3a2d13 100644
--- a/src/lib/hash/md4/md4.cpp
+++ b/src/lib/hash/md4/md4.cpp
@@ -9,6 +9,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> MD4::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new MD4(*this));
+ }
+
namespace {
/*
diff --git a/src/lib/hash/md4/md4.h b/src/lib/hash/md4/md4.h
index ebd0bdedd..c84cb0058 100644
--- a/src/lib/hash/md4/md4.h
+++ b/src/lib/hash/md4/md4.h
@@ -21,6 +21,7 @@ class BOTAN_DLL MD4 final : public MDx_HashFunction
std::string name() const override { return "MD4"; }
size_t output_length() const override { return 16; }
HashFunction* clone() const override { return new MD4; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/md5/md5.cpp b/src/lib/hash/md5/md5.cpp
index 0612ba956..174443a67 100644
--- a/src/lib/hash/md5/md5.cpp
+++ b/src/lib/hash/md5/md5.cpp
@@ -9,6 +9,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> MD5::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new MD5(*this));
+ }
+
namespace {
/*
diff --git a/src/lib/hash/md5/md5.h b/src/lib/hash/md5/md5.h
index 13a423594..ee8d70e3f 100644
--- a/src/lib/hash/md5/md5.h
+++ b/src/lib/hash/md5/md5.h
@@ -21,6 +21,7 @@ class BOTAN_DLL MD5 final : public MDx_HashFunction
std::string name() const override { return "MD5"; }
size_t output_length() const override { return 16; }
HashFunction* clone() const override { return new MD5; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp
index 2a1ef7c9c..af43d6d97 100644
--- a/src/lib/hash/par_hash/par_hash.cpp
+++ b/src/lib/hash/par_hash/par_hash.cpp
@@ -56,6 +56,18 @@ HashFunction* Parallel::clone() const
return new Parallel(hash_copies);
}
+std::unique_ptr<HashFunction> Parallel::copy_state() const
+ {
+ std::vector<std::unique_ptr<HashFunction>> hash_clones;
+
+ for(const std::unique_ptr<HashFunction>& hash : m_hashes)
+ {
+ hash_clones.push_back(hash->copy_state());
+ }
+
+ return std::unique_ptr<HashFunction>(new Parallel(hash_clones));
+ }
+
void Parallel::clear()
{
for(auto&& hash : m_hashes)
diff --git a/src/lib/hash/par_hash/par_hash.h b/src/lib/hash/par_hash/par_hash.h
index cf6f49af4..85bf49208 100644
--- a/src/lib/hash/par_hash/par_hash.h
+++ b/src/lib/hash/par_hash/par_hash.h
@@ -22,6 +22,7 @@ class BOTAN_DLL Parallel final : public HashFunction
void clear() override;
std::string name() const override;
HashFunction* clone() const override;
+ std::unique_ptr<HashFunction> copy_state() const override;
size_t output_length() const override;
diff --git a/src/lib/hash/rmd160/rmd160.cpp b/src/lib/hash/rmd160/rmd160.cpp
index 8d190a74f..95f96c281 100644
--- a/src/lib/hash/rmd160/rmd160.cpp
+++ b/src/lib/hash/rmd160/rmd160.cpp
@@ -9,6 +9,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> RIPEMD_160::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new RIPEMD_160(*this));
+ }
+
namespace {
/*
diff --git a/src/lib/hash/rmd160/rmd160.h b/src/lib/hash/rmd160/rmd160.h
index 9e2d1de87..f2b57ef33 100644
--- a/src/lib/hash/rmd160/rmd160.h
+++ b/src/lib/hash/rmd160/rmd160.h
@@ -21,6 +21,7 @@ class BOTAN_DLL RIPEMD_160 final : public MDx_HashFunction
std::string name() const override { return "RIPEMD-160"; }
size_t output_length() const override { return 20; }
HashFunction* clone() const override { return new RIPEMD_160; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/sha1/sha160.cpp b/src/lib/hash/sha1/sha160.cpp
index 6ebdba73f..fcca67341 100644
--- a/src/lib/hash/sha1/sha160.cpp
+++ b/src/lib/hash/sha1/sha160.cpp
@@ -10,6 +10,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> SHA_160::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_160(*this));
+ }
+
namespace SHA1_F {
namespace {
diff --git a/src/lib/hash/sha1/sha160.h b/src/lib/hash/sha1/sha160.h
index f2ed61b64..fd3c77d46 100644
--- a/src/lib/hash/sha1/sha160.h
+++ b/src/lib/hash/sha1/sha160.h
@@ -21,6 +21,7 @@ class BOTAN_DLL SHA_160 final : public MDx_HashFunction
std::string name() const override { return "SHA-160"; }
size_t output_length() const override { return 20; }
HashFunction* clone() const override { return new SHA_160; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/sha2_32/sha2_32.cpp b/src/lib/hash/sha2_32/sha2_32.cpp
index ab6903fa7..58977b617 100644
--- a/src/lib/hash/sha2_32/sha2_32.cpp
+++ b/src/lib/hash/sha2_32/sha2_32.cpp
@@ -11,6 +11,41 @@
namespace Botan {
+std::unique_ptr<HashFunction> SHA_224::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_224(*this));
+ }
+
+std::unique_ptr<HashFunction> SHA_256::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_256(*this));
+ }
+
+namespace {
+
+namespace SHA2_32 {
+
+/*
+* SHA-256 Rho Function
+*/
+inline uint32_t rho(uint32_t X, uint32_t rot1, uint32_t rot2, uint32_t rot3)
+ {
+ return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^
+ rotate_right(X, rot3));
+ }
+
+/*
+* SHA-256 Sigma Function
+*/
+inline uint32_t sigma(uint32_t X, uint32_t rot1, uint32_t rot2, uint32_t shift)
+ {
+ return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ (X >> shift));
+ }
+
+}
+
+}
+
/*
* SHA-256 F1 Function
*
diff --git a/src/lib/hash/sha2_32/sha2_32.h b/src/lib/hash/sha2_32/sha2_32.h
index ecf2e0ece..a6619f0fc 100644
--- a/src/lib/hash/sha2_32/sha2_32.h
+++ b/src/lib/hash/sha2_32/sha2_32.h
@@ -22,6 +22,7 @@ class BOTAN_DLL SHA_224 final : public MDx_HashFunction
std::string name() const override { return "SHA-224"; }
size_t output_length() const override { return 28; }
HashFunction* clone() const override { return new SHA_224; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
@@ -43,6 +44,7 @@ class BOTAN_DLL SHA_256 final : public MDx_HashFunction
std::string name() const override { return "SHA-256"; }
size_t output_length() const override { return 32; }
HashFunction* clone() const override { return new SHA_256; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/sha2_64/sha2_64.cpp b/src/lib/hash/sha2_64/sha2_64.cpp
index 59242ee9c..8e01b6b4d 100644
--- a/src/lib/hash/sha2_64/sha2_64.cpp
+++ b/src/lib/hash/sha2_64/sha2_64.cpp
@@ -9,6 +9,21 @@
namespace Botan {
+std::unique_ptr<HashFunction> SHA_384::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_384(*this));
+ }
+
+std::unique_ptr<HashFunction> SHA_512::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_512(*this));
+ }
+
+std::unique_ptr<HashFunction> SHA_512_256::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_512_256(*this));
+ }
+
namespace {
namespace SHA2_64 {
diff --git a/src/lib/hash/sha2_64/sha2_64.h b/src/lib/hash/sha2_64/sha2_64.h
index 51bdb2b77..b027c4d27 100644
--- a/src/lib/hash/sha2_64/sha2_64.h
+++ b/src/lib/hash/sha2_64/sha2_64.h
@@ -21,6 +21,7 @@ class BOTAN_DLL SHA_384 final : public MDx_HashFunction
std::string name() const override { return "SHA-384"; }
size_t output_length() const override { return 48; }
HashFunction* clone() const override { return new SHA_384; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
@@ -42,6 +43,7 @@ class BOTAN_DLL SHA_512 final : public MDx_HashFunction
std::string name() const override { return "SHA-512"; }
size_t output_length() const override { return 64; }
HashFunction* clone() const override { return new SHA_512; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
@@ -63,6 +65,7 @@ class BOTAN_DLL SHA_512_256 final : public MDx_HashFunction
std::string name() const override { return "SHA-512-256"; }
size_t output_length() const override { return 32; }
HashFunction* clone() const override { return new SHA_512_256; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/sha3/sha3.cpp b/src/lib/hash/sha3/sha3.cpp
index f1c769e6b..a31b3bd14 100644
--- a/src/lib/hash/sha3/sha3.cpp
+++ b/src/lib/hash/sha3/sha3.cpp
@@ -11,6 +11,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> SHA_3::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHA_3(*this));
+ }
+
//static
void SHA_3::permute(uint64_t A[25])
{
diff --git a/src/lib/hash/sha3/sha3.h b/src/lib/hash/sha3/sha3.h
index e7905b5c4..fec25b806 100644
--- a/src/lib/hash/sha3/sha3.h
+++ b/src/lib/hash/sha3/sha3.h
@@ -31,6 +31,7 @@ class BOTAN_DLL SHA_3 : public HashFunction
size_t output_length() const override { return m_output_bits / 8; }
HashFunction* clone() const override;
+ std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;
diff --git a/src/lib/hash/shake/shake.cpp b/src/lib/hash/shake/shake.cpp
index 97ee0c4da..329aec080 100644
--- a/src/lib/hash/shake/shake.cpp
+++ b/src/lib/hash/shake/shake.cpp
@@ -30,6 +30,11 @@ HashFunction* SHAKE_128::clone() const
return new SHAKE_128(m_output_bits);
}
+std::unique_ptr<HashFunction> SHAKE_128::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHAKE_128(*this));
+ }
+
void SHAKE_128::clear()
{
zeroise(m_S);
@@ -73,6 +78,11 @@ HashFunction* SHAKE_256::clone() const
return new SHAKE_256(m_output_bits);
}
+std::unique_ptr<HashFunction> SHAKE_256::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SHAKE_256(*this));
+ }
+
void SHAKE_256::clear()
{
zeroise(m_S);
diff --git a/src/lib/hash/shake/shake.h b/src/lib/hash/shake/shake.h
index f24fda4fa..363e8be48 100644
--- a/src/lib/hash/shake/shake.h
+++ b/src/lib/hash/shake/shake.h
@@ -31,6 +31,7 @@ class BOTAN_DLL SHAKE_128 : public HashFunction
size_t output_length() const override { return m_output_bits / 8; }
HashFunction* clone() const override;
+ std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;
@@ -62,6 +63,7 @@ class BOTAN_DLL SHAKE_256 : public HashFunction
size_t output_length() const override { return m_output_bits / 8; }
HashFunction* clone() const override;
+ std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;
diff --git a/src/lib/hash/skein/skein_512.cpp b/src/lib/hash/skein/skein_512.cpp
index ae059f085..eaa3090a4 100644
--- a/src/lib/hash/skein/skein_512.cpp
+++ b/src/lib/hash/skein/skein_512.cpp
@@ -38,6 +38,18 @@ HashFunction* Skein_512::clone() const
return new Skein_512(m_output_bits, m_personalization);
}
+std::unique_ptr<HashFunction> Skein_512::copy_state() const
+ {
+ std::unique_ptr<Skein_512> copy(new Skein_512(m_output_bits, m_personalization));
+
+ copy->m_threefish->m_K = this->m_threefish->m_K;
+ copy->m_T = this->m_T;
+ copy->m_buffer = this->m_buffer;
+ copy->m_buf_pos = this->m_buf_pos;
+
+ return std::move(copy);
+ }
+
void Skein_512::clear()
{
zeroise(m_buffer);
diff --git a/src/lib/hash/skein/skein_512.h b/src/lib/hash/skein/skein_512.h
index 32323807e..ad47e4b1c 100644
--- a/src/lib/hash/skein/skein_512.h
+++ b/src/lib/hash/skein/skein_512.h
@@ -33,6 +33,7 @@ class BOTAN_DLL Skein_512 final : public HashFunction
size_t output_length() const override { return m_output_bits / 8; }
HashFunction* clone() const override;
+ std::unique_ptr<HashFunction> copy_state() const override;
std::string name() const override;
void clear() override;
private:
diff --git a/src/lib/hash/sm3/sm3.cpp b/src/lib/hash/sm3/sm3.cpp
index a64a9a5e7..c2eeb4cdf 100644
--- a/src/lib/hash/sm3/sm3.cpp
+++ b/src/lib/hash/sm3/sm3.cpp
@@ -9,6 +9,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> SM3::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new SM3(*this));
+ }
+
namespace {
const uint32_t SM3_IV[] = {
diff --git a/src/lib/hash/sm3/sm3.h b/src/lib/hash/sm3/sm3.h
index c5dacdf3a..dd76ab4d0 100644
--- a/src/lib/hash/sm3/sm3.h
+++ b/src/lib/hash/sm3/sm3.h
@@ -26,6 +26,7 @@ class BOTAN_DLL SM3 final : public MDx_HashFunction
std::string name() const override { return "SM3"; }
size_t output_length() const override { return SM3_DIGEST_BYTES; }
HashFunction* clone() const override { return new SM3; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/hash/tiger/tiger.cpp b/src/lib/hash/tiger/tiger.cpp
index b09e03d2e..0851742c0 100644
--- a/src/lib/hash/tiger/tiger.cpp
+++ b/src/lib/hash/tiger/tiger.cpp
@@ -11,6 +11,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> Tiger::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new Tiger(*this));
+ }
+
namespace {
/*
diff --git a/src/lib/hash/tiger/tiger.h b/src/lib/hash/tiger/tiger.h
index 32ae26258..73907b71f 100644
--- a/src/lib/hash/tiger/tiger.h
+++ b/src/lib/hash/tiger/tiger.h
@@ -26,6 +26,8 @@ class BOTAN_DLL Tiger final : public MDx_HashFunction
return new Tiger(output_length(), m_passes);
}
+ std::unique_ptr<HashFunction> copy_state() const override;
+
void clear() override;
/**
diff --git a/src/lib/hash/whirlpool/whirlpool.cpp b/src/lib/hash/whirlpool/whirlpool.cpp
index 64350fd24..f78cc7572 100644
--- a/src/lib/hash/whirlpool/whirlpool.cpp
+++ b/src/lib/hash/whirlpool/whirlpool.cpp
@@ -9,6 +9,11 @@
namespace Botan {
+std::unique_ptr<HashFunction> Whirlpool::copy_state() const
+ {
+ return std::unique_ptr<HashFunction>(new Whirlpool(*this));
+ }
+
/*
* Whirlpool Compression Function
*/
diff --git a/src/lib/hash/whirlpool/whrlpool.h b/src/lib/hash/whirlpool/whrlpool.h
index 606fc3257..ed541e497 100644
--- a/src/lib/hash/whirlpool/whrlpool.h
+++ b/src/lib/hash/whirlpool/whrlpool.h
@@ -21,6 +21,7 @@ class BOTAN_DLL Whirlpool final : public MDx_HashFunction
std::string name() const override { return "Whirlpool"; }
size_t output_length() const override { return 64; }
HashFunction* clone() const override { return new Whirlpool; }
+ std::unique_ptr<HashFunction> copy_state() const override;
void clear() override;
diff --git a/src/lib/prov/openssl/openssl_block.cpp b/src/lib/prov/openssl/openssl_block.cpp
index 15d3bdc56..5d5cf0b47 100644
--- a/src/lib/prov/openssl/openssl_block.cpp
+++ b/src/lib/prov/openssl/openssl_block.cpp
@@ -37,14 +37,14 @@ class OpenSSL_BlockCipher : public BlockCipher
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
{
int out_len = 0;
- if(!EVP_EncryptUpdate(&m_encrypt, out, &out_len, in, blocks * m_block_sz))
+ if(!EVP_EncryptUpdate(m_encrypt, out, &out_len, in, blocks * m_block_sz))
throw OpenSSL_Error("EVP_EncryptUpdate");
}
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
{
int out_len = 0;
- if(!EVP_DecryptUpdate(&m_decrypt, out, &out_len, in, blocks * m_block_sz))
+ if(!EVP_DecryptUpdate(m_decrypt, out, &out_len, in, blocks * m_block_sz))
throw OpenSSL_Error("EVP_DecryptUpdate");
}
@@ -53,7 +53,8 @@ class OpenSSL_BlockCipher : public BlockCipher
size_t m_block_sz;
Key_Length_Specification m_cipher_key_spec;
std::string m_cipher_name;
- mutable EVP_CIPHER_CTX m_encrypt, m_decrypt;
+ mutable EVP_CIPHER_CTX *m_encrypt;
+ mutable EVP_CIPHER_CTX *m_decrypt;
};
OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
@@ -65,17 +66,19 @@ OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
- EVP_CIPHER_CTX_init(&m_encrypt);
- EVP_CIPHER_CTX_init(&m_decrypt);
+ m_encrypt = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_init(m_encrypt);
+ m_decrypt = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_init(m_decrypt);
- if(!EVP_EncryptInit_ex(&m_encrypt, algo, nullptr, nullptr, nullptr))
+ if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
throw OpenSSL_Error("EVP_EncryptInit_ex");
- if(!EVP_DecryptInit_ex(&m_decrypt, algo, nullptr, nullptr, nullptr))
+ if(!EVP_DecryptInit_ex(m_decrypt, algo, nullptr, nullptr, nullptr))
throw OpenSSL_Error("EVP_DecryptInit_ex");
- if(!EVP_CIPHER_CTX_set_padding(&m_encrypt, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_encrypt, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding encrypt");
- if(!EVP_CIPHER_CTX_set_padding(&m_decrypt, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_decrypt, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding decrypt");
}
@@ -91,24 +94,26 @@ OpenSSL_BlockCipher::OpenSSL_BlockCipher(const std::string& algo_name,
if(EVP_CIPHER_mode(algo) != EVP_CIPH_ECB_MODE)
throw Invalid_Argument("OpenSSL_BlockCipher: Non-ECB EVP was passed in");
- EVP_CIPHER_CTX_init(&m_encrypt);
- EVP_CIPHER_CTX_init(&m_decrypt);
+ m_encrypt = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_init(m_encrypt);
+ m_decrypt = EVP_CIPHER_CTX_new();
+ EVP_CIPHER_CTX_init(m_decrypt);
- if(!EVP_EncryptInit_ex(&m_encrypt, algo, nullptr, nullptr, nullptr))
+ if(!EVP_EncryptInit_ex(m_encrypt, algo, nullptr, nullptr, nullptr))
throw OpenSSL_Error("EVP_EncryptInit_ex");
- if(!EVP_DecryptInit_ex(&m_decrypt, algo, nullptr, nullptr, nullptr))
+ if(!EVP_DecryptInit_ex(m_decrypt, algo, nullptr, nullptr, nullptr))
throw OpenSSL_Error("EVP_DecryptInit_ex");
- if(!EVP_CIPHER_CTX_set_padding(&m_encrypt, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_encrypt, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding encrypt");
- if(!EVP_CIPHER_CTX_set_padding(&m_decrypt, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_decrypt, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding decrypt");
}
OpenSSL_BlockCipher::~OpenSSL_BlockCipher()
{
- EVP_CIPHER_CTX_cleanup(&m_encrypt);
- EVP_CIPHER_CTX_cleanup(&m_decrypt);
+ EVP_CIPHER_CTX_cleanup(m_encrypt);
+ EVP_CIPHER_CTX_cleanup(m_decrypt);
}
/*
@@ -123,14 +128,14 @@ void OpenSSL_BlockCipher::key_schedule(const uint8_t key[], size_t length)
full_key += std::make_pair(key, 8);
}
else
- if(EVP_CIPHER_CTX_set_key_length(&m_encrypt, length) == 0 ||
- EVP_CIPHER_CTX_set_key_length(&m_decrypt, length) == 0)
+ if(EVP_CIPHER_CTX_set_key_length(m_encrypt, length) == 0 ||
+ EVP_CIPHER_CTX_set_key_length(m_decrypt, length) == 0)
throw Invalid_Argument("OpenSSL_BlockCipher: Bad key length for " +
m_cipher_name);
- if(!EVP_EncryptInit_ex(&m_encrypt, nullptr, nullptr, full_key.data(), nullptr))
+ if(!EVP_EncryptInit_ex(m_encrypt, nullptr, nullptr, full_key.data(), nullptr))
throw OpenSSL_Error("EVP_EncryptInit_ex");
- if(!EVP_DecryptInit_ex(&m_decrypt, nullptr, nullptr, full_key.data(), nullptr))
+ if(!EVP_DecryptInit_ex(m_decrypt, nullptr, nullptr, full_key.data(), nullptr))
throw OpenSSL_Error("EVP_DecryptInit_ex");
}
@@ -140,7 +145,7 @@ void OpenSSL_BlockCipher::key_schedule(const uint8_t key[], size_t length)
BlockCipher* OpenSSL_BlockCipher::clone() const
{
return new OpenSSL_BlockCipher(m_cipher_name,
- EVP_CIPHER_CTX_cipher(&m_encrypt),
+ EVP_CIPHER_CTX_cipher(m_encrypt),
m_cipher_key_spec.minimum_keylength(),
m_cipher_key_spec.maximum_keylength(),
m_cipher_key_spec.keylength_multiple());
@@ -151,21 +156,21 @@ BlockCipher* OpenSSL_BlockCipher::clone() const
*/
void OpenSSL_BlockCipher::clear()
{
- const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&m_encrypt);
+ const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_encrypt);
- if(!EVP_CIPHER_CTX_cleanup(&m_encrypt))
+ if(!EVP_CIPHER_CTX_cleanup(m_encrypt))
throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup encrypt");
- if(!EVP_CIPHER_CTX_cleanup(&m_decrypt))
+ if(!EVP_CIPHER_CTX_cleanup(m_decrypt))
throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup decrypt");
- EVP_CIPHER_CTX_init(&m_encrypt);
- EVP_CIPHER_CTX_init(&m_decrypt);
- if(!EVP_EncryptInit_ex(&m_encrypt, algo, nullptr, nullptr, nullptr))
+ 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");
- if(!EVP_DecryptInit_ex(&m_decrypt, algo, nullptr, nullptr, nullptr))
+ if(!EVP_DecryptInit_ex(m_decrypt, algo, nullptr, nullptr, nullptr))
throw OpenSSL_Error("EVP_DecryptInit_ex");
- if(!EVP_CIPHER_CTX_set_padding(&m_encrypt, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_encrypt, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding encrypt");
- if(!EVP_CIPHER_CTX_set_padding(&m_decrypt, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_decrypt, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding decrypt");
}
diff --git a/src/lib/prov/openssl/openssl_ec.cpp b/src/lib/prov/openssl/openssl_ec.cpp
index 4b8afb5ed..0b23fa5e3 100644
--- a/src/lib/prov/openssl/openssl_ec.cpp
+++ b/src/lib/prov/openssl/openssl_ec.cpp
@@ -148,13 +148,18 @@ class OpenSSL_ECDSA_Verification_Operation : public PK_Ops::Verification_with_EM
std::unique_ptr<ECDSA_SIG, std::function<void (ECDSA_SIG*)>> sig(nullptr, ECDSA_SIG_free);
sig.reset(::ECDSA_SIG_new());
- sig->r = BN_bin2bn(sig_bytes , sig_len / 2, nullptr);
- if(!sig->r)
- throw OpenSSL_Error("BN_bin2bn sig r");
- sig->s = BN_bin2bn(sig_bytes + sig_len / 2, sig_len / 2, nullptr);
- if(!sig->s)
+ BIGNUM* r = BN_bin2bn(sig_bytes , sig_len / 2, nullptr);
+ BIGNUM* s = BN_bin2bn(sig_bytes + sig_len / 2, sig_len / 2, nullptr);
+ if(r == nullptr || s == nullptr)
throw OpenSSL_Error("BN_bin2bn sig s");
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ sig->r = r;
+ sig->s = s;
+#else
+ ECDSA_SIG_set0(sig.get(), r, s);
+#endif
+
const int res = ECDSA_do_verify(msg, msg_len, sig.get(), m_ossl_ec.get());
if(res < 0)
throw OpenSSL_Error("ECDSA_do_verify");
@@ -193,11 +198,21 @@ class OpenSSL_ECDSA_Signing_Operation : public PK_Ops::Signature_with_EMSA
throw OpenSSL_Error("ECDSA_do_sign");
const size_t order_bytes = (m_order_bits + 7) / 8;
- const size_t r_bytes = BN_num_bytes(sig->r);
- const size_t s_bytes = BN_num_bytes(sig->s);
+
+#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*order_bytes);
- BN_bn2bin(sig->r, &sigval[order_bytes - r_bytes]);
- BN_bn2bin(sig->s, &sigval[2*order_bytes - s_bytes]);
+ BN_bn2bin(r, &sigval[order_bytes - r_bytes]);
+ BN_bn2bin(s, &sigval[2*order_bytes - s_bytes]);
return sigval;
}
diff --git a/src/lib/prov/openssl/openssl_hash.cpp b/src/lib/prov/openssl/openssl_hash.cpp
index 05e97a4e3..4b3e01ac5 100644
--- a/src/lib/prov/openssl/openssl_hash.cpp
+++ b/src/lib/prov/openssl/openssl_hash.cpp
@@ -19,8 +19,8 @@ class OpenSSL_HashFunction : public HashFunction
public:
void clear() override
{
- const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
- if(!EVP_DigestInit_ex(&m_md, algo, nullptr))
+ const EVP_MD* algo = EVP_MD_CTX_md(m_md);
+ if(!EVP_DigestInit_ex(m_md, algo, nullptr))
throw OpenSSL_Error("EVP_DigestInit_ex");
}
@@ -29,50 +29,71 @@ class OpenSSL_HashFunction : public HashFunction
HashFunction* clone() const override
{
- const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
+ const EVP_MD* algo = EVP_MD_CTX_md(m_md);
return new OpenSSL_HashFunction(name(), algo);
}
+ std::unique_ptr<HashFunction> copy_state() const override
+ {
+ std::unique_ptr<OpenSSL_HashFunction> copy(new OpenSSL_HashFunction(m_name, nullptr));
+ EVP_MD_CTX_copy(copy->m_md, m_md);
+ return std::move(copy);
+ }
+
size_t output_length() const override
{
- return EVP_MD_size(EVP_MD_CTX_md(&m_md));
+ 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));
+ return EVP_MD_block_size(EVP_MD_CTX_md(m_md));
}
OpenSSL_HashFunction(const std::string& name, const EVP_MD* md) : m_name(name)
{
- EVP_MD_CTX_init(&m_md);
- if(!EVP_DigestInit_ex(&m_md, md, nullptr))
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ m_md = EVP_MD_CTX_create();
+#else
+ m_md = EVP_MD_CTX_new();
+#endif
+
+ EVP_MD_CTX_init(m_md);
+ if(md && !EVP_DigestInit_ex(m_md, md, nullptr))
throw OpenSSL_Error("EVP_DigestInit_ex");
}
+ OpenSSL_HashFunction(EVP_MD_CTX* ctx) : m_md(ctx)
+ {
+ }
+
~OpenSSL_HashFunction()
{
- EVP_MD_CTX_cleanup(&m_md);
+#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))
+ if(!EVP_DigestUpdate(m_md, input, length))
throw OpenSSL_Error("EVP_DigestUpdate");
}
void final_result(uint8_t output[]) override
{
- if(!EVP_DigestFinal_ex(&m_md, output, nullptr))
+ if(!EVP_DigestFinal_ex(m_md, output, nullptr))
throw OpenSSL_Error("EVP_DigestFinal_ex");
- const EVP_MD* algo = EVP_MD_CTX_md(&m_md);
- if(!EVP_DigestInit_ex(&m_md, algo, nullptr))
+ const EVP_MD* algo = EVP_MD_CTX_md(m_md);
+ if(!EVP_DigestInit_ex(m_md, algo, nullptr))
throw OpenSSL_Error("EVP_DigestInit_ex");
}
std::string m_name;
- EVP_MD_CTX m_md;
+ EVP_MD_CTX* m_md;
};
}
diff --git a/src/lib/prov/openssl/openssl_mode.cpp b/src/lib/prov/openssl/openssl_mode.cpp
index 184bdada7..36f19eaec 100644
--- a/src/lib/prov/openssl/openssl_mode.cpp
+++ b/src/lib/prov/openssl/openssl_mode.cpp
@@ -44,7 +44,7 @@ class BOTAN_DLL OpenSSL_Cipher_Mode : public Cipher_Mode
const std::string m_mode_name;
const Cipher_Dir m_direction;
size_t m_block_size;
- EVP_CIPHER_CTX m_cipher;
+ EVP_CIPHER_CTX* m_cipher;
};
OpenSSL_Cipher_Mode::OpenSSL_Cipher_Mode(const std::string& name,
@@ -58,17 +58,18 @@ OpenSSL_Cipher_Mode::OpenSSL_Cipher_Mode(const std::string& name,
if(EVP_CIPHER_mode(algo) != EVP_CIPH_CBC_MODE)
throw Invalid_Argument("OpenSSL_BlockCipher: Non-CBC EVP was passed in");
- EVP_CIPHER_CTX_init(&m_cipher);
- if(!EVP_CipherInit_ex(&m_cipher, algo, nullptr, nullptr, nullptr,
+ m_cipher = EVP_CIPHER_CTX_new();
+ 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");
- if(!EVP_CIPHER_CTX_set_padding(&m_cipher, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_cipher, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding");
}
OpenSSL_Cipher_Mode::~OpenSSL_Cipher_Mode()
{
- EVP_CIPHER_CTX_cleanup(&m_cipher);
+ EVP_CIPHER_CTX_free(m_cipher);
}
void OpenSSL_Cipher_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
@@ -77,7 +78,7 @@ void OpenSSL_Cipher_Mode::start_msg(const uint8_t nonce[], size_t nonce_len)
throw Invalid_IV_Length(name(), nonce_len);
if(nonce_len)
{
- if(!EVP_CipherInit_ex(&m_cipher, nullptr, nullptr, nullptr, nonce, -1))
+ if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nonce, -1))
throw OpenSSL_Error("EVP_CipherInit_ex nonce");
}
}
@@ -91,7 +92,7 @@ size_t OpenSSL_Cipher_Mode::process(uint8_t msg[], size_t msg_len)
int outl = msg_len;
secure_vector<uint8_t> out(outl);
- if(!EVP_CipherUpdate(&m_cipher, out.data(), &outl, msg, msg_len))
+ if(!EVP_CipherUpdate(m_cipher, out.data(), &outl, msg, msg_len))
throw OpenSSL_Error("EVP_CipherUpdate");
memcpy(msg, out.data(), outl);
return outl;
@@ -108,7 +109,7 @@ void OpenSSL_Cipher_Mode::finish(secure_vector<uint8_t>& buffer,
int outl = buf_size - written;
secure_vector<uint8_t> out(outl);
- if(!EVP_CipherFinal_ex(&m_cipher, out.data(), &outl))
+ if(!EVP_CipherFinal_ex(m_cipher, out.data(), &outl))
throw OpenSSL_Error("EVP_CipherFinal_ex");
memcpy(buf + written, out.data(), outl);
written += outl;
@@ -145,34 +146,34 @@ size_t OpenSSL_Cipher_Mode::output_length(size_t input_length) const
void OpenSSL_Cipher_Mode::clear()
{
- const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(&m_cipher);
+ const EVP_CIPHER* algo = EVP_CIPHER_CTX_cipher(m_cipher);
- if(!EVP_CIPHER_CTX_cleanup(&m_cipher))
+ if(!EVP_CIPHER_CTX_cleanup(m_cipher))
throw OpenSSL_Error("EVP_CIPHER_CTX_cleanup");
- EVP_CIPHER_CTX_init(&m_cipher);
- if(!EVP_CipherInit_ex(&m_cipher, algo, nullptr, nullptr, nullptr,
+ 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");
- if(!EVP_CIPHER_CTX_set_padding(&m_cipher, 0))
+ if(!EVP_CIPHER_CTX_set_padding(m_cipher, 0))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_padding clear");
}
void OpenSSL_Cipher_Mode::reset()
{
- if(!EVP_CipherInit_ex(&m_cipher, nullptr, nullptr, nullptr, nullptr, -1))
+ if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, nullptr, nullptr, -1))
throw OpenSSL_Error("EVP_CipherInit_ex clear");
}
Key_Length_Specification OpenSSL_Cipher_Mode::key_spec() const
{
- return Key_Length_Specification(EVP_CIPHER_CTX_key_length(&m_cipher));
+ return Key_Length_Specification(EVP_CIPHER_CTX_key_length(m_cipher));
}
void OpenSSL_Cipher_Mode::key_schedule(const uint8_t key[], size_t length)
{
- if(!EVP_CIPHER_CTX_set_key_length(&m_cipher, length))
+ if(!EVP_CIPHER_CTX_set_key_length(m_cipher, length))
throw OpenSSL_Error("EVP_CIPHER_CTX_set_key_length");
- if(!EVP_CipherInit_ex(&m_cipher, nullptr, nullptr, key, nullptr, -1))
+ if(!EVP_CipherInit_ex(m_cipher, nullptr, nullptr, key, nullptr, -1))
throw OpenSSL_Error("EVP_CipherInit_ex key");
}
diff --git a/src/lib/prov/openssl/openssl_rsa.cpp b/src/lib/prov/openssl/openssl_rsa.cpp
index 8c25d00ef..f8b2b82d6 100644
--- a/src/lib/prov/openssl/openssl_rsa.cpp
+++ b/src/lib/prov/openssl/openssl_rsa.cpp
@@ -152,7 +152,14 @@ class OpenSSL_RSA_Verification_Operation : public PK_Ops::Verification_with_EMSA
throw OpenSSL_Error("d2i_RSAPublicKey");
}
- size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
+ 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; }
@@ -215,7 +222,14 @@ class OpenSSL_RSA_Signing_Operation : public PK_Ops::Signature_with_EMSA
return outbuf;
}
- size_t max_input_bits() const override { return ::BN_num_bits(m_openssl_rsa->n) - 1; }
+ 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;
@@ -269,10 +283,10 @@ make_openssl_rsa_private_key(RandomNumberGenerator& rng, size_t rsa_bits)
std::unique_ptr<RSA, std::function<void (RSA*)>> rsa(RSA_new(), RSA_free);
if(!rsa)
throw OpenSSL_Error("RSA_new");
- if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), NULL))
+ if(!RSA_generate_key_ex(rsa.get(), rsa_bits, bn.get(), nullptr))
throw OpenSSL_Error("RSA_generate_key_ex");
- uint8_t* der = NULL;
+ uint8_t* der = nullptr;
int bytes = i2d_RSAPrivateKey(rsa.get(), &der);
if(bytes < 0)
throw OpenSSL_Error("i2d_RSAPrivateKey");
diff --git a/src/tests/test_hash.cpp b/src/tests/test_hash.cpp
index 9c6051f49..9ac3e7d4e 100644
--- a/src/tests/test_hash.cpp
+++ b/src/tests/test_hash.cpp
@@ -69,11 +69,19 @@ class Hash_Function_Tests : public Text_Based_Test
result.test_eq(provider, "hashing after clear", hash->final(), expected);
// TODO: feed in random pieces to fully test buffering
- if(input.size() > 1)
+ if(input.size() > 5)
{
hash->update(input[0]);
+
+ std::unique_ptr<Botan::HashFunction> fork = hash->copy_state();
+ // verify fork copy doesn't affect original computation
+ fork->update(&input[1], input.size() - 2);
+
hash->update(&input[1], input.size() - 1);
result.test_eq(provider, "hashing split", hash->final(), expected);
+
+ fork->update(&input[input.size() - 1], 1);
+ result.test_eq(provider, "hashing split", fork->final(), expected);
}
if(hash->hash_block_size() > 0)