aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Cryptography/CryptoConstants.h1
-rw-r--r--src/common/Cryptography/CryptoHash.h38
-rw-r--r--src/common/Cryptography/HMAC.h81
3 files changed, 80 insertions, 40 deletions
diff --git a/src/common/Cryptography/CryptoConstants.h b/src/common/Cryptography/CryptoConstants.h
index 7e698a685e4..d9fad902ab6 100644
--- a/src/common/Cryptography/CryptoConstants.h
+++ b/src/common/Cryptography/CryptoConstants.h
@@ -24,6 +24,7 @@ namespace Trinity::Crypto
{
struct Constants
{
+ static constexpr size_t MD5_DIGEST_LENGTH_BYTES = 16;
static constexpr size_t SHA1_DIGEST_LENGTH_BYTES = 20;
static constexpr size_t SHA256_DIGEST_LENGTH_BYTES = 32;
};
diff --git a/src/common/Cryptography/CryptoHash.h b/src/common/Cryptography/CryptoHash.h
index 56af9740c04..38f2047c30d 100644
--- a/src/common/Cryptography/CryptoHash.h
+++ b/src/common/Cryptography/CryptoHash.h
@@ -35,10 +35,10 @@ namespace Trinity::Impl
typedef EVP_MD const* (*HashCreator)();
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
- static EVP_MD_CTX* MakeCTX() { return EVP_MD_CTX_create(); }
+ static EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_create(); }
static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_destroy(ctx); }
#else
- static EVP_MD_CTX* MakeCTX() { return EVP_MD_CTX_new(); }
+ static EVP_MD_CTX* MakeCTX() noexcept { return EVP_MD_CTX_new(); }
static void DestroyCTX(EVP_MD_CTX* ctx) { EVP_MD_CTX_free(ctx); }
#endif
};
@@ -73,6 +73,16 @@ namespace Trinity::Impl
ASSERT(result == 1);
}
+ GenericHash(GenericHash const& right) : _ctx(GenericHashImpl::MakeCTX())
+ {
+ *this = right;
+ }
+
+ GenericHash(GenericHash&& right) noexcept
+ {
+ *this = std::move(right);
+ }
+
~GenericHash()
{
if (!_ctx)
@@ -81,6 +91,27 @@ namespace Trinity::Impl
_ctx = nullptr;
}
+ GenericHash& operator=(GenericHash const& right)
+ {
+ if (this == &right)
+ return *this;
+
+ int result = EVP_MD_CTX_copy(_ctx, right._ctx);
+ ASSERT(result == 1);
+ _digest = right._digest;
+ return *this;
+ }
+
+ GenericHash& operator=(GenericHash&& right) noexcept
+ {
+ if (this == &right)
+ return *this;
+
+ _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX());
+ _digest = std::exchange(right._digest, Digest{});
+ return *this;
+ }
+
void UpdateData(uint8 const* data, size_t len)
{
int result = EVP_DigestUpdate(_ctx, data, len);
@@ -98,8 +129,6 @@ namespace Trinity::Impl
int result = EVP_DigestFinal_ex(_ctx, _digest.data(), &length);
ASSERT(result == 1);
ASSERT(length == DIGEST_LENGTH);
- GenericHashImpl::DestroyCTX(_ctx);
- _ctx = nullptr;
}
Digest const& GetDigest() const { return _digest; }
@@ -112,6 +141,7 @@ namespace Trinity::Impl
namespace Trinity::Crypto
{
+ using MD5 = Trinity::Impl::GenericHash<EVP_md5, Constants::MD5_DIGEST_LENGTH_BYTES>;
using SHA1 = Trinity::Impl::GenericHash<EVP_sha1, Constants::SHA1_DIGEST_LENGTH_BYTES>;
using SHA256 = Trinity::Impl::GenericHash<EVP_sha256, Constants::SHA256_DIGEST_LENGTH_BYTES>;
}
diff --git a/src/common/Cryptography/HMAC.h b/src/common/Cryptography/HMAC.h
index 200955df832..b8db59a1ae9 100644
--- a/src/common/Cryptography/HMAC.h
+++ b/src/common/Cryptography/HMAC.h
@@ -19,41 +19,18 @@
#define TRINITY_HMAC_H
#include "CryptoConstants.h"
+#include "CryptoHash.h"
#include "Define.h"
#include "Errors.h"
#include <array>
#include <string>
#include <string_view>
-#include <openssl/hmac.h>
class BigNumber;
namespace Trinity::Impl
{
- struct HMACImpl
- {
- typedef EVP_MD const* (*HashCreator)();
-
-#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
- static HMAC_CTX* MakeCTX()
- {
- HMAC_CTX* ctx = new HMAC_CTX();
- HMAC_CTX_init(ctx);
- return ctx;
- }
-
- static void DestroyCTX(HMAC_CTX* ctx)
- {
- HMAC_CTX_cleanup(ctx);
- delete ctx;
- }
-#else
- static HMAC_CTX* MakeCTX() { return HMAC_CTX_new(); }
- static void DestroyCTX(HMAC_CTX* ctx) { HMAC_CTX_free(ctx); }
-#endif
- };
-
- template <HMACImpl::HashCreator HashCreator, size_t DigestLength>
+ template <GenericHashImpl::HashCreator HashCreator, size_t DigestLength>
class GenericHMAC
{
public:
@@ -78,25 +55,58 @@ namespace Trinity::Impl
return hash.GetDigest();
}
- GenericHMAC(uint8 const* seed, size_t len) : _ctx(HMACImpl::MakeCTX())
+ GenericHMAC(uint8 const* seed, size_t len) : _ctx(GenericHashImpl::MakeCTX()), _key(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, seed, len))
{
- int result = HMAC_Init_ex(_ctx, seed, len, HashCreator(), nullptr);
+ int result = EVP_DigestSignInit(_ctx, nullptr, HashCreator(), nullptr, _key);
ASSERT(result == 1);
}
template <typename Container>
GenericHMAC(Container const& container) : GenericHMAC(std::data(container), std::size(container)) {}
+ GenericHMAC(GenericHMAC const& right) : _ctx(GenericHashImpl::MakeCTX())
+ {
+ *this = right;
+ }
+
+ GenericHMAC(GenericHMAC&& right) noexcept
+ {
+ *this = std::move(right);
+ }
+
~GenericHMAC()
{
- if (!_ctx)
- return;
- HMACImpl::DestroyCTX(_ctx);
+ GenericHashImpl::DestroyCTX(_ctx);
_ctx = nullptr;
+ EVP_PKEY_free(_key);
+ _key = nullptr;
+ }
+
+ GenericHMAC& operator=(GenericHMAC const& right)
+ {
+ if (this == &right)
+ return *this;
+
+ int result = EVP_MD_CTX_copy(_ctx, right._ctx);
+ ASSERT(result == 1);
+ _key = right._key; // EVP_PKEY uses reference counting internally, just copy the pointer
+ _digest = right._digest;
+ return *this;
+ }
+
+ GenericHMAC& operator=(GenericHMAC&& right) noexcept
+ {
+ if (this == &right)
+ return *this;
+
+ _ctx = std::exchange(right._ctx, GenericHashImpl::MakeCTX());
+ _key = std::exchange(right._key, EVP_PKEY_new());
+ _digest = std::exchange(right._digest, Digest{});
+ return *this;
}
void UpdateData(uint8 const* data, size_t len)
{
- int result = HMAC_Update(_ctx, data, len);
+ int result = EVP_DigestSignUpdate(_ctx, data, len);
ASSERT(result == 1);
}
void UpdateData(std::string_view str) { UpdateData(reinterpret_cast<uint8 const*>(str.data()), str.size()); }
@@ -107,17 +117,16 @@ namespace Trinity::Impl
void Finalize()
{
- uint32 length = 0;
- int result = HMAC_Final(_ctx, _digest.data(), &length);
+ size_t length = 0;
+ int result = EVP_DigestSignFinal(_ctx, _digest.data(), &length);
ASSERT(result == 1);
ASSERT(length == DIGEST_LENGTH);
- HMACImpl::DestroyCTX(_ctx);
- _ctx = nullptr;
}
Digest const& GetDigest() const { return _digest; }
private:
- HMAC_CTX* _ctx;
+ EVP_MD_CTX* _ctx;
+ EVP_PKEY* _key;
Digest _digest = { };
};
}