/* */ #include "MessageDigestImpl.h" #include #include "Adler32MessageDigestImpl.h" namespace aria2 { #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100001L namespace { EVP_MD_CTX* EVP_MD_CTX_new() { return EVP_MD_CTX_create(); } } // namespace namespace { void EVP_MD_CTX_free(EVP_MD_CTX* ctx) { EVP_MD_CTX_destroy(ctx); } } // namespace namespace { int EVP_MD_CTX_reset(EVP_MD_CTX* ctx) { EVP_MD_CTX_init(ctx); return 1; } } // namespace #endif // defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < // 0x10100001L template class MessageDigestBase : public MessageDigestImpl { public: MessageDigestBase() : ctx_(EVP_MD_CTX_new()), md_(init_fn()), len_(EVP_MD_size(md_)) { EVP_MD_CTX_reset(ctx_); reset(); } virtual ~MessageDigestBase() { EVP_MD_CTX_free(ctx_); } static size_t length() { return EVP_MD_size(init_fn()); } virtual size_t getDigestLength() const CXX11_OVERRIDE { return len_; } virtual void reset() CXX11_OVERRIDE { EVP_DigestInit_ex(ctx_, md_, nullptr); } virtual void update(const void* data, size_t length) CXX11_OVERRIDE { auto bytes = reinterpret_cast(data); while (length) { size_t l = std::min(length, (size_t)std::numeric_limits::max()); EVP_DigestUpdate(ctx_, bytes, l); length -= l; bytes += l; } } virtual void digest(unsigned char* md) CXX11_OVERRIDE { unsigned int len; EVP_DigestFinal_ex(ctx_, md, &len); } private: EVP_MD_CTX* ctx_; const EVP_MD* md_; const size_t len_; }; typedef MessageDigestBase MessageDigestMD5; typedef MessageDigestBase MessageDigestSHA1; std::unique_ptr MessageDigestImpl::sha1() { return make_unique(); } MessageDigestImpl::hashes_t MessageDigestImpl::hashes = { {"sha-1", make_hi()}, #ifdef HAVE_EVP_SHA224 {"sha-224", make_hi>()}, #endif #ifdef HAVE_EVP_SHA224 {"sha-256", make_hi>()}, #endif #ifdef HAVE_EVP_SHA224 {"sha-384", make_hi>()}, #endif #ifdef HAVE_EVP_SHA224 {"sha-512", make_hi>()}, #endif {"md5", make_hi()}, ADLER32_MESSAGE_DIGEST}; } // namespace aria2