Added XTEA and Pearson Hashing.

Improved message encryption for RF24.
This commit is contained in:
2018-09-22 22:05:53 +02:00
committed by matzman
parent 15351cdd5b
commit b37cd045d5
12 changed files with 270 additions and 7 deletions
+16
View File
@@ -36,9 +36,16 @@
#include <stdint.h>
#endif
#define PROTOCOL_VERSION (2u) //!< The version of the protocol
#define MAX_MESSAGE_LENGTH (32u) //!< The maximum size of a message (including header)
#if (defined (MY_MESSAGE_ENABLE_HASH) && defined(MY_MESSAGE_ENABLE_NONCE))
#define HEADER_SIZE (11u) //!< The size of the header
#elif (defined (MY_MESSAGE_ENABLE_HASH) || defined(MY_MESSAGE_ENABLE_NONCE))
#define HEADER_SIZE (9u) //!< The size of the header
#else
#define HEADER_SIZE (7u) //!< The size of the header
#endif
#define MAX_PAYLOAD (MAX_MESSAGE_LENGTH - HEADER_SIZE) //!< The maximum size of a payload depends on #MAX_MESSAGE_LENGTH and #HEADER_SIZE
/// @brief The command field (message-type) defines the overall properties of a message
@@ -495,6 +502,15 @@ typedef union {
* 3 bit - Payload data type
*/
uint8_t command_ack_payload;
#if defined (MY_MESSAGE_ENABLE_NONCE)
// The salt/nonce need to be in the first XTEA block
uint16_t _nounce; // 16 bit - nounce
#endif
#if defined (MY_MESSAGE_ENABLE_HASH)
uint16_t _hash; // 16 bit - CRC16 checksum
#endif
uint8_t type; ///< 8 bit - Type varies depending on command
uint8_t sensor; ///< 8 bit - Id of sensor that this message concerns.
+13 -1
View File
@@ -40,7 +40,7 @@ MyMessage _msgTmp; // Buffer for temporary messages (acks and nonces among othe
static coreConfig_t _coreConfig;
#if defined(DEBUG_OUTPUT_ENABLED)
char _convBuf[MAX_PAYLOAD*2+1];
char _convBuf[MAX_PAYLOAD*2+10];
#endif
// Callback for transport=ok transition
@@ -313,12 +313,24 @@ bool _sendRoute(MyMessage &message)
#endif
}
#if defined (MY_MESSAGE_ENABLE_NONCE)
uint16_t _nounce = 0;
bool send(MyMessage &message, const bool enableAck) {
return send(message, enableAck, _nounce++);
}
bool send(MyMessage &message, const bool enableAck, uint16_t nounce)
#else
bool send(MyMessage &message, const bool enableAck)
#endif
{
message.sender = getNodeId();
mSetCommand(message, C_SET);
mSetRequestAck(message, enableAck);
#if defined(MY_MESSAGE_ENABLE_NONCE)
message._nounce = nounce;
#endif
#if defined(MY_REGISTRATION_FEATURE) && !defined(MY_GATEWAY_FEATURE)
if (_coreConfig.nodeRegistered) {
return _sendRoute(message);
+4
View File
@@ -159,6 +159,10 @@ bool sendSketchInfo(const __FlashStringHelper *name, const __FlashStringHelper *
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool send(MyMessage &msg, const bool ack = false);
#if defined(MY_MESSAGE_ENABLE_NONCE)
bool send(MyMessage &message, const bool enableAck, uint16_t nounce);
#endif
/**
* Send this nodes battery level to gateway.
+28 -5
View File
@@ -19,10 +19,14 @@
#include "MyTransport.h"
#if defined(MY_MESSAGE_ENABLE_HASH)
#include "drivers/PearsonHash/PearsonHash.cpp"
#endif
// debug
#if defined(MY_DEBUG_VERBOSE_TRANSPORT)
#define TRANSPORT_DEBUG(x,...) DEBUG_OUTPUT(x, ##__VA_ARGS__) //!< debug
extern char _convBuf[MAX_PAYLOAD * 2 + 1];
extern char _convBuf[MAX_PAYLOAD * 2 + 10];
#else
#define TRANSPORT_DEBUG(x,...) //!< debug NULL
#endif
@@ -647,7 +651,7 @@ void transportProcessMessage(void)
const uint8_t msgLength = min(mGetLength(_msg), (uint8_t)MAX_PAYLOAD);
// calculate expected length
const uint8_t expectedMessageLength = HEADER_SIZE + (mGetSigned(_msg) ? MAX_PAYLOAD : msgLength);
#if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_NRF5_ESB_ENABLE_ENCRYPTION) || defined(MY_RFM95_ENABLE_ENCRYPTION)
#if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_RF24_ENABLE_XTEA) || defined(MY_NRF5_ESB_ENABLE_ENCRYPTION) || defined(MY_RFM95_ENABLE_ENCRYPTION)
// payload length = a multiple of blocksize length for decrypted messages, i.e. cannot be used for payload length check
payloadLength = expectedMessageLength;
#endif
@@ -663,6 +667,18 @@ void transportProcessMessage(void)
mGetSigned(_msg), ((command == C_INTERNAL &&
type == I_NONCE_RESPONSE) ? "<NONCE>" : _msg.getString(_convBuf)));
#if defined (MY_MESSAGE_ENABLE_HASH)
// Reject messages that do not pass CRC check
auto hash = _msg._hash;
_msg._hash = 0;
if (!PearsonHash::checkHash16(hash, &_msg.last+1, expectedMessageLength-sizeof(_msg.last))) { // do NOT include _msg.last
setIndication(INDICATION_ERR_SIGN);
TRANSPORT_DEBUG(PSTR("!TSF:MSG:CRC VERIFY FAIL\n"));
return;
}
_msg._hash = hash;
#endif
// Reject payloads with incorrect length
if (payloadLength != expectedMessageLength) {
setIndication(INDICATION_ERR_LENGTH);
@@ -932,7 +948,7 @@ void transportProcessMessage(void)
(void)transportRouteMessage(_msg);
}
#else
TRANSPORT_DEBUG(PSTR("!TSF:MSG:REL MSG,NREP\n")); // message relaying request, but not a repeater
TRANSPORT_DEBUG(PSTR("!TSF:MSG:REL MSG,NREP,D=%" PRIu8 ", Id=%" PRIu8 "\n"), destination, _transportConfig.nodeId); // message relaying request, but not a repeater
#endif
}
(void)last; //avoid cppcheck warning
@@ -979,6 +995,7 @@ void transportProcessFIFO(void)
bool transportSendWrite(const uint8_t to, MyMessage &message)
{
message.last = _transportConfig.nodeId; // Update last
// sign message if required
if (!signerSignMsg(message)) {
@@ -988,8 +1005,14 @@ bool transportSendWrite(const uint8_t to, MyMessage &message)
}
// msg length changes if signed
const uint8_t totalMsgLength = HEADER_SIZE + ( mGetSigned(message) ? MAX_PAYLOAD : mGetLength(
message) );
const uint8_t totalMsgLength = min(HEADER_SIZE + ( mGetSigned(message) ? MAX_PAYLOAD : mGetLength(
message) ), MAX_MESSAGE_LENGTH);
#if defined (MY_MESSAGE_ENABLE_HASH)
//calculate crc
message._hash = 0;
message._hash = PearsonHash::calcHash16(&message.last+1, totalMsgLength-sizeof(message.last)); // Do not include message.last;
#endif
// send
setIndication(INDICATION_TX);