1.2-legacy
geeksville 2020-05-09 19:08:04 -07:00
rodzic 1cc24de787
commit 3e356e5866
8 zmienionych plików z 137 dodań i 21 usunięć

Wyświetl plik

@ -4,7 +4,7 @@ This project is still pretty young but moving at a pretty good pace. Not all fea
Most of these problems should be solved by the beta release (within three months):
- We don't make these devices and they haven't been tested by UL or the FCC. If you use them you are experimenting and we can't promise they won't burn your house down ;-)
- Encryption is turned off for now
- The encryption [implementation](software/crypto.md) has not been reviewed by an expert. (Are you an expert? Please help us)
- A number of (straightforward) software work items have to be completed before battery life matches our measurements, currently battery life is about three days. Join us on chat if you want the spreadsheet of power measurements/calculations.
- The Android API needs to be documented better
- No one has written an iOS app yet. But some good souls [are talking about it](https://github.com/meshtastic/Meshtastic-esp32/issues/14) ;-)

2
proto

@ -1 +1 @@
Subproject commit f775ebe369cd9bd92d954d46f76ea0a4ae62078c
Subproject commit 5e2df6c9986cd75f0af4eab1ba0d2aacf258aaab

Wyświetl plik

@ -0,0 +1,83 @@
#include "CryptoEngine.h"
#include "configuration.h"
#include "crypto/includes.h"
#include "crypto/common.h"
// #include "esp_system.h"
#include "crypto/aes.h"
#include "crypto/aes_wrap.h"
#include "mbedtls/aes.h"
#define MAX_BLOCKSIZE 256
class ESP32CryptoEngine : public CryptoEngine
{
mbedtls_aes_context aes;
/// How many bytes in our key
uint8_t keySize = 0;
public:
ESP32CryptoEngine() { mbedtls_aes_init(&aes); }
~ESP32CryptoEngine() { mbedtls_aes_free(&aes); }
/**
* Set the key used for encrypt, decrypt.
*
* As a special case: If all bytes are zero, we assume _no encryption_ and send all data in cleartext.
*
* @param numBytes must be 16 (AES128), 32 (AES256) or 0 (no crypt)
* @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the
* provided pointer)
*/
virtual void setKey(size_t numBytes, uint8_t *bytes)
{
keySize = numBytes;
DEBUG_MSG("Installing AES%d key!\n", numBytes * 8);
if (numBytes != 0) {
auto res = mbedtls_aes_setkey_enc(&aes, bytes, numBytes * 8);
assert(!res);
}
}
/**
* Encrypt a packet
*
* @param bytes is updated in place
*/
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
{
if (keySize != 0) {
uint8_t stream_block[16];
static uint8_t scratch[MAX_BLOCKSIZE];
size_t nc_off = 0;
// DEBUG_MSG("ESP32 encrypt!\n");
initNonce(fromNode, packetNum);
assert(numBytes <= 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)
auto res = mbedtls_aes_crypt_ctr(&aes, numBytes, &nc_off, nonce, stream_block, scratch, bytes);
assert(!res);
}
}
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
{
// DEBUG_MSG("ESP32 decrypt!\n");
// For CTR, the implementation is the same
encrypt(fromNode, packetNum, numBytes, bytes);
}
private:
};
CryptoEngine *crypto = new ESP32CryptoEngine();

Wyświetl plik

@ -1,7 +1,7 @@
#include "CryptoEngine.h"
#include "configuration.h"
void CryptoEngine::setKey(size_t numBytes, const uint8_t *bytes)
void CryptoEngine::setKey(size_t numBytes, uint8_t *bytes)
{
DEBUG_MSG("WARNING: Using stub crypto - all crypto is sent in plaintext!\n");
}
@ -19,4 +19,14 @@ void CryptoEngine::encrypt(uint32_t fromNode, uint64_t packetNum, size_t numByte
void CryptoEngine::decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes)
{
DEBUG_MSG("WARNING: noop decryption!\n");
}
/**
* Init our 128 bit nonce for a new packet
*/
void CryptoEngine::initNonce(uint32_t fromNode, uint64_t packetNum)
{
memset(nonce, 0, sizeof(nonce));
*((uint64_t *)&nonce[0]) = packetNum;
*((uint32_t *)&nonce[8]) = fromNode;
}

Wyświetl plik

@ -5,27 +5,46 @@
/**
* see docs/software/crypto.md for details.
*
* The NONCE is constructed by concatenating:
* a 32 bit sending node number + a 64 bit packet number + a 32 bit block counter (starts at zero)
*/
class CryptoEngine
{
protected:
/** Our per packet nonce */
uint8_t nonce[16];
public:
virtual ~CryptoEngine() {}
/**
* Set the key used for encrypt, decrypt.
*
* As a special case: If all bytes are zero, we assume _no encryption_ and send all data in cleartext.
*
* @param numBytes must be 32 for now (AES256)
* @param numBytes must be 16 (AES128), 32 (AES256) or 0 (no crypt)
* @param bytes a _static_ buffer that will remain valid for the life of this crypto instance (i.e. this class will cache the
* provided pointer)
*/
void setKey(size_t numBytes, const uint8_t *bytes);
virtual void setKey(size_t numBytes, uint8_t *bytes);
/**
* Encrypt a packet
*
* @param bytes is updated in place
*/
void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes);
void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes);
};
virtual void encrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes);
virtual void decrypt(uint32_t fromNode, uint64_t packetNum, size_t numBytes, uint8_t *bytes);
protected:
/**
* Init our 128 bit nonce for a new packet
*
* The NONCE is constructed by concatenating (from MSB to LSB):
* a 64 bit packet number (stored in little endian order)
* a 32 bit sending node number (stored in little endian order)
* a 32 bit block counter (starts at zero)
*/
void initNonce(uint32_t fromNode, uint64_t packetNum);
};
extern CryptoEngine *crypto;

Wyświetl plik

@ -5,6 +5,7 @@
#include "FS.h"
#include "SPIFFS.h"
#include "CryptoEngine.h"
#include "GPS.h"
#include "NodeDB.h"
#include "PowerFSM.h"
@ -51,7 +52,7 @@ NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_cou
void NodeDB::resetRadioConfig()
{
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on
/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf};
@ -75,10 +76,14 @@ void NodeDB::resetRadioConfig()
channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range
channelSettings.tx_power = 23;
memcpy(&channelSettings.psk, &defaultpsk, sizeof(channelSettings.psk));
memcpy(&channelSettings.psk.bytes, &defaultpsk, sizeof(channelSettings.psk));
channelSettings.psk.size = sizeof(defaultpsk);
strcpy(channelSettings.name, "Default");
}
// Tell our crypto engine about the psk
crypto->setKey(channelSettings.psk.size, channelSettings.psk.bytes);
// temp hack for quicker testing
/*
radioConfig.preferences.screen_on_secs = 30;

Wyświetl plik

@ -4,8 +4,6 @@
#include "configuration.h"
#include "mesh-pb-constants.h"
CryptoEngine *crypto = new CryptoEngine();
/**
* Router todo
*

Wyświetl plik

@ -36,10 +36,11 @@ typedef struct _RouteDiscovery {
pb_callback_t route;
} RouteDiscovery;
typedef PB_BYTES_ARRAY_T(32) ChannelSettings_psk_t;
typedef struct _ChannelSettings {
int32_t tx_power;
ChannelSettings_ModemConfig modem_config;
pb_byte_t psk[16];
ChannelSettings_psk_t psk;
char name[12];
} ChannelSettings;
@ -198,7 +199,7 @@ typedef struct _ToRadio {
#define RouteDiscovery_init_default {{{NULL}, NULL}}
#define SubPacket_init_default {false, Position_init_default, false, Data_init_default, false, User_init_default, 0}
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0}
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0}, ""}
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, ""}
#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0}
@ -213,7 +214,7 @@ typedef struct _ToRadio {
#define RouteDiscovery_init_zero {{{NULL}, NULL}}
#define SubPacket_init_zero {false, Position_init_zero, false, Data_init_zero, false, User_init_zero, 0}
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0}
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0}, ""}
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, ""}
#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0}
@ -355,7 +356,7 @@ X(a, STATIC, SINGULAR, FLOAT, rx_snr, 7)
#define ChannelSettings_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, INT32, tx_power, 1) \
X(a, STATIC, SINGULAR, UENUM, modem_config, 3) \
X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, psk, 4) \
X(a, STATIC, SINGULAR, BYTES, psk, 4) \
X(a, STATIC, SINGULAR, STRING, name, 5)
#define ChannelSettings_CALLBACK NULL
#define ChannelSettings_DEFAULT NULL
@ -498,12 +499,12 @@ extern const pb_msgdesc_t ToRadio_msg;
/* RouteDiscovery_size depends on runtime parameters */
#define SubPacket_size 377
#define MeshPacket_size 419
#define ChannelSettings_size 44
#define RadioConfig_size 120
#define ChannelSettings_size 60
#define RadioConfig_size 136
#define RadioConfig_UserPreferences_size 72
#define NodeInfo_size 132
#define MyNodeInfo_size 85
#define DeviceState_size 18535
#define DeviceState_size 18552
#define DebugString_size 258
#define FromRadio_size 428
#define ToRadio_size 422