diff --git a/Libraries/LibCrypto/Hash/OpenSSLHashFunction.h b/Libraries/LibCrypto/Hash/OpenSSLHashFunction.h new file mode 100644 index 0000000000000..a7fac1ce4188b --- /dev/null +++ b/Libraries/LibCrypto/Hash/OpenSSLHashFunction.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024, Altomani Gianluca + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace Crypto::Hash { + +template> +class OpenSSLHashFunction : public HashFunction { + AK_MAKE_NONCOPYABLE(OpenSSLHashFunction); + +public: + using HashFunction::update; + + static NonnullOwnPtr create() + { + auto* context = EVP_MD_CTX_new(); + return make(context); + } + + explicit OpenSSLHashFunction(EVP_MD const* type, EVP_MD_CTX* context) + : m_type(type) + , m_context(context) + { + OpenSSLHashFunction::reset(); + } + + virtual ~OpenSSLHashFunction() override + { + EVP_MD_CTX_free(m_context); + } + + virtual ByteString class_name() const override = 0; + + void update(u8 const* input, size_t length) override + { + VERIFY(EVP_DigestUpdate(m_context, input, length)); + } + + DigestT digest() override + { + DigestT digest; + VERIFY(EVP_DigestFinal_ex(m_context, digest.data, nullptr)); + reset(); + return digest; + } + + DigestT peek() override + { + auto c = copy(); + return c->digest(); + } + + void reset() override + { + VERIFY(EVP_DigestInit_ex(m_context, m_type, nullptr)); + } + + virtual NonnullOwnPtr copy() const + { + auto context = create(); + VERIFY(EVP_MD_CTX_copy_ex(context->m_context, m_context)); + return context; + } + + static DigestT hash(u8 const* data, size_t length) + { + auto md5 = create(); + md5->update(data, length); + return md5->digest(); + } + + static DigestT hash(ByteBuffer const& buffer) { return hash(buffer.data(), buffer.size()); } + static DigestT hash(StringView buffer) { return hash((u8 const*)buffer.characters_without_null_termination(), buffer.length()); } + +private: + EVP_MD const* m_type; + EVP_MD_CTX* m_context; +}; + +}