Botan 2.19.5 Crypto and TLS for C&

commoncrypto_hash.cpp
Go to the documentation of this file.
1/*
2* CommonCrypto Hash Functions
3* (C) 2018 Jose Pereira
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/commoncrypto.h>
9#include <botan/hash.h>
10#include <unordered_map>
11
12#include <CommonCrypto/CommonCrypto.h>
13
14 namespace Botan {
15
16 namespace {
17
18 template <class CTX>
19 class CommonCrypto_HashFunction final : public HashFunction
20 {
21 public:
22
23 struct digest_config_t {
24 std::string name;
25 size_t digestLength;
26 size_t blockSize;
27 int (*init)(CTX *);
28 int (*update)(CTX *, const void *, CC_LONG len);
29 int (*final)(unsigned char *, CTX*);
30 };
31
32 void clear() override
33 {
34 if(m_info.init(&m_ctx) != 1)
35 throw CommonCrypto_Error("CC_" + m_info.name + "_Init");
36 }
37
38 std::string provider() const override { return "commoncrypto"; }
39 std::string name() const override { return m_info.name; }
40
41 HashFunction* clone() const override
42 {
43 return new CommonCrypto_HashFunction(m_info);
44 }
45
46 std::unique_ptr<HashFunction> copy_state() const override
47 {
48 return std::unique_ptr<CommonCrypto_HashFunction>(
49 new CommonCrypto_HashFunction(m_info, m_ctx));
50 }
51
52 size_t output_length() const override
53 {
54 return m_info.digestLength;
55 }
56
57 size_t hash_block_size() const override
58 {
59 return m_info.blockSize;
60 }
61
62 CommonCrypto_HashFunction(const digest_config_t& info) :
63 m_info(info)
64 {
65 clear();
66 }
67
68 CommonCrypto_HashFunction(const digest_config_t& info, const CTX &ctx) :
69 m_ctx(ctx), m_info(info) {}
70
71 private:
72 void add_data(const uint8_t input[], size_t length) override
73 {
74 /* update len parameter is 32 bit unsigned integer, feed input in parts */
75 while (length > 0)
76 {
77 CC_LONG update_len = (length > 0xFFFFFFFFUL) ? 0xFFFFFFFFUL : static_cast<CC_LONG>(length);
78 m_info.update(&m_ctx, input, update_len);
79 input += update_len;
80 length -= update_len;
81 }
82 }
83
84 void final_result(uint8_t output[]) override
85 {
86 if(m_info.final(output, &m_ctx) != 1)
87 throw CommonCrypto_Error("CC_" + m_info.name + "_Final");
88 clear();
89 }
90
91 CTX m_ctx;
92 digest_config_t m_info;
93 };
94}
95
96std::unique_ptr<HashFunction>
97 make_commoncrypto_hash(const std::string& name)
98 {
99#define MAKE_COMMONCRYPTO_HASH_3(name, hash, ctx) \
100 std::unique_ptr<HashFunction>( \
101 new CommonCrypto_HashFunction<CC_ ## ctx ## _CTX >({ \
102 name, \
103 CC_ ## hash ## _DIGEST_LENGTH, \
104 CC_ ## hash ## _BLOCK_BYTES, \
105 CC_ ## hash ## _Init, \
106 CC_ ## hash ## _Update, \
107 CC_ ## hash ## _Final \
108 }));
109
110#define MAKE_COMMONCRYPTO_HASH_2(name, id) \
111 MAKE_COMMONCRYPTO_HASH_3(name, id, id)
112
113#define MAKE_COMMONCRYPTO_HASH_1(id) \
114 MAKE_COMMONCRYPTO_HASH_2(#id, id)
115
116#if defined(BOTAN_HAS_SHA2_32)
117 if(name == "SHA-224")
118 return MAKE_COMMONCRYPTO_HASH_3(name, SHA224, SHA256);
119 if(name == "SHA-256")
120 return MAKE_COMMONCRYPTO_HASH_2(name, SHA256);
121#endif
122#if defined(BOTAN_HAS_SHA2_64)
123 if(name == "SHA-384")
124 return MAKE_COMMONCRYPTO_HASH_3(name, SHA384, SHA512);
125 if(name == "SHA-512")
126 return MAKE_COMMONCRYPTO_HASH_2(name, SHA512);
127#endif
128
129#if defined(BOTAN_HAS_SHA1)
130 if(name == "SHA-160" || name == "SHA-1" || name == "SHA1")
131 return MAKE_COMMONCRYPTO_HASH_2(name, SHA1);
132#endif
133
134#if defined(BOTAN_HAS_MD5)
135 if(name == "MD5")
136 return MAKE_COMMONCRYPTO_HASH_1(MD5);
137#endif
138
139#if defined(BOTAN_HAS_MD4)
140 if(name == "MD4")
141 return MAKE_COMMONCRYPTO_HASH_1(MD4);
142#endif
143 return nullptr;
144 }
145
146}
Botan::MD4
Definition: md4.h:21
Botan::MD5
Definition: md5.h:21
MAKE_COMMONCRYPTO_HASH_1
#define MAKE_COMMONCRYPTO_HASH_1(id)
MAKE_COMMONCRYPTO_HASH_2
#define MAKE_COMMONCRYPTO_HASH_2(name, id)
digestLength
size_t digestLength
Definition: commoncrypto_hash.cpp:25
init
int(* init)(CTX *)
Definition: commoncrypto_hash.cpp:27
name
std::string name
Definition: commoncrypto_hash.cpp:24
blockSize
size_t blockSize
Definition: commoncrypto_hash.cpp:26
update
int(* update)(CTX *, const void *, CC_LONG len)
Definition: commoncrypto_hash.cpp:28
MAKE_COMMONCRYPTO_HASH_3
#define MAKE_COMMONCRYPTO_HASH_3(name, hash, ctx)
final
int(* final)(unsigned char *, CTX *)
Definition: commoncrypto_hash.cpp:29
Botan
Definition: alg_id.cpp:13
Botan::make_commoncrypto_hash
std::unique_ptr< HashFunction > make_commoncrypto_hash(const std::string &name)
Definition: commoncrypto_hash.cpp:97