15#ifndef OPENVPN_APPLECRYPTO_CRYPTO_DIGEST_H
16#define OPENVPN_APPLECRYPTO_CRYPTO_DIGEST_H
20#include <CommonCrypto/CommonDigest.h>
21#include <CommonCrypto/CommonHMAC.h>
31#define OPENVPN_DIGEST_CONTEXT(TYPE) CC_##TYPE##_CTX TYPE##_ctx
33#define OPENVPN_DIGEST_ALG_CLASS(TYPE) \
34 class DigestAlgorithm##TYPE : public DigestAlgorithm \
37 DigestAlgorithm##TYPE() \
40 int init(DigestCTX &ctx) const override \
42 return CC_##TYPE##_Init(&ctx.u.TYPE##_ctx); \
44 int update(DigestCTX &ctx, const unsigned char *data, size_t size) const override \
46 return CC_##TYPE##_Update(&ctx.u.TYPE##_ctx, data, size); \
48 int final(DigestCTX &ctx, unsigned char *md) const override \
50 return CC_##TYPE##_Final(md, &ctx.u.TYPE##_ctx); \
54#define OPENVPN_DIGEST_ALG_DECLARE(TYPE) const DigestAlgorithm##TYPE alg_##TYPE;
56#define OPENVPN_DIGEST_INFO_DECLARE(TYPE) const DigestInfo info_##TYPE(CryptoAlgs::TYPE, &alg_##TYPE, kCCHmacAlg##TYPE)
58#define OPENVPN_DIGEST_INFO_DECLARE_NO_HMAC(TYPE) const DigestInfo info_##TYPE(CryptoAlgs::TYPE, &alg_##TYPE, DigestInfo::NO_HMAC_ALG)
61typedef CC_SHA256_CTX CC_SHA224_CTX;
62typedef CC_SHA512_CTX CC_SHA384_CTX;
67 OPENVPN_DIGEST_CONTEXT(MD4);
68 OPENVPN_DIGEST_CONTEXT(MD5);
69 OPENVPN_DIGEST_CONTEXT(SHA1);
70 OPENVPN_DIGEST_CONTEXT(SHA224);
71 OPENVPN_DIGEST_CONTEXT(SHA256);
72 OPENVPN_DIGEST_CONTEXT(SHA384);
73 OPENVPN_DIGEST_CONTEXT(SHA512);
79 virtual int init(DigestCTX &ctx)
const = 0;
80 virtual int update(DigestCTX &ctx,
const unsigned char *data,
size_t size)
const = 0;
81 virtual int final(DigestCTX &ctx,
unsigned char *md)
const = 0;
85OPENVPN_DIGEST_ALG_CLASS(MD4);
86OPENVPN_DIGEST_ALG_CLASS(MD5);
87OPENVPN_DIGEST_ALG_CLASS(SHA1);
88OPENVPN_DIGEST_ALG_CLASS(SHA224);
89OPENVPN_DIGEST_ALG_CLASS(SHA256);
90OPENVPN_DIGEST_ALG_CLASS(SHA384);
91OPENVPN_DIGEST_ALG_CLASS(SHA512);
104 const DigestAlgorithm *digest_alg,
105 const CCHmacAlgorithm hmac_alg)
107 digest_alg_(digest_alg),
118 return CryptoAlgs::name(type_);
122 return CryptoAlgs::size(type_);
167 friend class HMACContext;
175 MAX_DIGEST_SIZE = CC_SHA512_DIGEST_LENGTH
188 void init(
const CryptoAlgs::Type alg)
191 info = digest_type(alg);
192 meth = info->digest_alg();
193 if (meth->init(ctx) != 1)
194 throw apple_digest_error(
"init");
198 void update(
const unsigned char *in,
const size_t size)
201 if (meth->update(ctx, in, size) != 1)
202 throw apple_digest_error(
"update");
205 size_t final(
unsigned char *
out)
208 if (meth->final(ctx,
out) != 1)
209 throw apple_digest_error(
"final");
229 case CryptoAlgs::MD4:
231 case CryptoAlgs::MD5:
233 case CryptoAlgs::SHA1:
235 case CryptoAlgs::SHA224:
237 case CryptoAlgs::SHA256:
239 case CryptoAlgs::SHA384:
241 case CryptoAlgs::SHA512:
244 OPENVPN_THROW(apple_digest_error, CryptoAlgs::name(alg) <<
": not usable");
255#ifdef OPENVPN_ENABLE_ASSERT
257 throw apple_digest_uninitialized();
268#undef OPENVPN_DIGEST_CONTEXT
269#undef OPENVPN_DIGEST_ALG_CLASS
270#undef OPENVPN_DIGEST_ALG_DECLARE
271#undef OPENVPN_DIGEST_INFO_DECLARE
OPENVPN_DIGEST_ALG_DECLARE(MD4)
OPENVPN_DIGEST_INFO_DECLARE(MD5)
OPENVPN_DIGEST_INFO_DECLARE_NO_HMAC(MD4)
void check_initialized() const
void init(const CryptoAlgs::Type alg)
OPENVPN_SIMPLE_EXCEPTION(apple_digest_final_overflow)
OPENVPN_SIMPLE_EXCEPTION(apple_digest_uninitialized)
const DigestAlgorithm * meth
OPENVPN_EXCEPTION(apple_digest_error)
DigestContext & operator=(const DigestContext &)=delete
void update(const unsigned char *in, const size_t size)
static const DigestInfo * digest_type(const CryptoAlgs::Type alg)
bool is_initialized() const
DigestContext(const CryptoAlgs::Type alg)
DigestContext(const DigestContext &)=delete
const DigestAlgorithm * digest_alg() const
CCHmacAlgorithm hmac_alg_
const char * name() const
CryptoAlgs::Type type() const
DigestInfo(CryptoAlgs::Type type, const DigestAlgorithm *digest_alg, const CCHmacAlgorithm hmac_alg)
CCHmacAlgorithm hmac_alg() const
const DigestAlgorithm * digest_alg_
#define OPENVPN_THROW(exc, stuff)
static std::stringstream out