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 hash_block_size()
const override {
return m_info.blockSize; }
52 CommonCrypto_HashFunction(
const digest_config_t& info) : m_info(info) { clear(); }
54 CommonCrypto_HashFunction(
const digest_config_t& info,
const CTX& ctx) : m_ctx(ctx), m_info(info) {}
57 void add_data(std::span<const uint8_t> input)
override {
58 BufferSlicer in(input);
62 CC_LONG update_len = (in.remaining() > 0xFFFFFFFFUL) ? 0xFFFFFFFFUL :
static_cast<CC_LONG
>(in.remaining());
63 const auto chunk = in.take(update_len);
64 m_info.update(&m_ctx, chunk.data(),
static_cast<CC_LONG
>(chunk.size()));
68 void final_result(std::span<uint8_t> output)
override {
69 if(m_info.final(output.data(), &m_ctx) != 1)
70 throw CommonCrypto_Error(
"CC_" + m_info.name +
"_Final");
75 digest_config_t m_info;
80#define MAKE_COMMONCRYPTO_HASH_3(name, hash, ctx) \
81 std::unique_ptr<HashFunction>(new CommonCrypto_HashFunction<CC_##ctx##_CTX>({std::string(name), \
82 CC_##hash##_DIGEST_LENGTH, \
83 CC_##hash##_BLOCK_BYTES, \
88#define MAKE_COMMONCRYPTO_HASH_2(name, id) MAKE_COMMONCRYPTO_HASH_3(name, id, id)
90#define MAKE_COMMONCRYPTO_HASH_1(id) MAKE_COMMONCRYPTO_HASH_2(#id, id)
92#if defined(BOTAN_HAS_SHA2_32)
98#if defined(BOTAN_HAS_SHA2_64)
101 if(name ==
"SHA-512")
105#if defined(BOTAN_HAS_SHA1)
#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)