/*
 * newpwd.h - replacement password hashing for ISQL.
 *
 * Copyright (c) 2026 Muhammad Anisur Rahman
 *
 * WHY THIS EXISTS
 * The original PwdEncrypt has NO SOURCE (task #51): it survives only as a
 * compiled object inside isqllib.lib. Nobody can read its algorithm,
 * audit its strength, port it, or regenerate it - and one clean rebuild
 * of that archive would destroy every stored password permanently. That
 * is not a foundation a release can stand on.
 *
 * This replaces it with a scheme that is entirely in source, built from
 * SHA-256 implemented here clean-room from FIPS 180-4. No third-party
 * code, consistent with the rest of the toolchain.
 *
 * DROP-IN SHAPE
 * The original was used as  strcmp(PwdEncrypt(input), stored_pwd)  - a
 * deterministic transform compared for equality. NewPwdEncrypt keeps that
 * exact shape so the call sites change by name only. It is DETERMINISTIC
 * (same password -> same hash), which is what makes it drop-in.
 *
 * THE TRADE-OFF, STATED HONESTLY
 * A deterministic hash has no per-user salt, so two users with the same
 * password get the same stored value, and a precomputed table could be
 * used against a stolen database. That is strictly better than an
 * unknown/lost algorithm, and it is drop-in. When the login architecture
 * can afford a separate verify step, use NewPwdVerify with the salted
 * form instead - it is provided here and is the correct long-term choice.
 *
 * C++98 / MSVC / gcc / kcpp compatible. No dependencies.
 */
#ifndef NEWPWD_H
#define NEWPWD_H

#ifdef __cplusplus
extern "C" {
#endif

/* Raw SHA-256. digest is 32 bytes. Exposed so it can be tested directly
   against the FIPS test vectors - a hash you cannot check against a known
   answer is a hash you cannot trust. */
void NewSha256(const unsigned char *data, unsigned long len,
               unsigned char digest[32]);

/* SHA-256 as a lowercase hex string. 'out' must hold at least 65 bytes. */
void NewSha256Hex(const unsigned char *data, unsigned long len, char *out);

/* DROP-IN replacement for PwdEncrypt. Deterministic. Writes a 64-char
   lowercase hex hash (plus NUL) into 'encrypted', which must hold >= 65
   bytes. Returns 1 on success. A fixed application pepper is mixed in so
   the stored values are not bare SHA-256 of the password, which slightly
   raises the bar against a generic rainbow table. */
int NewPwdEncrypt(const char *pwd, char *encrypted);

/* SALTED form, the better long-term scheme. NewPwdHash produces
   "salt:hash" (salt is 16 hex chars, hash is 64); NewPwdVerify recomputes
   with the embedded salt and compares in constant time. Use these once a
   call site can store the salted string and call a verify function rather
   than strcmp. 'out' must hold >= 96 bytes. */
int NewPwdHash(const char *pwd, char *out);
int NewPwdVerify(const char *pwd, const char *stored);   /* 1 = match */

#ifdef __cplusplus
}
#endif

#endif /* NEWPWD_H */
