From 1925623bbcc1390e51d5068697fb2889feea4ea6 Mon Sep 17 00:00:00 2001 From: Yaroslav Lelkin Date: Tue, 31 Dec 2024 14:31:09 +0500 Subject: [PATCH 1/5] use BN_check_prime instead of BN_is_prime_ex BN_is_prime_ex is deprecated in OpenSSL 3.0, and all OpenSSL versions lesser than 3.0 are deprecated as well. Use BN_check_prime according to the migration guide (https://docs.openssl.org/3.0/man7/migration_guide/). --- base/openssl_help.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/base/openssl_help.h b/base/openssl_help.h index 8ed18b6b..01a5e7d2 100644 --- a/base/openssl_help.h +++ b/base/openssl_help.h @@ -272,12 +272,7 @@ class BigNum { if (failed() || !_data) { return false; } - constexpr auto kMillerRabinIterationCount = 64; - const auto result = BN_is_prime_ex( - raw(), - kMillerRabinIterationCount, - context.raw(), - nullptr); + const auto result = BN_check_prime(raw(), context.raw(), nullptr); if (result == 1) { return true; } else if (result != 0) { From 696af9ab928b1dc60c89ae54adb960d9a620c193 Mon Sep 17 00:00:00 2001 From: Yaroslav Lelkin Date: Tue, 31 Dec 2024 17:59:32 +0500 Subject: [PATCH 2/5] replace SHA* functions with EVP api SHA* functions are deprecated in OpenSSL 3.0 and adviced to replace with EVP api in migration guide (https://docs.openssl.org/3.0/man7/migration_guide/). Also, using generic EVP api allows us to clean up code a bit. --- base/openssl_help.h | 127 +++++++++++++------------------------------- 1 file changed, 36 insertions(+), 91 deletions(-) diff --git a/base/openssl_help.h b/base/openssl_help.h index 01a5e7d2..caaaf63a 100644 --- a/base/openssl_help.h +++ b/base/openssl_help.h @@ -447,62 +447,40 @@ class BigNum { namespace details { -template -inline void ShaUpdate(Context context, Method method, Arg &&arg) { - const auto span = bytes::make_span(arg); - method(context, span.data(), span.size()); -} +void ShaImpl(bytes::span dst, auto md, auto &&...args) { + Expects(dst.size() >= EVP_MD_size(md)); -template -inline void ShaUpdate(Context context, Method method, Arg &&arg, Args &&...args) { - const auto span = bytes::make_span(arg); - method(context, span.data(), span.size()); - ShaUpdate(context, method, args...); -} + EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); + if constexpr (sizeof...(args) == 1) { + EVP_MD_CTX_set_flags(mdctx, EVP_MD_CTX_FLAG_ONESHOT); + } -template -inline void Sha( - bytes::span dst, - Method method, - bytes::const_span data) { - Expects(dst.size() >= Size); + EVP_DigestInit_ex(mdctx, md, nullptr); - method( - reinterpret_cast(data.data()), - data.size(), - reinterpret_cast(dst.data())); + const auto update = [&mdctx](auto &&arg) { + const auto span = bytes::const_span(arg); + EVP_DigestUpdate(mdctx, arg.data(), arg.size()); + }; + (update(args), ...); + + EVP_DigestFinal(mdctx, reinterpret_cast(dst.data()), nullptr); + EVP_MD_CTX_free(mdctx); } -template -[[nodiscard]] inline bytes::vector Sha( - Method method, - bytes::const_span data) { - auto bytes = bytes::vector(Size); - Sha(bytes, method, data); - return bytes; +inline void ShaTo(bytes::span dst, auto mdname, bytes::const_span data) { + auto md = EVP_MD_fetch(nullptr, mdname, nullptr); + Expects(dst.size() >= EVP_MD_size(md)); + details::ShaImpl(dst, md, data); + EVP_MD_free(md); } -template < - size_type Size, - typename Context, - typename Init, - typename Update, - typename Finalize, - typename ...Args, - typename = std::enable_if_t<(sizeof...(Args) > 1)>> -[[nodiscard]] bytes::vector Sha( - Context context, - Init init, - Update update, - Finalize finalize, - Args &&...args) { - auto bytes = bytes::vector(Size); - - init(&context); - ShaUpdate(&context, update, args...); - finalize(reinterpret_cast(bytes.data()), &context); - - return bytes; +template +[[nodiscard]] inline bytes::vector Sha(auto mdname, Args &&...args) { + auto md = EVP_MD_fetch(nullptr, mdname, nullptr); + bytes::vector dst(EVP_MD_size(md)); + details::ShaImpl(dst, md, args...); + EVP_MD_free(md); + return dst; } template < @@ -532,64 +510,31 @@ constexpr auto kSha1Size = size_type(SHA_DIGEST_LENGTH); constexpr auto kSha256Size = size_type(SHA256_DIGEST_LENGTH); constexpr auto kSha512Size = size_type(SHA512_DIGEST_LENGTH); -[[nodiscard]] inline bytes::vector Sha1(bytes::const_span data) { - return details::Sha(SHA1, data); -} - inline void Sha1To(bytes::span dst, bytes::const_span data) { - details::Sha(dst, SHA1, data); + details::ShaTo(dst, "SHA1", data); } -template < - typename ...Args, - typename = std::enable_if_t<(sizeof...(Args) > 1)>> +template [[nodiscard]] inline bytes::vector Sha1(Args &&...args) { - return details::Sha( - SHA_CTX(), - SHA1_Init, - SHA1_Update, - SHA1_Final, - args...); -} - -[[nodiscard]] inline bytes::vector Sha256(bytes::const_span data) { - return details::Sha(SHA256, data); + return details::Sha("SHA1", args...); } inline void Sha256To(bytes::span dst, bytes::const_span data) { - details::Sha(dst, SHA256, data); + details::ShaTo(dst, "SHA256", data); } -template < - typename ...Args, - typename = std::enable_if_t<(sizeof...(Args) > 1)>> +template [[nodiscard]] inline bytes::vector Sha256(Args &&...args) { - return details::Sha( - SHA256_CTX(), - SHA256_Init, - SHA256_Update, - SHA256_Final, - args...); -} - -[[nodiscard]] inline bytes::vector Sha512(bytes::const_span data) { - return details::Sha(SHA512, data); + return details::Sha("SHA256", args...); } inline void Sha512To(bytes::span dst, bytes::const_span data) { - details::Sha(dst, SHA512, data); + details::ShaTo(dst, "SHA512", data); } -template < - typename ...Args, - typename = std::enable_if_t<(sizeof...(Args) > 1)>> +template [[nodiscard]] inline bytes::vector Sha512(Args &&...args) { - return details::Sha( - SHA512_CTX(), - SHA512_Init, - SHA512_Update, - SHA512_Final, - args...); + return details::Sha("SHA512", args...); } inline bytes::vector Pbkdf2Sha512( From 52a858fa061e7c29a1293a8f86854a3e94f29f2b Mon Sep 17 00:00:00 2001 From: Yaroslav Lelkin Date: Sun, 5 Jan 2025 19:23:00 +0500 Subject: [PATCH 3/5] replace EVP_DigestFinal with EVP_DigestFinal_ex EVP_DigestFinal is deprecated according to OpenSSL 3.0 documentation --- base/openssl_help.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/openssl_help.h b/base/openssl_help.h index caaaf63a..62dcb833 100644 --- a/base/openssl_help.h +++ b/base/openssl_help.h @@ -463,7 +463,7 @@ void ShaImpl(bytes::span dst, auto md, auto &&...args) { }; (update(args), ...); - EVP_DigestFinal(mdctx, reinterpret_cast(dst.data()), nullptr); + EVP_DigestFinal_ex(mdctx, reinterpret_cast(dst.data()), nullptr); EVP_MD_CTX_free(mdctx); } From 2719b630d555e24f774ef14a92fe85b7880fde83 Mon Sep 17 00:00:00 2001 From: Yaroslav Lelkin Date: Sun, 5 Jan 2025 19:29:59 +0500 Subject: [PATCH 4/5] ensure that ShaImpl is called with at least 1 arg Otherwise such call makes no sense, and result of EVP_DigestFinal_ex is undefined. --- base/openssl_help.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/openssl_help.h b/base/openssl_help.h index 62dcb833..805f2593 100644 --- a/base/openssl_help.h +++ b/base/openssl_help.h @@ -447,7 +447,10 @@ class BigNum { namespace details { -void ShaImpl(bytes::span dst, auto md, auto &&...args) { +template < + typename ...Args, + typename = std::enable_if_t<(sizeof...(Args) >= 1)>> +void ShaImpl(bytes::span dst, auto md, Args &&...args) { Expects(dst.size() >= EVP_MD_size(md)); EVP_MD_CTX *mdctx = EVP_MD_CTX_create(); From f844b9bd5af90562ef96e9003dc2c79bf2298986 Mon Sep 17 00:00:00 2001 From: Yaroslav Lelkin Date: Sun, 5 Jan 2025 19:44:59 +0500 Subject: [PATCH 5/5] replace EVP_MD_fetch with EVP_sha* functions --- base/openssl_help.h | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/base/openssl_help.h b/base/openssl_help.h index 805f2593..cb621dd8 100644 --- a/base/openssl_help.h +++ b/base/openssl_help.h @@ -470,19 +470,15 @@ void ShaImpl(bytes::span dst, auto md, Args &&...args) { EVP_MD_CTX_free(mdctx); } -inline void ShaTo(bytes::span dst, auto mdname, bytes::const_span data) { - auto md = EVP_MD_fetch(nullptr, mdname, nullptr); +inline void ShaTo(bytes::span dst, auto md, bytes::const_span data) { Expects(dst.size() >= EVP_MD_size(md)); details::ShaImpl(dst, md, data); - EVP_MD_free(md); } template -[[nodiscard]] inline bytes::vector Sha(auto mdname, Args &&...args) { - auto md = EVP_MD_fetch(nullptr, mdname, nullptr); +[[nodiscard]] inline bytes::vector Sha(auto md, Args &&...args) { bytes::vector dst(EVP_MD_size(md)); details::ShaImpl(dst, md, args...); - EVP_MD_free(md); return dst; } @@ -514,30 +510,30 @@ constexpr auto kSha256Size = size_type(SHA256_DIGEST_LENGTH); constexpr auto kSha512Size = size_type(SHA512_DIGEST_LENGTH); inline void Sha1To(bytes::span dst, bytes::const_span data) { - details::ShaTo(dst, "SHA1", data); + details::ShaTo(dst, EVP_sha1(), data); } template [[nodiscard]] inline bytes::vector Sha1(Args &&...args) { - return details::Sha("SHA1", args...); + return details::Sha(EVP_sha1(), args...); } inline void Sha256To(bytes::span dst, bytes::const_span data) { - details::ShaTo(dst, "SHA256", data); + details::ShaTo(dst, EVP_sha256(), data); } template [[nodiscard]] inline bytes::vector Sha256(Args &&...args) { - return details::Sha("SHA256", args...); + return details::Sha(EVP_sha256(), args...); } inline void Sha512To(bytes::span dst, bytes::const_span data) { - details::ShaTo(dst, "SHA512", data); + details::ShaTo(dst, EVP_sha512(), data); } template [[nodiscard]] inline bytes::vector Sha512(Args &&...args) { - return details::Sha("SHA512", args...); + return details::Sha(EVP_sha512(), args...); } inline bytes::vector Pbkdf2Sha512(