/* * auth_crypto.cpp - bcrypt C++ wrapper implementation */ #include "auth_crypto.h" #include "bcrypt/bcrypt.h" #include #include #include #include namespace auth { static const int BCRYPT_COST = 12; std::string bcrypt_hash(const std::string &password) { char salt[64]; char hash[128]; if (bcrypt_gensalt(BCRYPT_COST, salt) != 0) return ""; if (bcrypt_hashpw(password.c_str(), salt, hash) != 0) return ""; return std::string(hash); } std::string bcrypt_hash_with_salt(const std::string &password, const std::string &salt) { char hash[128]; if (bcrypt_hashpw(password.c_str(), salt.c_str(), hash) != 0) return ""; return std::string(hash); } bool bcrypt_verify(const std::string &password, const std::string &hash) { return ::bcrypt_verify(password.c_str(), hash.c_str()) == 1; } std::string random_bytes(int byte_count) { std::string result(byte_count, '\0'); int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) return ""; ssize_t n = read(fd, &result[0], byte_count); close(fd); if (n != byte_count) return ""; return result; } static const char hex_chars[] = "0123456789abcdef"; std::string random_hex(int byte_count) { std::string raw = random_bytes(byte_count); if (raw.empty()) return ""; std::string hex(byte_count * 2, '\0'); for (int i = 0; i < byte_count; i++) { hex[i * 2] = hex_chars[(uint8_t)raw[i] >> 4]; hex[i * 2 + 1] = hex_chars[(uint8_t)raw[i] & 0x0f]; } return hex; } bool secure_compare(const std::string &a, const std::string &b) { if (a.size() != b.size()) return false; volatile unsigned char result = 0; for (size_t i = 0; i < a.size(); i++) { result |= (unsigned char)a[i] ^ (unsigned char)b[i]; } return result == 0; } } // namespace auth