diff --git a/src/m_pw.cpp b/src/m_pw.cpp index e27707c89..1154320b3 100644 --- a/src/m_pw.cpp +++ b/src/m_pw.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -36,12 +35,13 @@ #include "m_pw_hash.h" #include "s_sound.h" #include "sounds.h" -#include "stun.h" // csprng #include "z_zone.h" namespace { +constexpr const UINT8 kRRSalt[17] = "0L4rlK}{9ay6'VJS"; + struct Pw { Pw(void (*cb)(), const char *encoded_hash) : cb_(cb), hash_(decode_hash(encoded_hash)) {} @@ -102,18 +102,21 @@ try_password_e M_TryPassword(const char *password, boolean conditions) std::string key = password; strlwr(key.data()); - auto worker = [&key](const UINT8* hash, var result) + UINT8 key_hash[M_PW_HASH_SIZE]; + M_HashPassword(key_hash, key.c_str(), kRRSalt); + + auto worker = [key_hash](const UINT8* hash, var result) { - if (M_HashCompare(hash, key.c_str())) + if (memcmp(key_hash, hash, M_PW_HASH_SIZE)) result = std::monostate {}; // fail state return result; }; - // Because hashing is time consuming, do the work in parallel. - std::vector> jobs; + var result; auto add_job = [&](auto&&... args) { - jobs.push_back(std::move(std::async(std::launch::async, worker, args...))); + if (var n = worker(args...); !std::holds_alternative(n)) + result = n; }; for (Pw& pw : passwords) @@ -123,15 +126,6 @@ try_password_e M_TryPassword(const char *password, boolean conditions) if (conditions) iter_conditions([&](condition_t* cn) { add_job((const UINT8*)cn->stringvar, cn); }); - var result; - for (auto& job : jobs) - { - SRB2_ASSERT(job.valid()); - // Wait for every thread to finish, then retrieve the last matched password (if any). - if (var n = job.get(); !std::holds_alternative(n)) - result = n; - } - try_password_e return_code = M_PW_INVALID; if (!std::holds_alternative(result)) { @@ -172,11 +166,8 @@ void Command_Crypt_f(void) auto gen = [](char *input) { UINT8 bin[M_PW_BUF_SIZE]; - UINT8* salt = &bin[M_PW_HASH_SIZE]; - csprng(salt, M_PW_SALT_SIZE); // randomize salt - strlwr(input); - M_HashPassword(bin, input, salt); + M_HashPassword(bin, input, kRRSalt); CONS_Printf("%s %s\n", input, modp::b64_encode((const char*)bin, M_PW_BUF_SIZE).c_str()); }; diff --git a/src/m_pw_hash.c b/src/m_pw_hash.c index a5e30332a..884f1ddfb 100644 --- a/src/m_pw_hash.c +++ b/src/m_pw_hash.c @@ -13,22 +13,9 @@ #include "doomdef.h" #include "m_pw_hash.h" -boolean M_HashCompare(const UINT8 remote[M_PW_BUF_SIZE], const char *key) -{ - UINT8 local[M_PW_HASH_SIZE]; - if (!M_HashPassword(local, key, &remote[M_PW_HASH_SIZE])) - return true; - - // It is OK to use memcmp here. - // Constant time is not a concern, since the hashes are - // freely available anyway. - return memcmp(remote, local, M_PW_HASH_SIZE); -} - UINT8 *M_HashPassword(UINT8 hash[M_PW_HASH_SIZE], const char *key, const UINT8 salt[M_PW_SALT_SIZE]) { - // https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html - size_t memory = 19*1024*1024; + size_t memory = 8*1024*1024; void *int_buf = malloc(memory); if (!int_buf) return NULL; diff --git a/src/m_pw_hash.h b/src/m_pw_hash.h index 046469474..fec6c9558 100644 --- a/src/m_pw_hash.h +++ b/src/m_pw_hash.h @@ -18,9 +18,8 @@ extern "C" { #define M_PW_HASH_SIZE (64) #define M_PW_SALT_SIZE (16) -#define M_PW_BUF_SIZE (M_PW_HASH_SIZE + M_PW_SALT_SIZE) +#define M_PW_BUF_SIZE M_PW_HASH_SIZE -boolean M_HashCompare(const UINT8 hash[M_PW_BUF_SIZE], const char *key); UINT8 *M_HashPassword(UINT8 hash[M_PW_HASH_SIZE], const char *key, const UINT8 salt[M_PW_SALT_SIZE]); #ifdef __cplusplus