[+] Added "Safer" variants to bcrypt when using string containers

This commit is contained in:
Reece Wilson 2024-02-19 19:08:20 +00:00
parent 0461b54045
commit 2da8332c0f
2 changed files with 28 additions and 0 deletions

View File

@ -7,6 +7,14 @@
Note: MD5 ($1$), the other numberic methods, and non-standard unix fuckery (ie: $sha1$) isn't implemented. Note: MD5 ($1$), the other numberic methods, and non-standard unix fuckery (ie: $sha1$) isn't implemented.
This API implements $2x$-class password hashing and verification This API implements $2x$-class password hashing and verification
Note 2: BCrypt is really fucky when it comes to NULL termination. A bunch of libraries were vulnerable to \x00 injection.
In addition, the final NULL termination is supposed to be carried into the hash. For this reason we use AuStrings
instead of memory views by default. Only use the MemoryView with an additional NUL byte otherwise your hashes will
not be compatible with other software. This could be a problem for database [accessing?] software.
Note 3: ...with AuStrings being recommended to prevent fuck-ups between other bcrypt implementations, the [...]Safer variants
enforce zeroing out of the passwords character buffer before the function returns.
***/ ***/
#pragma once #pragma once
@ -18,7 +26,9 @@ namespace Aurora::Crypto::BCrypt
AUKN_SYM AuString HashPassword(const AuString &password, const AuString &salt); AUKN_SYM AuString HashPassword(const AuString &password, const AuString &salt);
AUKN_SYM AuString HashPasswordEx(const Memory::MemoryViewRead &password, const AuString &salt); AUKN_SYM AuString HashPasswordEx(const Memory::MemoryViewRead &password, const AuString &salt);
AUKN_SYM AuString HashPasswordSafer(AuString &&password, const AuString &salt);
AUKN_SYM bool CheckPassword(const AuString &password, const AuString &hashedPassword); AUKN_SYM bool CheckPassword(const AuString &password, const AuString &hashedPassword);
AUKN_SYM bool CheckPasswordEx(const Memory::MemoryViewRead &password, const AuString &hashedPassword); AUKN_SYM bool CheckPasswordEx(const Memory::MemoryViewRead &password, const AuString &hashedPassword);
AUKN_SYM bool CheckPasswordSafer(AuString &&password, const AuString &hashedPassword);
} }

View File

@ -69,6 +69,14 @@ namespace Aurora::Crypto::BCrypt
return pRet; return pRet;
} }
AUKN_SYM AuString HashPasswordSafer(AuString &&password, const AuString &salt)
{
auto ret = HashPassword(password, salt);
AuMemset(password.data(), 0, password.size());
return ret;
}
AUKN_SYM bool CheckPassword(const AuString &password, const AuString &hashedPassword) AUKN_SYM bool CheckPassword(const AuString &password, const AuString &hashedPassword)
{ {
return CheckPasswordEx({ password.c_str(), password.size() + 1 }, hashedPassword); return CheckPasswordEx({ password.c_str(), password.size() + 1 }, hashedPassword);
@ -99,6 +107,16 @@ namespace Aurora::Crypto::BCrypt
} }
// I don't care about safe eval... // I don't care about safe eval...
// I refuse to believe side channel attacks are possible outside of circlejerk academic settings.
// Especially with vectorization optimizations of memcpy. Even if you could tell how quickly we fail,
// it's highly unlikely you could backfeed this into bcrypt to reguess a similar digest string.
return cryptBuffer == hashedPassword; return cryptBuffer == hashedPassword;
} }
AUKN_SYM bool CheckPasswordSafer(AuString &&password, const AuString &hashedPassword)
{
auto ret = CheckPassword(password, hashedPassword);
AuMemset(password.data(), 0, password.size());
return ret;
}
} }