Hash API polish

[+] Added IHashStream::Export
[+] Added IHashStream::Import
[+] Added IHashStream::Finalize (versus "deprecated" older api)
[+] Added EHashType eMD4, eRMD128, eRMD160, eRMD256, eRMD320
This commit is contained in:
Reece Wilson 2022-05-14 21:00:36 +01:00
parent f182ecd986
commit d0c4d8cb33
6 changed files with 342 additions and 50 deletions

View File

@ -9,9 +9,23 @@
namespace Aurora::Hashing namespace Aurora::Hashing
{ {
AUKN_SYM void MD5(const Memory::MemoryViewRead &span, AuArray<AuUInt8, 16> &md5); AUKN_SYM void MD4(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 16> &md4);
AUKN_SYM void SHA1(const Memory::MemoryViewRead &span, AuArray<AuUInt8, 20> &sha1);
AUKN_SYM void Tiger(const Memory::MemoryViewRead &span, AuArray<AuUInt8, 24> &tiger); AUKN_SYM void MD5(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 16> &md5);
AUKN_SYM void SHA2(const Memory::MemoryViewRead &span, AuArray<AuUInt8, 32> &sha2);
AUKN_SYM void SHA2_64(const Memory::MemoryViewRead &span, AuArray<AuUInt8, 64> &sha2); AUKN_SYM void SHA1(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 20> &sha1);
AUKN_SYM void Tiger(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 24> &tiger);
AUKN_SYM void SHA2(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 32> &sha2);
AUKN_SYM void SHA2_64(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 64> &sha2);
AUKN_SYM void RMD128(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 16> &rmd128);
AUKN_SYM void RMD160(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 20> &rmd160);
AUKN_SYM void RMD256(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 32> &rmd256);
AUKN_SYM void RMD320(const Memory::MemoryViewRead &read, AuArray<AuUInt8, 40> &rmd320);
} }

View File

@ -11,10 +11,15 @@ namespace Aurora::Hashing
{ {
AUE_DEFINE(EHashType, AUE_DEFINE(EHashType,
( (
eMD4,
eMD5, eMD5,
eSHA1, eSHA1,
eSHA2_32, eSHA2_32,
eSHA2_64, eSHA2_64,
eTiger eTiger,
eRMD128,
eRMD160,
eRMD256,
eRMD320
)); ));
} }

View File

@ -9,18 +9,44 @@
namespace Aurora::Hashing namespace Aurora::Hashing
{ {
class IHashStream struct IHashStream
{ {
public:
/** /**
* Digest length of pBuf bytes * @brief Processes an arbitrary amount of bytes
* @param input
*/ */
virtual void Ingest(const Memory::MemoryViewRead &input) = 0; virtual void Ingest(const Memory::MemoryViewRead &input) = 0;
/** /**
* Locks and returns the internal buffer * @brief Legacy pointer variant of the ::Finalize API. Wont deprecate.
* @param length
* @return
*/ */
virtual AuUInt8 const* GetBytes(AuUInt32 &length) = 0; virtual AuUInt8 const* GetBytes(AuUInt32 &length) = 0;
/**
* @brief Finalizes the stream - locks and returns the internal buffer
* @return
*/
virtual Memory::MemoryViewRead Finalize() = 0;
/**
* @brief Exports the state of an aligned stream
* @return
*/
virtual AuResult<Memory::MemoryViewRead> Export() = 0;
/**
* @brief Starts off from where ::Export left off
* @param view
* @return
*/
virtual bool Import(const Memory::MemoryViewRead &view) = 0;
/**
* @brief Reuse the IHashStream of the EHashType variant by resetting the stream state to its' default configuration
*/
virtual void Reset() = 0;
}; };
AUKN_SHARED_API(HashStream, IHashStream, EHashType type); AUKN_SHARED_API(HashStream, IHashStream, EHashType type);

View File

@ -11,43 +11,83 @@
namespace Aurora::Hashing namespace Aurora::Hashing
{ {
AUKN_SYM void MD4(const AuMemoryViewRead &read, AuArray<AuUInt8, 16> &md4)
{
hash_state md;
md4_init(&md);
md4_process(&md, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
md4_done(&md, md4.data());
}
AUKN_SYM void MD5(const AuMemoryViewRead &read, AuArray<AuUInt8, 16> &md5) AUKN_SYM void MD5(const AuMemoryViewRead &read, AuArray<AuUInt8, 16> &md5)
{ {
hash_state md; hash_state md;
md5_init(&md); md5_init(&md);
md5_process(&md, reinterpret_cast<const unsigned char*>(read.ptr), read.length); md5_process(&md, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
md5_done(&md, md5.data()); md5_done(&md, md5.data());
} }
AUKN_SYM void SHA1(const AuMemoryViewRead &read, AuArray<AuUInt8, 20> &sha1) AUKN_SYM void SHA1(const AuMemoryViewRead &read, AuArray<AuUInt8, 20> &sha1)
{ {
hash_state md; hash_state hs;
sha1_init(&md); sha1_init(&hs);
sha1_process(&md, reinterpret_cast<const unsigned char*>(read.ptr), read.length); sha1_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
sha1_done(&md, sha1.data()); sha1_done(&hs, sha1.data());
} }
AUKN_SYM void Tiger(const AuMemoryViewRead &read, AuArray<AuUInt8, 24> &tiger) AUKN_SYM void Tiger(const AuMemoryViewRead &read, AuArray<AuUInt8, 24> &tiger)
{ {
hash_state md; hash_state hs;
tiger_init(&md); tiger_init(&hs);
tiger_process(&md, reinterpret_cast<const unsigned char*>(read.ptr), read.length); tiger_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
tiger_done(&md, tiger.data()); tiger_done(&hs, tiger.data());
} }
AUKN_SYM void SHA2(const AuMemoryViewRead &read, AuArray<AuUInt8, 32> &sha2) AUKN_SYM void SHA2(const AuMemoryViewRead &read, AuArray<AuUInt8, 32> &sha2)
{ {
hash_state md; hash_state hs;
sha256_init(&md); sha256_init(&hs);
sha256_process(&md, reinterpret_cast<const unsigned char*>(read.ptr), read.length); sha256_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
sha256_done(&md, sha2.data()); sha256_done(&hs, sha2.data());
} }
AUKN_SYM void SHA2_64(const AuMemoryViewRead &read, AuArray<AuUInt8, 64> &sha2) AUKN_SYM void SHA2_64(const AuMemoryViewRead &read, AuArray<AuUInt8, 64> &sha2)
{ {
hash_state md; hash_state hs;
sha512_init(&md); sha512_init(&hs);
sha512_process(&md, reinterpret_cast<const unsigned char*>(read.ptr), read.length); sha512_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
sha512_done(&md, sha2.data()); sha512_done(&hs, sha2.data());
}
AUKN_SYM void RMD128(const AuMemoryViewRead &read, AuArray<AuUInt8, 16> &rmd128)
{
hash_state hs;
rmd128_init(&hs);
rmd128_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
rmd128_done(&hs, rmd128.data());
}
AUKN_SYM void RMD160(const AuMemoryViewRead &read, AuArray<AuUInt8, 20> &rmd160)
{
hash_state hs;
rmd160_init(&hs);
rmd160_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
rmd160_done(&hs, rmd160.data());
}
AUKN_SYM void RMD256(const AuMemoryViewRead &read, AuArray<AuUInt8, 32> &rmd256)
{
hash_state hs;
rmd256_init(&hs);
rmd256_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
rmd256_done(&hs, rmd256.data());
}
AUKN_SYM void RMD320(const AuMemoryViewRead &read, AuArray<AuUInt8, 40> &rmd320)
{
hash_state hs;
rmd320_init(&hs);
rmd320_process(&hs, reinterpret_cast<const unsigned char *>(read.ptr), read.length);
rmd320_done(&hs, rmd320.data());
} }
} }

View File

@ -13,24 +13,7 @@ namespace Aurora::Hashing
{ {
HashStream::HashStream(EHashType type) : type_(type) HashStream::HashStream(EHashType type) : type_(type)
{ {
switch (type) Init();
{
case EHashType::eMD5:
md5_init(&this->state_);
break;
case EHashType::eSHA1:
sha1_init(&this->state_);
break;
case EHashType::eSHA2_32:
sha256_init(&this->state_);
break;
case EHashType::eSHA2_64:
sha512_init(&this->state_);
break;
case EHashType::eTiger:
tiger_init(&this->state_);
break;
}
} }
void HashStream::Ingest(const Memory::MemoryViewRead &input) void HashStream::Ingest(const Memory::MemoryViewRead &input)
@ -45,6 +28,9 @@ namespace Aurora::Hashing
switch (this->type_) switch (this->type_)
{ {
case EHashType::eMD4:
md4_process(&this->state_, buffer, len);
break;
case EHashType::eMD5: case EHashType::eMD5:
md5_process(&this->state_, buffer, len); md5_process(&this->state_, buffer, len);
break; break;
@ -60,6 +46,18 @@ namespace Aurora::Hashing
case EHashType::eTiger: case EHashType::eTiger:
tiger_process(&this->state_, buffer, len); tiger_process(&this->state_, buffer, len);
break; break;
case EHashType::eRMD128:
rmd128_process(&this->state_, buffer, len);
break;
case EHashType::eRMD160:
rmd160_process(&this->state_, buffer, len);
break;
case EHashType::eRMD256:
rmd256_process(&this->state_, buffer, len);
break;
case EHashType::eRMD320:
rmd320_process(&this->state_, buffer, len);
break;
} }
} }
@ -67,6 +65,14 @@ namespace Aurora::Hashing
{ {
switch (this->type_) switch (this->type_)
{ {
case EHashType::eMD4:
length = 16;
if (!AuExchange(this->finished_, true))
{
md4_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
}
return this->buffer_;
case EHashType::eMD5: case EHashType::eMD5:
length = 16; length = 16;
if (!AuExchange(this->finished_, true)) if (!AuExchange(this->finished_, true))
@ -74,6 +80,7 @@ namespace Aurora::Hashing
md5_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_)); md5_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
} }
return this->buffer_; return this->buffer_;
case EHashType::eSHA1: case EHashType::eSHA1:
length = 20; length = 20;
if (!AuExchange(this->finished_, true)) if (!AuExchange(this->finished_, true))
@ -81,6 +88,7 @@ namespace Aurora::Hashing
sha1_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_)); sha1_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
} }
return this->buffer_; return this->buffer_;
case EHashType::eSHA2_32: case EHashType::eSHA2_32:
length = 32; length = 32;
if (!AuExchange(this->finished_, true)) if (!AuExchange(this->finished_, true))
@ -88,6 +96,7 @@ namespace Aurora::Hashing
sha256_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_)); sha256_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
} }
return this->buffer_; return this->buffer_;
case EHashType::eSHA2_64: case EHashType::eSHA2_64:
length = 64; length = 64;
if (!AuExchange(this->finished_, true)) if (!AuExchange(this->finished_, true))
@ -95,6 +104,7 @@ namespace Aurora::Hashing
sha512_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_)); sha512_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
} }
return this->buffer_; return this->buffer_;
case EHashType::eTiger: case EHashType::eTiger:
length = 24; length = 24;
if (!AuExchange(this->finished_, true)) if (!AuExchange(this->finished_, true))
@ -102,10 +112,198 @@ namespace Aurora::Hashing
tiger_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_)); tiger_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
} }
return this->buffer_; return this->buffer_;
case EHashType::eRMD128:
length = 16;
if (!AuExchange(this->finished_, true))
{
rmd128_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
}
return this->buffer_;
case EHashType::eRMD160:
length = 20;
if (!AuExchange(this->finished_, true))
{
rmd160_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
}
return this->buffer_;
case EHashType::eRMD256:
length = 32;
if (!AuExchange(this->finished_, true))
{
rmd256_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
}
return this->buffer_;
case EHashType::eRMD320:
length = 40;
if (!AuExchange(this->finished_, true))
{
rmd256_done(&this->state_, reinterpret_cast<unsigned char *>(this->buffer_));
}
return this->buffer_;
} }
return nullptr; return nullptr;
} }
AuMemoryViewRead HashStream::Finalize()
{
AuUInt32 length;
auto begin = GetBytes(length);
return AuMemoryViewRead(begin, length);
}
AuResult<AuMemoryViewRead> HashStream::Export()
{
// Defer to HASH_PROCESS defined in the private libtomcrypt header
//this->state_.name.length | bits processed
#define ADD_EXPORT(name) \
if (this->state_.name.curlen) \
{ \
return {}; \
} \
return AuMemoryViewRead {this->state_.name.state, sizeof(this->state_.name.state)};
switch (this->type_)
{
case EHashType::eMD4:
ADD_EXPORT(md4);
case EHashType::eMD5:
ADD_EXPORT(md5);
case EHashType::eSHA1:
ADD_EXPORT(sha1);
case EHashType::eSHA2_32:
ADD_EXPORT(sha256);
case EHashType::eSHA2_64:
ADD_EXPORT(sha512);
case EHashType::eTiger:
ADD_EXPORT(tiger);
case EHashType::eRMD128:
ADD_EXPORT(rmd128);
case EHashType::eRMD160:
ADD_EXPORT(rmd160);
case EHashType::eRMD256:
ADD_EXPORT(rmd256);
case EHashType::eRMD320:
ADD_EXPORT(rmd320);
default:
return {};
}
#undef ADD_EXPORT
}
bool HashStream::Import(const Memory::MemoryViewRead &view)
{
#define ADD_IMPORT(name) \
if (sizeof(this->state_.name.state) != view.length) \
{ \
SysPushErrorCrypt("Invalid hash state length -> mixed ciphers?"); \
return false; \
} \
AuMemset(&this->state_, 0, sizeof(this->state_)); \
AuMemcpy(this->state_.name.state, view.ptr, sizeof(this->state_.name.state)); \
return true;
switch (this->type_)
{
case EHashType::eMD4:
ADD_IMPORT(md4);
case EHashType::eMD5:
ADD_IMPORT(md5);
case EHashType::eSHA1:
ADD_IMPORT(sha1);
case EHashType::eSHA2_32:
ADD_IMPORT(sha256);
case EHashType::eSHA2_64:
ADD_IMPORT(sha512);
case EHashType::eTiger:
ADD_IMPORT(tiger);
case EHashType::eRMD128:
ADD_IMPORT(rmd128);
case EHashType::eRMD160:
ADD_IMPORT(rmd160);
case EHashType::eRMD256:
ADD_IMPORT(rmd256);
case EHashType::eRMD320:
ADD_IMPORT(rmd320);
default:
return false;
}
#undef ADD_IMPORT
}
void HashStream::Reset()
{
Init();
}
void HashStream::Init()
{
AuMemset(&this->state_, 0, sizeof(this->state_));
switch (this->type_)
{
case EHashType::eMD4:
md4_init(&this->state_);
break;
case EHashType::eMD5:
md5_init(&this->state_);
break;
case EHashType::eSHA1:
sha1_init(&this->state_);
break;
case EHashType::eSHA2_32:
sha256_init(&this->state_);
break;
case EHashType::eSHA2_64:
sha512_init(&this->state_);
break;
case EHashType::eTiger:
tiger_init(&this->state_);
break;
case EHashType::eRMD128:
rmd128_init(&this->state_);
break;
case EHashType::eRMD160:
rmd160_init(&this->state_);
break;
case EHashType::eRMD256:
rmd256_init(&this->state_);
break;
case EHashType::eRMD320:
rmd320_init(&this->state_);
break;
}
}
AUKN_SYM IHashStream *HashStreamNew(EHashType type) AUKN_SYM IHashStream *HashStreamNew(EHashType type)
{ {
return _new HashStream(type); return _new HashStream(type);

View File

@ -9,14 +9,23 @@
namespace Aurora::Hashing namespace Aurora::Hashing
{ {
class HashStream : public IHashStream struct HashStream : IHashStream
{ {
public:
HashStream(EHashType type); HashStream(EHashType type);
void Ingest(const Memory::MemoryViewRead &input) override; void Ingest(const Memory::MemoryViewRead &input) override;
AuUInt8 const *GetBytes(AuUInt32 &length) override; AuUInt8 const *GetBytes(AuUInt32 &length) override;
Memory::MemoryViewRead Finalize() override;
AuResult<Memory::MemoryViewRead> Export() override;
bool Import(const Memory::MemoryViewRead &view) override;
void Reset() override;
void Init();
private: private:
AuUInt8 buffer_[64] {}; AuUInt8 buffer_[64] {};
hash_state state_ {}; hash_state state_ {};