Hold cryptLock around RNG use in admin and key verification (#11096)

setPassKey drew the session passkey outside cryptLock, unlike the signing
and key verification paths. Also replaces random() for the key verification
nonce with the hardware RNG.
This commit is contained in:
Thomas Göttgens
2026-07-20 18:36:06 -05:00
committed by GitHub
co-authored by GitHub
parent 67e2012136
commit 51019b14f4
2 changed files with 17 additions and 3 deletions
+9 -2
View File
@@ -1,5 +1,6 @@
#include "AdminModule.h"
#include "Channels.h"
#include "CryptoEngine.h"
#include "DisplayFormatters.h"
#include "HardwareRNG.h"
#include "MeshService.h"
@@ -1849,8 +1850,14 @@ void AdminModule::setPassKey(meshtastic_AdminMessage *res)
if (!sessionPasskeyValid || !Throttle::isWithinTimespanMs(session_time, 150 * 1000UL)) {
// Session passkey authenticates admin replies, so it must be unpredictable: prefer the
// hardware RNG, falling back to the seeded CSPRNG only when no hardware source exists.
if (!HardwareRNG::fill(session_passkey, sizeof(session_passkey)))
CryptRNG.rand(session_passkey, sizeof(session_passkey));
// Hold cryptLock like the signing path does: this runs on the admin receive path, which on
// nRF52 is the BLE task, and the fill toggles the CC310 that packet crypto also uses while
// the CryptRNG state is shared with signing.
{
concurrency::LockGuard g(cryptLock);
if (!HardwareRNG::fill(session_passkey, sizeof(session_passkey)))
CryptRNG.rand(session_passkey, sizeof(session_passkey));
}
session_time = millis();
sessionPasskeyValid = true;
}