mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-04 03:18:10 +10:00
perf(crypto): stop heap-allocating a cipher object per packet (#11462)
* perf(crypto): stop heap-allocating a cipher object per packet encryptAESCtr() constructed a fresh CTR<AES128/256> on the heap for every call - once per encrypted transmit and once per channel decrypt attempt on every received encrypted packet. On the platforms that use this base implementation (STM32WL, RP2040, nRF54L15, portduino) that is avoidable per-packet malloc/free churn on small heaps. Reuse lazily-created singletons instead. Safe for the same reason the function's static scratch buffer already is: every caller serializes under cryptLock, and setKey/setIV reinitialize the cipher state each call. Lazy heap pointers rather than static objects so ESP32/nRF52 (which override this method) never reserve the RAM. * Improve comments in encryptAESCtr function Refactor comments for clarity and conciseness in AES-CTR encryption implementation. --------- Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
This commit is contained in:
co-authored by
Thomas Göttgens
parent
a65d9aef39
commit
fa031c95dc
@@ -403,11 +403,20 @@ void CryptoEngine::decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes
|
||||
// Generic implementation of AES-CTR encryption.
|
||||
void CryptoEngine::encryptAESCtr(CryptoKey _key, uint8_t *_nonce, size_t numBytes, uint8_t *bytes)
|
||||
{
|
||||
std::unique_ptr<CTRCommon> ctr;
|
||||
if (_key.length == 16)
|
||||
ctr = std::unique_ptr<CTRCommon>(new CTR<AES128>());
|
||||
else
|
||||
ctr = std::unique_ptr<CTRCommon>(new CTR<AES256>());
|
||||
// Reused instead of reallocated per packet: safe because all callers hold cryptLock and setKey/setIV reset the
|
||||
// full cipher state. Lazy so overriding platforms reserve nothing; key material now lives until the next call.
|
||||
static CTR<AES128> *ctr128 = nullptr;
|
||||
static CTR<AES256> *ctr256 = nullptr;
|
||||
CTRCommon *ctr;
|
||||
if (_key.length == 16) {
|
||||
if (!ctr128)
|
||||
ctr128 = new CTR<AES128>();
|
||||
ctr = ctr128;
|
||||
} else {
|
||||
if (!ctr256)
|
||||
ctr256 = new CTR<AES256>();
|
||||
ctr = ctr256;
|
||||
}
|
||||
ctr->setKey(_key.bytes, _key.length);
|
||||
static uint8_t scratch[MAX_BLOCKSIZE];
|
||||
memcpy(scratch, bytes, numBytes);
|
||||
|
||||
Reference in New Issue
Block a user