mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-02 19:13:50 +00:00
crypto: harden all crypto-sensitive memcmp + memset sites
Audit-driven sweep found additional compiler-optimization-sensitive patterns beyond the login password compare just fixed: P4.F3 (HIGH) — Utils::MACThenDecrypt verified packet MACs with plain memcmp. Runs on EVERY encrypted-then-MAC'd packet in the mesh; a timing oracle here lets attackers forge MACs byte-by-byte across the whole mesh layer. Replaced with constantTimeEqual. P4.F4 (MEDIUM) — Multiple memset(secret, 0, ...) calls on stack-resident crypto buffers (Ed25519 seed, ADC noise pool, AES key derived in extract_via_aes_ctr, HWINFO unique ID) were subject to dead-store elimination under -Os. GCC/Clang routinely elide these when the buffer is never read after; the wipe vanishes and the secret persists on stack until next call overwrites. Replaced with secureZeroize using volatile pointer writes. P4.F5 (LOW) — Identity::validatePrivateKey boot self-test compared shared secrets with plain memcmp. Boot-only, no attacker observation channel, but hygiene matters and the fix is one line. Also added secret-wipe for ss1/ss2 on all return paths. Promoted the local ct_memeq() previously added to RepeaterMesh.cpp into Utils::constantTimeEqual + Utils::secureZeroize (Utils.h/cpp) so the login compare and MAC compare share the same audited helper. Both helpers verified by Thumb-2 disassembly on rak3401_1watt: - constantTimeEqual: loop branches on iterator, accumulator load-modify-stored to stack every iteration, final return uses CLZ+LSR (no conditional branch on result). - secureZeroize: STRB.W to memory in a counted loop, not replaced with memset builtin and not eliminated.
This commit is contained in:
@@ -82,12 +82,21 @@ bool LocalIdentity::validatePrivateKey(const uint8_t prv[64])
|
||||
uint8_t ss1[32], ss2[32];
|
||||
ed25519_key_exchange(ss1, test_client_pub, prv);
|
||||
ed25519_key_exchange(ss2, pub, test_client_prv);
|
||||
if (memcmp(ss1, ss2, 32) != 0) return false;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (ss1[i] != 0) return true;
|
||||
/* Constant-time even though this self-test runs at boot before
|
||||
* any networking is up — hygiene + no attacker observation. */
|
||||
if (!Utils::constantTimeEqual(ss1, ss2, 32)) {
|
||||
Utils::secureZeroize(ss1, sizeof(ss1));
|
||||
Utils::secureZeroize(ss2, sizeof(ss2));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
bool nonzero = false;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (ss1[i] != 0) { nonzero = true; break; }
|
||||
}
|
||||
Utils::secureZeroize(ss1, sizeof(ss1));
|
||||
Utils::secureZeroize(ss2, sizeof(ss2));
|
||||
return nonzero;
|
||||
}
|
||||
|
||||
bool LocalIdentity::readFrom(const uint8_t *src, size_t len)
|
||||
|
||||
Reference in New Issue
Block a user