mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-02 08:00:38 +00:00
Refactor platform cryptography, add tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "CryptoEngine.h"
|
||||
#include "NodeDB.h"
|
||||
#include "RadioInterface.h"
|
||||
#include "architecture.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||
@@ -188,14 +189,44 @@ void CryptoEngine::setKey(const CryptoKey &k)
|
||||
*
|
||||
* @param bytes is updated in place
|
||||
*/
|
||||
void CryptoEngine::encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes)
|
||||
void CryptoEngine::encryptPacket(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes)
|
||||
{
|
||||
LOG_WARN("noop encryption!\n");
|
||||
if (key.length > 0) {
|
||||
initNonce(fromNode, packetId);
|
||||
if (numBytes <= MAX_BLOCKSIZE) {
|
||||
encryptAESCtr(key, nonce, numBytes, bytes);
|
||||
} else {
|
||||
LOG_ERROR("Packet too large for crypto engine: %d. noop encryption!\n", numBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CryptoEngine::decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes)
|
||||
{
|
||||
LOG_WARN("noop decryption!\n");
|
||||
// For CTR, the implementation is the same
|
||||
encryptPacket(fromNode, packetId, numBytes, bytes);
|
||||
}
|
||||
|
||||
// Generic implementation of AES-CTR encryption.
|
||||
void CryptoEngine::encryptAESCtr(CryptoKey _key, uint8_t *_nonce, size_t numBytes, uint8_t *bytes)
|
||||
{
|
||||
if (ctr) {
|
||||
delete ctr;
|
||||
ctr = nullptr;
|
||||
}
|
||||
if (_key.length == 16)
|
||||
ctr = new CTR<AES128>();
|
||||
else
|
||||
ctr = new CTR<AES256>();
|
||||
ctr->setKey(_key.bytes, _key.length);
|
||||
static uint8_t scratch[MAX_BLOCKSIZE];
|
||||
memcpy(scratch, bytes, numBytes);
|
||||
memset(scratch + numBytes, 0,
|
||||
sizeof(scratch) - numBytes); // Fill rest of buffer with zero (in case cypher looks at it)
|
||||
|
||||
ctr->setIV(_nonce, 16);
|
||||
ctr->setCounterSize(4);
|
||||
ctr->encrypt(bytes, scratch, numBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,4 +239,7 @@ void CryptoEngine::initNonce(uint32_t fromNode, uint64_t packetId)
|
||||
// use memcpy to avoid breaking strict-aliasing
|
||||
memcpy(nonce, &packetId, sizeof(uint64_t));
|
||||
memcpy(nonce + sizeof(uint64_t), &fromNode, sizeof(uint32_t));
|
||||
}
|
||||
}
|
||||
#ifndef HAS_CUSTOM_CRYPTO_ENGINE
|
||||
CryptoEngine *crypto = new CryptoEngine;
|
||||
#endif
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "AES.h"
|
||||
#include "CTR.h"
|
||||
#include "concurrency/LockGuard.h"
|
||||
#include "configuration.h"
|
||||
#include "mesh-pb-constants.h"
|
||||
@@ -65,15 +66,16 @@ class CryptoEngine
|
||||
*
|
||||
* @param bytes is updated in place
|
||||
*/
|
||||
virtual void encrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes);
|
||||
virtual void encryptPacket(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes);
|
||||
virtual void decrypt(uint32_t fromNode, uint64_t packetId, size_t numBytes, uint8_t *bytes);
|
||||
virtual void encryptAESCtr(CryptoKey key, uint8_t *nonce, size_t numBytes, uint8_t *bytes);
|
||||
#ifndef PIO_UNIT_TESTING
|
||||
protected:
|
||||
#endif
|
||||
/** Our per packet nonce */
|
||||
uint8_t nonce[16] = {0};
|
||||
|
||||
CryptoKey key = {};
|
||||
CTRCommon *ctr = NULL;
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||
uint8_t shared_key[32] = {0};
|
||||
uint8_t private_key[32] = {0};
|
||||
|
||||
@@ -480,7 +480,7 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p)
|
||||
memcpy(p->encrypted.bytes, ScratchEncrypted, numbytes);
|
||||
p->channel = 0;
|
||||
} else {
|
||||
crypto->encrypt(getFrom(p), p->id, numbytes, bytes);
|
||||
crypto->encryptPacket(getFrom(p), p->id, numbytes, bytes);
|
||||
memcpy(p->encrypted.bytes, bytes, numbytes);
|
||||
}
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user