8#include <botan/internal/commoncrypto.h>
10#include <botan/hash.h>
11#include <botan/internal/buffer_slicer.h>
13#include <CommonCrypto/CommonCrypto.h>
20class CommonCrypto_HashFunction final :
public HashFunction {
22 struct digest_config_t {
27 int (*update)(CTX*,
const void*, CC_LONG len);
28 int (*
final)(
unsigned char*, CTX*);
31 void clear()
override {
32 if(m_info.init(&m_ctx) != 1)
33 throw CommonCrypto_Error(
"CC_" + m_info.name +
"_Init");
36 std::string provider()
const override {
return "commoncrypto"; }
38 std::string name()
const override {
return m_info.name; }
40 std::unique_ptr<HashFunction> new_object()
const override {
41 return std::make_unique<CommonCrypto_HashFunction>(m_info);
44 std::unique_ptr<HashFunction> copy_state()
const override {
45 return std::unique_ptr<CommonCrypto_HashFunction>(
new CommonCrypto_HashFunction(m_info, m_ctx));
48 size_t output_length()
const override {
return m_info.digestLength; }
50 size_t security_level()
const override {
51 if(m_info.name ==
"SHA-1") {
59 size_t hash_block_size()
const override {
return m_info.blockSize; }
61 CommonCrypto_HashFunction(
const digest_config_t& info) : m_info(info) { clear(); }
63 CommonCrypto_HashFunction(
const digest_config_t& info,
const CTX& ctx) : m_ctx(ctx), m_info(info) {}
66 void add_data(std::span<const uint8_t> input)
override {
67 BufferSlicer in(input);
71 CC_LONG update_len = (in.remaining() > 0xFFFFFFFFUL) ? 0xFFFFFFFFUL :
static_cast<CC_LONG
>(in.remaining());
72 const auto chunk = in.take(update_len);
73 m_info.update(&m_ctx, chunk.data(),
static_cast<CC_LONG
>(chunk.size()));
77 void final_result(std::span<uint8_t> output)
override {
78 if(m_info.final(output.data(), &m_ctx) != 1)
79 throw CommonCrypto_Error(
"CC_" + m_info.name +
"_Final");
84 digest_config_t m_info;
89#define MAKE_COMMONCRYPTO_HASH_3(name, hash, ctx) \
90 std::unique_ptr<HashFunction>(new CommonCrypto_HashFunction<CC_##ctx##_CTX>({std::string(name), \
91 CC_##hash##_DIGEST_LENGTH, \
92 CC_##hash##_BLOCK_BYTES, \
97#define MAKE_COMMONCRYPTO_HASH_2(name, id) MAKE_COMMONCRYPTO_HASH_3(name, id, id)
99#define MAKE_COMMONCRYPTO_HASH_1(id) MAKE_COMMONCRYPTO_HASH_2(#id, id)
101#if defined(BOTAN_HAS_SHA2_32)
102 if(name ==
"SHA-224")
104 if(name ==
"SHA-256")
107#if defined(BOTAN_HAS_SHA2_64)
108 if(name ==
"SHA-384")
110 if(name ==
"SHA-512")
114#if defined(BOTAN_HAS_SHA1)
virtual size_t security_level() const
#define MAKE_COMMONCRYPTO_HASH_2(name, id)
#define MAKE_COMMONCRYPTO_HASH_3(name, hash, ctx)
std::unique_ptr< HashFunction > make_commoncrypto_hash(std::string_view name)