Skip to content

Commit

Permalink
LibCrypto: Introduce utility class for OpenSSL backed hashes
Browse files Browse the repository at this point in the history
This abstract class allows implementing hashes backed by OpenSSL with
very few lines of code, see next commit.
  • Loading branch information
devgianlu committed Dec 20, 2024
1 parent 199c663 commit fc9f17f
Showing 1 changed file with 91 additions and 0 deletions.
91 changes: 91 additions & 0 deletions Libraries/LibCrypto/Hash/OpenSSLHashFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2024, Altomani Gianluca <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#include <AK/ByteString.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/Types.h>
#include <LibCrypto/Hash/HashFunction.h>

#include <openssl/evp.h>

namespace Crypto::Hash {

template<typename T, size_t BlockS, size_t DigestS, typename DigestT = Digest<DigestS>>
class OpenSSLHashFunction : public HashFunction<BlockS, DigestS, DigestT> {
AK_MAKE_NONCOPYABLE(OpenSSLHashFunction);

public:
using HashFunction<BlockS, DigestS, DigestT>::update;

static NonnullOwnPtr<T> create()
{
auto* context = EVP_MD_CTX_new();
return make<T>(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<T> 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;
};

}

0 comments on commit fc9f17f

Please sign in to comment.