AuroraRuntime/Source/Hashing/HashStream.cpp

130 lines
3.5 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: HashStream.cpp
Date: 2021-6-12
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "HashStream.hpp"
#include <tomcrypt.h>
namespace Aurora::Hashing
{
class HashStream : public IHashStream
{
public:
HashStream(EHashType type);
void Ingest(const void *buffer, AuUInt32 len) override;
AuUInt8 const * GetBytes(AuUInt32 &length) override;
private:
AuUInt8 buffer_[64] {};
hash_state state_ {};
EHashType type_ {};
bool finished_ {};
};
HashStream::HashStream(EHashType type) : type_(type)
{
switch (type)
{
case EHashType::eMD5:
md5_init(&state_);
break;
case EHashType::eSHA1:
sha1_init(&state_);
break;
case EHashType::eSHA2_32:
sha256_init(&state_);
break;
case EHashType::eSHA2_64:
sha512_init(&state_);
break;
case EHashType::eTiger:
tiger_init(&state_);
break;
}
}
void HashStream::Ingest(const void *buffer, AuUInt32 len)
{
if (finished_)
{
return;
}
switch (type_)
{
case EHashType::eMD5:
md5_process(&state_, reinterpret_cast<const unsigned char *>(buffer), len);
break;
case EHashType::eSHA1:
sha1_process(&state_, reinterpret_cast<const unsigned char *>(buffer), len);
break;
case EHashType::eSHA2_32:
sha256_process(&state_, reinterpret_cast<const unsigned char *>(buffer), len);
break;
case EHashType::eSHA2_64:
sha512_process(&state_, reinterpret_cast<const unsigned char *>(buffer), len);
break;
case EHashType::eTiger:
tiger_process(&state_, reinterpret_cast<const unsigned char *>(buffer), len);
break;
}
}
AuUInt8 const* HashStream::GetBytes(AuUInt32 &length)
{
switch (type_)
{
case EHashType::eMD5:
length = 16;
if (!std::exchange(finished_, true))
{
md5_done(&state_, reinterpret_cast<unsigned char *>(buffer_));
}
return buffer_;
case EHashType::eSHA1:
length = 20;
if (!std::exchange(finished_, true))
{
sha1_done(&state_, reinterpret_cast<unsigned char *>(buffer_));
}
return buffer_;
case EHashType::eSHA2_32:
length = 32;
if (!std::exchange(finished_, true))
{
sha256_done(&state_, reinterpret_cast<unsigned char *>(buffer_));
}
return buffer_;
case EHashType::eSHA2_64:
length = 64;
if (!std::exchange(finished_, true))
{
sha512_done(&state_, reinterpret_cast<unsigned char *>(buffer_));
}
return buffer_;
case EHashType::eTiger:
length = 24;
if (!std::exchange(finished_, true))
{
tiger_done(&state_, reinterpret_cast<unsigned char *>(buffer_));
}
return buffer_;
}
return nullptr;
}
AUKN_SYM IHashStream *HashStreamNew(EHashType type)
{
return _new HashStream(type);
}
AUKN_SYM void HashStreamRelease(IHashStream *stream)
{
SafeDelete<HashStream*>(stream);
}
}