Reece Wilson
8a2947ffc5
[*] Refactor bcrypt api: HashPW[Ex] -> HashPassword[Ex] [+] ByteBuffer::GetOrAllocateLinearWriteable [+] ByteBuffer::Can[Read/Write](n) [+] ByteBuffer::GetLinear[Read/Writable]able(n) [*] Split RNG.cpp into two files [+] EHashType::eSHA2_48 (_32, _64 was already in place. missed 48/384 bit) [+] AuCrypto::HMAC and IHMACContext (AuHashing) [+] EHashType::eSHA3_28 [+] EHashType::eSHA3_32 [+] EHashType::eSHA3_48 [+] EHashType::eSHA3_64 (AuCrypto) [+] EHashType::eSHA2_48_384 [+] EHashType::eSHA2_64_512 [+] EHashType::eSHA3_28_224 [+] EHashType::eSHA3_32_256 [+] EHashType::eSHA3_48_384 [+] EHashType::eSHA3_64_512 [*] (IRandomDevice) class -> struct [*] Bugfix: cast in Promise<SuccessValue_t, ErrorValue_t>::WriteIntoError [+] Missing AuHashing namespace alias [*] Time util: pad ms when fraction of a second to 3 digits
104 lines
2.8 KiB
C++
104 lines
2.8 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: BCrypt.cpp
|
|
Date: 2022-9-15
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "BCrypt.hpp"
|
|
|
|
extern "C"
|
|
{
|
|
#include "crypt_blowfish.h"
|
|
}
|
|
|
|
namespace Aurora::Crypto::BCrypt
|
|
{
|
|
static const int kMinBCryptRounds = 10;
|
|
|
|
AUKN_SYM int GetForcedMinRounds()
|
|
{
|
|
return kMinBCryptRounds;
|
|
}
|
|
|
|
AUKN_SYM AuString GenSalt(int rounds)
|
|
{
|
|
char seed[16];
|
|
char saltBuffer[31];
|
|
|
|
AuRng::RngFillArray<false>(seed);
|
|
|
|
rounds = AuMin(rounds, 31);
|
|
rounds = AuMax(rounds, kMinBCryptRounds);
|
|
auto ptr = _crypt_gensalt_blowfish_rn("$2a$",
|
|
rounds,
|
|
seed,
|
|
16,
|
|
saltBuffer,
|
|
AuArraySize(saltBuffer));
|
|
SysAssert(ptr, "?");
|
|
return ptr;
|
|
}
|
|
|
|
AUKN_SYM AuString HashPassword(const AuString &password, const AuString &salt)
|
|
{
|
|
return HashPasswordEx({ password.c_str(), password.size() + 1 }, salt);
|
|
}
|
|
|
|
AUKN_SYM AuString HashPasswordEx(const Memory::MemoryViewRead &password, const AuString &salt)
|
|
{
|
|
if (password.length > 72)
|
|
{
|
|
SysPushErrorCrypt("BCrypt password cannot be greater than 72 characters");
|
|
return {};
|
|
}
|
|
|
|
char cryptBuffer[62] { 0 };
|
|
char *pRet;
|
|
if (!(pRet = crypt_rn(password.Begin<char>(),
|
|
password.length,
|
|
salt.c_str(),
|
|
cryptBuffer,
|
|
AuArraySize(cryptBuffer))))
|
|
{
|
|
SysPushErrorCrypto("bcrypt failed");
|
|
return {};
|
|
}
|
|
|
|
return pRet;
|
|
}
|
|
|
|
AUKN_SYM bool CheckPassword(const AuString &password, const AuString &hashedPassword)
|
|
{
|
|
return CheckPasswordEx({ password.c_str(), password.size() + 1 }, hashedPassword);
|
|
}
|
|
|
|
AUKN_SYM bool CheckPasswordEx(const Memory::MemoryViewRead &password, const AuString &hashedPassword)
|
|
{
|
|
if (password.length == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (hashedPassword.empty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
char cryptBuffer[62] { 0 };
|
|
char *pRet;
|
|
if (!(pRet = crypt_rn(password.Begin<char>(),
|
|
password.length,
|
|
hashedPassword.c_str(),
|
|
cryptBuffer,
|
|
AuArraySize(cryptBuffer))))
|
|
{
|
|
SysPushErrorCrypto("bcrypt failed");
|
|
return {};
|
|
}
|
|
|
|
// I don't care about safe eval...
|
|
return cryptBuffer == hashedPassword;
|
|
}
|
|
} |