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:
co-authored by
GitHub
parent
67e2012136
commit
51019b14f4
@@ -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;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,14 @@ bool KeyVerificationModule::sendInitialRequest(NodeNum remoteNode)
|
||||
return false;
|
||||
}
|
||||
updateState(true);
|
||||
currentNonce = random();
|
||||
// The nonce binds the handshake, so draw it from the hardware RNG (falling back to the CSPRNG)
|
||||
// under cryptLock, as allocReply does for the security number. random() is both predictable and
|
||||
// only 32 bits wide, leaving half of this nonce zero.
|
||||
{
|
||||
concurrency::LockGuard g(cryptLock);
|
||||
if (!HardwareRNG::fill((uint8_t *)¤tNonce, sizeof(currentNonce)))
|
||||
CryptRNG.rand((uint8_t *)¤tNonce, sizeof(currentNonce));
|
||||
}
|
||||
currentNonceTimestamp = getTime();
|
||||
currentRemoteNode = remoteNode;
|
||||
meshtastic_KeyVerification KeyVerification = meshtastic_KeyVerification_init_zero;
|
||||
|
||||
Reference in New Issue
Block a user