123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #pragma once
- #ifndef _WIN32
- #include <string.h>
- #include <openssl/crypto.h>
- #include <openssl/sha.h>
- //ndef _WIN32
- struct HasherSha1Traits {
- public:
- static constexpr size_t BlockSize = 512 / 8;
- static constexpr size_t DigestSize = 160 / 8;
- struct DigestType {
- unsigned char Bytes[DigestSize];
- };
- using ContextType = SHA_CTX;
- public:
- static inline ContextType ContextCreate() {
- ContextType Ctx;
- SHA1_Init(&Ctx);
- return Ctx;
- }
- static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) {
- ContextType Ctx = ContextCreate();
- ContextUpdate(Ctx, lpBuffer, cbBuffer);
- return Ctx;
- }
- static inline ContextType ContextCopy(const ContextType& Ctx) {
- return Ctx;
- }
- static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) {
- SHA1_Update(&Ctx, lpBuffer, cbBuffer);
- }
- static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) {
- auto ForkedCtx = ContextCopy(Ctx);
- SHA1_Final(Digest.Bytes, &ForkedCtx);
- }
- static inline void ContextDestroy(ContextType& Ctx) noexcept {
- OPENSSL_cleanse(&Ctx, sizeof(Ctx));
- }
- };
- #else
- #include <windows.h>
- #include <wincrypt.h>
- #include <system_error>
- struct HasherSha1Traits {
- public:
- static constexpr size_t BlockSize = 512 / 8;
- static constexpr size_t DigestSize = 160 / 8;
- struct DigestType {
- BYTE Bytes[DigestSize];
- };
- struct ContextType {
- HCRYPTHASH hHash;
- ContextType() noexcept :
- hHash(NULL) {}
- ContextType(const ContextType& Other) noexcept = default;
- ContextType(ContextType&& Other) noexcept : hHash(Other.hHash) {
- Other.hHash = NULL;
- }
- ContextType& operator=(const ContextType& Other) noexcept = default;
- ContextType& operator=(ContextType&& Other) noexcept {
- hHash = Other.hHash;
- Other.hHash = NULL;
- return *this;
- }
- };
- private:
- static inline struct ContextProvider {
- HCRYPTPROV Handle;
- ~ContextProvider() {
- if (Handle) {
- CryptReleaseContext(Handle, 0);
- Handle = NULL;
- }
- }
- } CryptProvider;
- public:
- static inline ContextType ContextCreate() {
- ContextType Ctx;
- if (CryptProvider.Handle == NULL) {
- if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) {
- auto err = GetLastError();
- if (err == NTE_BAD_KEYSET) {
- if (!CryptAcquireContext(&CryptProvider.Handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) {
- err = GetLastError();
- throw std::system_error(err, std::system_category());
- }
- } else {
- throw std::system_error(err, std::system_category());
- }
- }
- }
- if (!CryptCreateHash(CryptProvider.Handle, CALG_SHA1, NULL, 0, &Ctx.hHash)) {
- auto err = GetLastError();
- throw std::system_error(err, std::system_category());
- }
- return Ctx;
- }
- static inline ContextType ContextCreate(const void* lpBuffer, size_t cbBuffer) {
- ContextType Ctx = ContextCreate();
- ContextUpdate(Ctx, lpBuffer, cbBuffer);
- return Ctx;
- }
- static inline ContextType ContextCopy(const ContextType& Ctx) {
- ContextType NewCtx;
- if (!CryptDuplicateHash(Ctx.hHash, NULL, 0, &NewCtx.hHash)) {
- auto err = GetLastError();
- throw std::system_error(err, std::system_category());
- }
- return NewCtx;
- }
- static inline void ContextUpdate(ContextType& Ctx, const void* lpBuffer, size_t cbBuffer) {
- if constexpr (sizeof(size_t) <= sizeof(DWORD)) {
- if (!CryptHashData(Ctx.hHash, reinterpret_cast<const BYTE*>(lpBuffer), static_cast<DWORD>(cbBuffer), 0)) {
- auto err = GetLastError();
- throw std::system_error(err, std::system_category());
- }
- } else {
- size_t BytesRead = 0;
- DWORD BytesToRead = cbBuffer - BytesRead > MAXDWORD ? MAXDWORD : static_cast<DWORD>(cbBuffer - BytesRead);
-
- do {
- if (!CryptHashData(Ctx.hHash, reinterpret_cast<const BYTE*>(lpBuffer) + BytesRead, BytesToRead, 0)) {
- auto err = GetLastError();
- throw std::system_error(err, std::system_category());
- }
- BytesRead += BytesToRead;
- BytesToRead = cbBuffer - BytesRead > MAXDWORD ? MAXDWORD : static_cast<DWORD>(cbBuffer - BytesRead);
- } while (BytesToRead);
- }
- }
- static inline void ContextEvaluate(const ContextType& Ctx, DigestType& Digest) {
- DWORD SizeOfDigest = sizeof(Digest.Bytes);
- if (!CryptGetHashParam(Ctx.hHash, HP_HASHVAL, Digest.Bytes, &SizeOfDigest, 0)) {
- auto err = GetLastError();
- throw std::system_error(err, std::system_category());
- }
- }
- static inline void ContextDestroy(ContextType& Ctx) noexcept {
- if (Ctx.hHash) {
- CryptDestroyHash(Ctx.hHash);
- Ctx.hHash = NULL;
- }
- }
- };
- #endif
|