mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 20:09:17 +00:00
crypto: switch login password compare to volatile-based ct_memeq
mbedtls_ct_memcmp is declared in the tf-psa-crypto header but its implementation isn't compiled into the current Zephyr mbedtls build (would require enabling additional TLS features). Use a local ct_memeq() with `volatile uint8_t` accumulator instead — pattern matches rweather/arduinolibs Crypto.cpp secure_compare(). Disassembly verified on rak3401_1watt (Thumb-2): loop branches on the iterator pointer not the accumulator, result is load-modify- stored to stack every iteration (volatile preserved), final return uses clz+shift instead of a conditional branch on the value. Spotted by nextgens during review of meshcore-dev/MeshCore#2556 mitigations.
This commit is contained in:
@@ -122,18 +122,22 @@ void RepeaterMesh::putNeighbour(const mesh::Identity& id, uint32_t timestamp, fl
|
||||
* byte of `a` matches `b`. No early exit — timing is independent of input,
|
||||
* defeating timing-leak attacks against password comparison.
|
||||
*
|
||||
* `volatile` on the accumulator prevents the compiler from short-circuiting
|
||||
* the XOR-OR loop back into a branching memcmp under aggressive LTO. Pattern
|
||||
* matches rweather/arduinolibs Crypto.cpp secure_compare(). mbedtls offers
|
||||
* mbedtls_ct_memcmp() but its implementation lives in a .c file that isn't
|
||||
* pulled into the Zephyr mbedtls build under current Kconfig — would require
|
||||
* enabling additional TLS features just for this one function.
|
||||
*
|
||||
* Mitigation for the password-handling weakness tracked upstream as
|
||||
* meshcore-dev/MeshCore#2556. The protocol still sends plaintext passwords
|
||||
* (encrypted only at the mesh layer to whatever pubkey the user selected),
|
||||
* but this fix removes the timing oracle that would otherwise let an
|
||||
* already-MITM attacker reveal the stored password byte-by-byte. */
|
||||
* meshcore-dev/MeshCore#2556. See CRYPTO_AUDIT_INDEX.md P4.F1. */
|
||||
static bool ct_memeq(const uint8_t *a, const uint8_t *b, size_t n)
|
||||
{
|
||||
uint8_t diff = 0;
|
||||
volatile uint8_t result = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
diff |= (uint8_t)(a[i] ^ b[i]);
|
||||
result |= (uint8_t)(a[i] ^ b[i]);
|
||||
}
|
||||
return diff == 0;
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
uint8_t RepeaterMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood) {
|
||||
|
||||
Reference in New Issue
Block a user