For discussion

This commit is contained in:
Henrik Ekblad
2015-02-26 23:53:37 +01:00
parent 23a8a48f8e
commit bf8102ecad
13 changed files with 90 additions and 156 deletions
+20 -83
View File
@@ -1,99 +1,36 @@
#ifndef MyConfig_h
#define MyConfig_h
/***
* Configure Sensor Network
*/
// pick ONE of these - other board layouts can be easily added this way
#define MYSENSORS_SENSOR
//#define MYSENSORS_SERIAL_GATEWAY
//#define MYSENSORS_ETHERNET_GATEWAY
//#define MYSENSORS_MQTT_GATEWAY
/**********************************
* Enable/Disable debug logging
***********************************/
#define DEBUG
// Choose radio type by enabling one of the following
#define MYSENSORS_RF_NRF24
//#define MYSENSORS_RF_RF69
// Choose signing backend by enabling one of the following
#define MYSENSORS_SIGNING_NONE
//#define MYSENSORS_SIGNING_ATSHA204
//#define MYSENSORS_SIGNING_ATSHA204SOFT
/**********************************
* Message Signing Settings
***********************************/
// Define a suitable timeout for a signature verification session
// Consider the turnaround from a nonce being generated to a signed message being received
// which might vary, especially in networks with many hops. 5s ought to be enough for anyone.
#define VERIFICATION_TIMEOUT_MS 5000
#define MY_VERIFICATION_TIMEOUT_MS 5000
#ifdef MYSENSORS_RF_NRF24
#include "MyRFDriverNRF24.h"
typedef class MyRFDriverNRF24 MyRFDriverClass;
#endif
// MySigningDriverAtsha204 settinga
#define MY_ATSHA204_PIN 17 // A3 - pin where ATSHA204 is attached
#ifdef MYSENSORS_RF_RF69
#include "MyRFDriverRF69.h"
typedef class MyRFDriverRF69 MyRFDriverClass;
#endif
// MySigningDriverAtsha204Soft settings
#define MY_RANDOMSEED_PIN 7 // A7 - Pin used for random generation (do not connect anything to this)
// Key to use for HMAC calculation in MySigningDriverAtsha204Soft (32 bytes)
#define MY_HMAC_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
#if defined(MYSENSORS_SERIAL_GATEWAY) || defined(MYSENSORS_ETHERNET_GATEWAY)
#include "MyParserSerial.h"
typedef class MyParserSerial MyParserClass;
#endif
#ifdef MYSENSORS_SIGNING_NONE
#include "MySigningDriverNone.h"
#define SIGNING_IDENTIFIER (0) // Reserved for dummy implementation, will not work with other backends
typedef class MySigningDriverNone MySigningDriverClass;
#endif
/**********************************
* NRF24L01 Driver Defaults
***********************************/
#define RF24_CE_PIN 9
#define RF24_CS_PIN 10
#define RF24_PA_LEVEL RF24_PA_MAX
#ifdef MYSENSORS_SIGNING_ATSHA204
#ifdef MYSENSORS_SENSOR
#define ATSHA204_PIN 17 //A3
#endif
#ifdef MYSENSORS_SERIAL_GATEWAY
#define ATSHA204_PIN 17 //A3
#endif
#if defined(MYSENSORS_ETHERNET_GATEWAY) || defined(MYSENSORS_MQTT_GATEWAY)
#define ATSHA204_PIN 17 //A3
#endif
#include "MySigningDriverAtsha204.h"
#define SIGNING_IDENTIFIER (1) // SHA256-based HMAC (ATSHA204 specific)
typedef class MySigningDriverAtsha204 MySigningDriverClass;
#endif
#ifdef MYSENSORS_SIGNING_ATSHA204SOFT
// Key to use for HMAC calculation
static uint8_t hmacKey[32] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
// Pick an unconnected analog pin for RANDOMSEED_PIN
#ifdef MYSENSORS_SENSOR
#define RANDOMSEED_PIN 7 //A7
#endif
#ifdef MYSENSORS_SERIAL_GATEWAY
#define RANDOMSEED_PIN 7 //A7
#endif
#if defined(MYSENSORS_ETHERNET_GATEWAY) || defined(MYSENSORS_MQTT_GATEWAY)
#define RANDOMSEED_PIN 7 //A7
#endif
#include "MySigningDriverAtsha204Soft.h"
#define SIGNING_IDENTIFIER (1) // SHA256-based HMAC (ATSHA204 specific)
typedef class MySigningDriverAtsha204Soft MySigningDriverClass;
#endif
/***
* Enable/Disable debug logging
*/
#define DEBUG
#endif
+1
View File
@@ -1,5 +1,6 @@
#include "MyParser.h"
#include "MyParserSerial.h"
#include "MyRFDriver.h"
MyParserSerial::MyParserSerial() : MyParser() {}
+31 -27
View File
@@ -1,37 +1,41 @@
#include "MyRFDriver.h"
#include "MyRFDriverNRF24.h"
MyRFDriverNRF24::MyRFDriverNRF24() : MyRFDriver() {
rf24 = new RF24(RF24_CE_PIN, RF24_CS_PIN);
MyRFDriverNRF24::MyRFDriverNRF24(uint8_t ce, uint8_t cs, uint8_t paLevel)
:
MyRFDriver(),
rf24(ce, cs),
_paLevel(paLevel)
{
}
void MyRFDriverNRF24::init() {
// Start up the radio library
rf24->begin();
rf24.begin();
if (!rf24->isPVariant()) {
if (!rf24.isPVariant()) {
debug(PSTR("check wires\n"));
while(1);
}
rf24->setAutoAck(1);
rf24->setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
rf24->enableAckPayload();
rf24->setChannel(RF24_CHANNEL);
rf24->setPALevel(RF24_PA_LEVEL);
rf24->setDataRate(RF24_DATARATE);
rf24->setRetries(5,15);
rf24->setCRCLength(RF24_CRC_16);
rf24->enableDynamicPayloads();
rf24.setAutoAck(1);
rf24.setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
rf24.enableAckPayload();
rf24.setChannel(RF24_CHANNEL);
rf24.setPALevel(_paLevel);
rf24.setDataRate(RF24_DATARATE);
rf24.setRetries(5,15);
rf24.setCRCLength(RF24_CRC_16);
rf24.enableDynamicPayloads();
// All nodes listen to broadcast pipe (for FIND_PARENT_RESPONSE messages)
rf24->openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
rf24.openReadingPipe(BROADCAST_PIPE, TO_ADDR(BROADCAST_ADDRESS));
}
void MyRFDriverNRF24::setAddress(uint8_t address) {
_address = address;
rf24->openReadingPipe(WRITE_PIPE, TO_ADDR(address));
rf24->openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(address));
rf24->startListening();
rf24.openReadingPipe(WRITE_PIPE, TO_ADDR(address));
rf24.openReadingPipe(CURRENT_NODE_PIPE, TO_ADDR(address));
rf24.startListening();
}
uint8_t MyRFDriverNRF24::getAddress() {
@@ -40,30 +44,30 @@ uint8_t MyRFDriverNRF24::getAddress() {
bool MyRFDriverNRF24::send(uint8_t to, const void* data, uint8_t len) {
// Make sure radio has powered up
rf24->powerUp();
rf24->stopListening();
rf24->openWritingPipe(TO_ADDR(to));
bool ok = rf24->write(data, len, to == BROADCAST_ADDRESS);
rf24->startListening();
rf24.powerUp();
rf24.stopListening();
rf24.openWritingPipe(TO_ADDR(to));
bool ok = rf24.write(data, len, to == BROADCAST_ADDRESS);
rf24.startListening();
return ok;
}
bool MyRFDriverNRF24::available(uint8_t *to) {
uint8_t pipe = 255;
boolean avail = rf24->available(&pipe);
boolean avail = rf24.available(&pipe);
if (pipe == CURRENT_NODE_PIPE)
*to = _address;
else if (pipe == BROADCAST_PIPE)
*to = BROADCAST_ADDRESS;
return (rf24->available() && pipe < 6);
return (rf24.available() && pipe < 6);
}
uint8_t MyRFDriverNRF24::receive(void* data) {
uint8_t len = rf24->getDynamicPayloadSize();
rf24->read(data, len);
uint8_t len = rf24.getDynamicPayloadSize();
rf24.read(data, len);
return len;
}
void MyRFDriverNRF24::powerDown() {
rf24->powerDown();
rf24.powerDown();
}
+3 -22
View File
@@ -7,26 +7,6 @@
#include "utility/RF24.h"
#include "utility/RF24_config.h"
#ifdef MYSENSORS_SENSOR
#define RF24_CE_PIN 9
#define RF24_CS_PIN 10
#define RF24_PA_LEVEL RF24_PA_MAX
#endif
#ifdef MYSENSORS_SERIAL_GATEWAY
#define RF24_CE_PIN 9
#define RF24_CS_PIN 10
#define RF24_PA_LEVEL RF24_PA_LOW
#endif
#if defined(MYSENSORS_ETHERNET_GATEWAY) || defined(MYSENSORS_MQTT_GATEWAY)
#define RF24_CE_PIN 5
#define RF24_CS_PIN 6
#define RF24_PA_LEVEL RF24_PA_LOW
#endif
#define RF24_CHANNEL 76 //RF channel for the sensor net, 0-127
#define RF24_DATARATE RF24_250KBPS //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
#define RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL) // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
@@ -40,7 +20,7 @@
class MyRFDriverNRF24 : public MyRFDriver
{
public:
MyRFDriverNRF24();
MyRFDriverNRF24(uint8_t ce=RF24_CE_PIN, uint8_t cs=RF24_CS_PIN, uint8_t paLevel=RF24_PA_LEVEL);
void init();
void setAddress(uint8_t address);
uint8_t getAddress();
@@ -49,8 +29,9 @@ public:
uint8_t receive(void* data);
void powerDown();
private:
RF24 *rf24;
RF24 rf24;
uint8_t _address;
uint8_t _paLevel;
};
#endif
+5 -1
View File
@@ -37,7 +37,11 @@ static inline bool isValidDistance( const uint8_t distance ) {
return distance != DISTANCE_INVALID;
}
MySensor::MySensor() {
MySensor::MySensor(MyRFDriver &_radio, MySigningDriver &_signer)
:
radio(_radio),
signer(_signer)
{
}
+3 -4
View File
@@ -79,7 +79,7 @@ class MySensor
* Creates a new instance of Sensor class.
*
*/
MySensor();
MySensor(MyRFDriver &radio, MySigningDriver &signer);
/**
* Begin operation of the MySensors library
@@ -249,9 +249,8 @@ class MySensor
MyMessage tmpMsg ; // Buffer for temporary messages (acks and nonces among others).
MyMessage msgSign; // Buffer for message to sign.
MyRFDriverClass radio;
MySigningDriverClass signer;
MyRFDriver& radio;
MySigningDriver& signer;
void setupRepeaterMode();
boolean sendWrite(uint8_t dest, MyMessage &message);
@@ -7,7 +7,6 @@
#include "MySigningDriver.h"
#include "MySigningDriverAtsha204.h"
#ifdef MYSENSORS_SIGNING_ATSHA204
// Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected)
//#define DEBUG_ATSHA_SIGNING
@@ -36,11 +35,13 @@ static void DEBUG_ATSHA_PRINTBUF(char* str, uint8_t* buf, uint8_t sz)
#define DEBUG_ATSHA_PRINTBUF(str, buf, sz)
#endif
static atsha204Class atsha204(ATSHA204_PIN);
MySigningDriverAtsha204::MySigningDriverAtsha204() : MySigningDriver() {
verification_ongoing = false;
MySigningDriverAtsha204::MySigningDriverAtsha204()
:
MySigningDriver(),
atsha204(MY_ATSHA204_PIN),
verification_ongoing(false)
{
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(current_nonce, 0xAA, sizeof(current_nonce));
}
@@ -73,13 +74,13 @@ bool MySigningDriverAtsha204::getNonce(MyMessage &msg) {
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
// Note that if message is "too" quick, and arrives before turnover, it will be rejected
// but this is consider such a rare case that it is accepted and rejects are 'safe'
if (timestamp + VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0;
if (timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0;
return true;
}
bool MySigningDriverAtsha204::checkTimer() {
if (verification_ongoing) {
if (millis() < timestamp || millis() > timestamp + VERIFICATION_TIMEOUT_MS) {
if (millis() < timestamp || millis() > timestamp + MY_VERIFICATION_TIMEOUT_MS) {
DEBUG_ATSHA_PRINTLN("Verification timeout");
// Purge nonce
memset(current_nonce, 0xAA, NONCE_NUMIN_SIZE_PASSTHROUGH);
@@ -214,4 +215,3 @@ bool MySigningDriverAtsha204::calculateSignature(MyMessage &msg) {
DEBUG_ATSHA_PRINTBUF("HMAC:", &rx_buffer[SHA204_BUFFER_POS_DATA], 32);
return true; // We return with the signature in rx_buffer[SHA204_BUFFER_POS_DATA]
}
#endif
@@ -12,6 +12,8 @@
#include "utility/ATSHA204.h"
#include <stdint.h>
#define SIGNING_IDENTIFIER (1)
// The ATSHA204 is capable of generating proper random numbers for nonce
// and can calculate HMAC-SHA256 signatures. This is enterprise-
// level of security and ought to implement the signing needs for anybody.
@@ -25,6 +27,7 @@ public:
bool signMsg(MyMessage &msg);
bool verifyMsg(MyMessage &msg);
private:
atsha204Class atsha204;
unsigned long timestamp;
bool verification_ongoing;
uint8_t current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH];
@@ -7,11 +7,11 @@
Created by Patrick "Anticimex" Fallberg <patrick@fallberg.net>
*/
#include "MyConfig.h"
#include "MySigningDriver.h"
#include "MySigningDriverAtsha204Soft.h"
#include "sha256.h"
#include "utility/sha256.h"
#ifdef MYSENSORS_SIGNING_ATSHA204SOFT
// Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected)
//#define DEBUG_ATSHASOFT_SIGNING
@@ -42,16 +42,15 @@ static void DEBUG_ATSHASOFT_PRINTBUF(char* str, uint8_t* buf, uint8_t sz)
static Sha256Class Sha256;
MySigningDriverAtsha204Soft::MySigningDriverAtsha204Soft() : MySigningDriver() {
MySigningDriverAtsha204Soft::MySigningDriverAtsha204Soft() : MySigningDriver(), hmacKey({MY_HMAC_KEY}) {
verification_ongoing = false;
// We set the part of the 32-byte nonce that does not fit into a message to 0xAA
memset(current_nonce, 0xAA, sizeof(current_nonce));
}
bool MySigningDriverAtsha204Soft::getNonce(MyMessage &msg) {
// Set randomseed
randomSeed(analogRead(RANDOMSEED_PIN));
randomSeed(analogRead(MY_RANDOMSEED_PIN));
for (int i = 0; i < MAX_PAYLOAD; i++)
{
current_nonce[i] = random(255);
@@ -65,13 +64,13 @@ bool MySigningDriverAtsha204Soft::getNonce(MyMessage &msg) {
// Be a little fancy to handle turnover (prolong the time allowed to timeout after turnover)
// Note that if message is "too" quick, and arrives before turnover, it will be rejected
// but this is consider such a rare case that it is accepted and rejects are 'safe'
if (timestamp + VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0;
if (timestamp + MY_VERIFICATION_TIMEOUT_MS < millis()) timestamp = 0;
return true;
}
bool MySigningDriverAtsha204Soft::checkTimer() {
if (verification_ongoing) {
if (millis() < timestamp || millis() > timestamp + VERIFICATION_TIMEOUT_MS) {
if (millis() < timestamp || millis() > timestamp + MY_VERIFICATION_TIMEOUT_MS) {
DEBUG_ATSHASOFT_PRINTLN("Verification timeout");
// Purge nonce
memset(current_nonce, 0xAA, 32);
@@ -222,4 +221,3 @@ bool MySigningDriverAtsha204Soft::calculateSignature(MyMessage &msg) {
DEBUG_ATSHASOFT_PRINTBUF("HMAC:", hmac, 32);
return true;
}
#endif
@@ -15,6 +15,8 @@
#include "utility/ATSHA204.h"
#include <stdint.h>
#define SIGNING_IDENTIFIER (1)
// This implementation is the pure software variant of the ATSHA204.
// It is designed to work fully compliant with nodes using ATSHA204 in the network
// and therefore uses the same signing identifier as ATSHA204.
@@ -36,6 +38,7 @@ private:
bool verification_ongoing;
uint8_t current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH];
uint8_t temp_message[32];
uint8_t hmacKey[32];
uint8_t* hmac;
bool calculateSignature(MyMessage &msg);
};
@@ -6,7 +6,6 @@
#include "MySigningDriver.h"
#include "MySigningDriverNone.h"
#ifdef MYSENSORS_SIGNING_NONE
// Uncomment this to get some useful serial debug info (Serial.print and Serial.println expected)
//#define DEBUG_NONE_SIGNING
@@ -67,4 +66,3 @@ bool MySigningDriverNone::verifyMsg(MyMessage &msg) {
else
return true;
}
#endif
@@ -10,6 +10,8 @@
#include "MySigningDriver.h"
#include <stdint.h>
#define SIGNING_IDENTIFIER (0)
// The "none" signing driver that can be used for nodes
// not requiring signing
// It does check SIGNING_IDENTIFIER byte to avoid illegal mixing of signing back-ends in
@@ -1,6 +1,8 @@
// Example sketch showing how to control physical relays.
// This example will remember relay state even after power failure.
#include <MySigningDriverNone.h>
#include <MyRFDriverNRF24.h>
#include <MySensor.h>
#include <SPI.h>
@@ -9,7 +11,9 @@
#define RELAY_ON 1 // GPIO value to write to turn on attached relay
#define RELAY_OFF 0 // GPIO value to write to turn off attached relay
MySensor gw;
MyRFDriverNRF24 radio; // NRFRF24L01 radio driver
MySigningDriverNone signer; // Message signing disabled
MySensor gw(radio, signer);
void setup()
{