diff options
author | Jack Lloyd <[email protected]> | 2017-05-22 22:18:21 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-05-22 22:18:21 -0400 |
commit | cb91be3967edab3688b744e150a98d96db89b2fd (patch) | |
tree | ad818dc31b2a6b2c1fb894cbf3cfcf2a70213bca | |
parent | 22797129ff2f746f96d3725ab45e043c506664f3 (diff) | |
parent | b136d4e7ca350bb388a1a6d638b1010a2b1e5b73 (diff) |
Merge GH #1056 Add HashFunction::copy_state and port to OpenSSL 1.1.0
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) |