Public Access
hmac_sign() previously trusted whatever secret_hex came out of NVS: - Lengths >128 chars overflowed the fixed 64-byte stack buffer in hex_to_bytes (out_len was unbounded). - Non-hex characters were silently decoded to 0 via strtol with no end-pointer check, producing signatures under a corrupted key. - Empty secrets fell through to mbedtls_md_hmac_starts with len=0. flash_device.py now rejects malformed --hmac-secret at provision time, but hmac_sign should also refuse to sign under a malformed key regardless of how it ended up in NVS (legacy provisioning, partial flash, etc.). Add length, hex-charset, and even-length validation; make hex_to_bytes return bool and have hmac_sign return empty HString on any failure (callers already treat empty as failure via post_json_once). Found via adversarial review (run 2026-05-01-202910, both reviewers). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>