From c52d2cd64345bc03b59977bc66c8f2ce97c7b06e Mon Sep 17 00:00:00 2001 From: Patrick Fallberg Date: Fri, 8 Jan 2016 14:28:31 +0100 Subject: [PATCH] All software security related data moved to EEPROM The Sha204Personalizer has been converted to a SecurityPersonalizer. It takes care of generation and storage of keys and data to both ATSHA204A and nonvolatile storage (EEPROM). Library has been updated to read any software security related data from the corresponding EEPROM locations. The effect this has is that any node using any security feature has to execute the personalizer at least once to store appropriate values. The benefit of this is that the software no longer contain sensitive data such as HMAC or AES keys. Whitelists still are stored in software as they are variable in size. --- libraries/MySensors/MyConfig.h | 31 +- libraries/MySensors/core/MyEepromAddresses.h | 43 ++ libraries/MySensors/core/MyHwESP8266.cpp | 2 +- .../MySensors/core/MyPrivateConfig.h.sample | 10 - libraries/MySensors/core/MySensorCore.h | 19 +- libraries/MySensors/core/MySigning.cpp | 8 +- libraries/MySensors/core/MySigning.h | 62 +-- .../MySensors/core/MySigningAtsha204.cpp | 3 + .../MySensors/core/MySigningAtsha204Soft.cpp | 12 +- libraries/MySensors/core/MyTransportNRF24.cpp | 4 +- libraries/MySensors/core/MyTransportRFM69.cpp | 5 +- libraries/MySensors/drivers/AES/AES.h | 10 +- .../SecureActuator/SecureActuator.ino | 6 - .../SecurityPersonalizer.ino} | 377 ++++++++++++++++-- libraries/MySensors/keywords.txt | 5 +- 15 files changed, 454 insertions(+), 143 deletions(-) create mode 100644 libraries/MySensors/core/MyEepromAddresses.h rename libraries/MySensors/examples/{Sha204Personalizer/Sha204Personalizer.ino => SecurityPersonalizer/SecurityPersonalizer.ino} (73%) diff --git a/libraries/MySensors/MyConfig.h b/libraries/MySensors/MyConfig.h index 19648a3..bbbabdb 100644 --- a/libraries/MySensors/MyConfig.h +++ b/libraries/MySensors/MyConfig.h @@ -289,25 +289,6 @@ #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 #endif -/** - * @def MY_SIGNING_SOFT_SERIAL - * @brief Serial number for SW signing enabled node - * - * Set the soft_serial value to an arbitrary value for proper security. - * It should be random and unique for each node. - */ -#ifndef MY_SIGNING_SOFT_SERIAL -#define MY_SIGNING_SOFT_SERIAL 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09 -#endif - -/** - * @def MY_SIGNING_SOFT_HMAC_KEY - * @brief Key to use for HMAC calculation in MySigningAtsha204Soft (32 bytes) - */ -#ifndef MY_SIGNING_SOFT_HMAC_KEY -#define MY_SIGNING_SOFT_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 -#endif - /********************************** * RS485 Driver Defaults ***********************************/ @@ -324,14 +305,9 @@ * NRF24L01 Driver Defaults ***********************************/ -// Enables RF24 encryption (all nodes and gateway must have this enabled) +// Enables RF24 encryption (all nodes and gateway must have this enabled, and all must be personalized with the same AES key) //#define MY_RF24_ENABLE_ENCRYPTION -// Default encryption key. Override in sketch if needed. -#ifndef MY_RF24_ENCRYPTKEY -#define MY_RF24_ENCRYPTKEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16 -#endif - // Default pin settings. Override in sketch if needed. #ifndef MY_RF24_CE_PIN #if defined(ARDUINO_ARCH_ESP8266) @@ -418,11 +394,8 @@ #endif #endif -// Enable this for encryption of packets +// Enables RFM69 encryption (all nodes and gateway must have this enabled, and all must be personalized with the same AES key) //#define MY_RFM69_ENABLE_ENCRYPTION -#ifndef MY_RFM69_ENCRYPTKEY -#define MY_RFM69_ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! -#endif /************************************** * Ethernet Gateway Transport Defaults diff --git a/libraries/MySensors/core/MyEepromAddresses.h b/libraries/MySensors/core/MyEepromAddresses.h new file mode 100644 index 0000000..510126f --- /dev/null +++ b/libraries/MySensors/core/MyEepromAddresses.h @@ -0,0 +1,43 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2015 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#ifndef MyEepromAddresses_h +#define MyEepromAddresses_h +// EEPROM start address for mysensors library data +#define EEPROM_START 0 +// EEPROM location of node id +#define EEPROM_NODE_ID_ADDRESS EEPROM_START +// EEPROM location of parent id +#define EEPROM_PARENT_NODE_ID_ADDRESS (EEPROM_START+1) +// EEPROM location of distance to gateway +#define EEPROM_DISTANCE_ADDRESS (EEPROM_PARENT_NODE_ID_ADDRESS+1) +#define EEPROM_ROUTES_ADDRESS (EEPROM_DISTANCE_ADDRESS+1) // Where to start storing routing information in EEPROM. Will allocate 256 bytes. +#define EEPROM_CONTROLLER_CONFIG_ADDRESS (EEPROM_ROUTES_ADDRESS+256) // Location of controller sent configuration (we allow one payload of config data from controller) +#define EEPROM_FIRMWARE_TYPE_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS+24) +#define EEPROM_FIRMWARE_VERSION_ADDRESS (EEPROM_FIRMWARE_TYPE_ADDRESS+2) +#define EEPROM_FIRMWARE_BLOCKS_ADDRESS (EEPROM_FIRMWARE_VERSION_ADDRESS+2) +#define EEPROM_FIRMWARE_CRC_ADDRESS (EEPROM_FIRMWARE_BLOCKS_ADDRESS+2) +#define EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS (EEPROM_FIRMWARE_CRC_ADDRESS+2) +#define EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS (EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS+32) +#define EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS (EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS+32) // This is set with SecurityPersonalizer.ino +#define EEPROM_SIGNING_SOFT_SERIAL_ADDRESS (EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS+32) // This is set with SecurityPersonalizer.ino +#define EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS (EEPROM_SIGNING_SOFT_SERIAL_ADDRESS+9) // This is set with SecurityPersonalizer.ino +#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS+16) // First free address for sketch static configuration + +#endif diff --git a/libraries/MySensors/core/MyHwESP8266.cpp b/libraries/MySensors/core/MyHwESP8266.cpp index 946210a..cec567f 100644 --- a/libraries/MySensors/core/MyHwESP8266.cpp +++ b/libraries/MySensors/core/MyHwESP8266.cpp @@ -18,7 +18,7 @@ */ #include "MyHwESP8266.h" - +#include /* int8_t pinIntTrigger = 0; diff --git a/libraries/MySensors/core/MyPrivateConfig.h.sample b/libraries/MySensors/core/MyPrivateConfig.h.sample index 3ac1175..099fd36 100644 --- a/libraries/MySensors/core/MyPrivateConfig.h.sample +++ b/libraries/MySensors/core/MyPrivateConfig.h.sample @@ -40,12 +40,6 @@ // Pin used for random generation in soft signing (do not connect anything to this when enabled) #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 // A7 - -// Set the soft_serial value to an arbitrary value for proper security -#define MY_SIGNING_SOFT_SERIAL 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09 - -// Key to use for HMAC calculation in MySigningAtsha204Soft (32 bytes) -#define MY_SIGNING_SOFT_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 - // Enable node whitelisting //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}} @@ -55,9 +49,6 @@ // Enables RF24 encryption (all nodes and gateway must have this enabled) //#define MY_RF24_ENABLE_ENCRYPTION -// Default encryption key -#define MY_RF24_ENCRYPTKEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16 - /********************************** * RFM69 Driver Defaults ***********************************/ @@ -66,6 +57,5 @@ // Enable this for encryption of packets //#define MY_RFM69_ENABLE_ENCRYPTION -#define MY_RFM69_ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes! #endif diff --git a/libraries/MySensors/core/MySensorCore.h b/libraries/MySensors/core/MySensorCore.h index 6400373..1991673 100644 --- a/libraries/MySensors/core/MySensorCore.h +++ b/libraries/MySensors/core/MySensorCore.h @@ -23,6 +23,7 @@ #include "Version.h" // Auto generated by bot #include "MyConfig.h" +#include "MyEepromAddresses.h" #include "MyMessage.h" #ifdef MY_OTA_FIRMWARE_FEATURE #include "drivers/SPIFlash/SPIFlash.h" @@ -37,24 +38,6 @@ #define debug(x,...) #endif -// EEPROM start address for mysensors library data -#define EEPROM_START 0 -// EEPROM location of node id -#define EEPROM_NODE_ID_ADDRESS EEPROM_START -// EEPROM location of parent id -#define EEPROM_PARENT_NODE_ID_ADDRESS (EEPROM_START+1) -// EEPROM location of distance to gateway -#define EEPROM_DISTANCE_ADDRESS (EEPROM_PARENT_NODE_ID_ADDRESS+1) -#define EEPROM_ROUTES_ADDRESS (EEPROM_DISTANCE_ADDRESS+1) // Where to start storing routing information in EEPROM. Will allocate 256 bytes. -#define EEPROM_CONTROLLER_CONFIG_ADDRESS (EEPROM_ROUTES_ADDRESS+256) // Location of controller sent configuration (we allow one payload of config data from controller) -#define EEPROM_FIRMWARE_TYPE_ADDRESS (EEPROM_CONTROLLER_CONFIG_ADDRESS+24) -#define EEPROM_FIRMWARE_VERSION_ADDRESS (EEPROM_FIRMWARE_TYPE_ADDRESS+2) -#define EEPROM_FIRMWARE_BLOCKS_ADDRESS (EEPROM_FIRMWARE_VERSION_ADDRESS+2) -#define EEPROM_FIRMWARE_CRC_ADDRESS (EEPROM_FIRMWARE_BLOCKS_ADDRESS+2) -#define EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS (EEPROM_FIRMWARE_CRC_ADDRESS+2) -#define EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS (EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS+32) -#define EEPROM_LOCAL_CONFIG_ADDRESS (EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS+32) // First free address for sketch static configuration - // This is the nodeId for sensor net gateway receiver sketch (where all sensors should send their data). #define GATEWAY_ADDRESS ((uint8_t)0) // Node child is always created/presented when a node is started diff --git a/libraries/MySensors/core/MySigning.cpp b/libraries/MySensors/core/MySigning.cpp index 1202474..689b374 100644 --- a/libraries/MySensors/core/MySigning.cpp +++ b/libraries/MySensors/core/MySigning.cpp @@ -57,6 +57,7 @@ enum { SIGN_WAITING_FOR_NONCE = 0, SIGN_OK = 1 }; * This function is typically called as action when receiving a I_NONCE_REQUEST message. */ #if defined(MY_SIGNING_SOFT) +extern void signerAtsha204SoftInit(void); extern bool signerAtsha204SoftCheckTimer(void); extern bool signerAtsha204SoftGetNonce(MyMessage &msg); extern void signerAtsha204SoftPutNonce(MyMessage &msg); @@ -64,6 +65,7 @@ extern bool signerAtsha204SoftVerifyMsg(MyMessage &msg); extern bool signerAtsha204SoftSignMsg(MyMessage &msg); #endif #if defined(MY_SIGNING_ATSHA204) +extern void signerAtsha204Init(void); extern bool signerAtsha204CheckTimer(void); extern bool signerAtsha204GetNonce(MyMessage &msg); extern void signerAtsha204PutNonce(MyMessage &msg); @@ -114,8 +116,10 @@ void signerInit(void) { sizeof(_doWhitelist)); #if defined(MY_SIGNING_SOFT) - // initialize pseudo-RNG - randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN)); + signerAtsha204SoftInit(); +#endif +#if defined(MY_SIGNING_ATSHA204) + signerAtsha204Init(); #endif #endif } diff --git a/libraries/MySensors/core/MySigning.h b/libraries/MySensors/core/MySigning.h index 10de162..68d76a8 100644 --- a/libraries/MySensors/core/MySigning.h +++ b/libraries/MySensors/core/MySigning.h @@ -178,14 +178,10 @@ * signatures. The setting is defined using @ref MY_SIGNING_SOFT_RANDOMSEED_PIN and the default is to use pin A7. The same configuration * possibilities exist as with the other configuration options. * - * Thirdly, if you use the software backend, you need to create/set a HMAC key to use. This key is 32 bytes wide and should - * be an arbitrarily chosen value. A string is OK, but as this key never needs to be “parsed” a completely random number is recommended. The - * key is stored in software and can be set "globally" in @ref MyConfig.h or locally in your sketch. The define is @ref MY_SIGNING_SOFT_HMAC_KEY. + * Thirdly, if you use the software backend, you need to personalize the node (see @ref perzonalization). * @code{.cpp} * #define MY_SIGNING_SOFT - * #define MY_SIGNING_SOFT_SERIAL 0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78 * #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 - * #define MY_SIGNING_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x11,0x22 * #define MY_SIGNING_REQUEST_SIGNATURES * #include * ... @@ -195,7 +191,8 @@ * * @anchor perzonalization If you use the “real” ATSHA204A, before any signing operations can be done, the device needs to be personalized. * This can be a daunting process as it involves irreversibly writing configurations to the device, which cannot be undone. I have however tried - * to simplify the process as much as possibly by creating a helper-sketch specifically for this purpose in @ref Sha204Personalizer.ino + * to simplify the process as much as possibly by creating a helper-sketch specifically for this purpose in @ref SecurityPersonalizer.ino + * Note that you also need to do personalization for software signing, but then the values are stored in EEPROM (described below). * * The process of personalizing the ATSHA204A involves * - Writing and locking chip configuration @@ -211,15 +208,15 @@ * if this is desired.
* Now it is possible to execute the sketch to lock the configuration and enable the RNG.
* Next step is to decide if a new key should be generated or an existing key should be stored to the device. This is determined using - * @ref USER_KEY_DATA, which, if defined, will use the data in the variable user_key_data.
- * If @ref USER_KEY_DATA is disabled, the RNG will be used to generate a key. This key obviously need to be made available to you so you can use + * @ref USER_KEY, which, if defined, will use the data in the variable user_key_data.
+ * If @ref USER_KEY is disabled, the RNG will be used to generate a key. This key obviously need to be made available to you so you can use * it in other devices in the network, and this key is therefore also printed on the serial console when it has been generated.
* The key (generated or provided) will be written to the device unless @ref SKIP_KEY_STORAGE is set. As long as the data zone is kept unlocked * the key can be replaced at any time. However, Atmel suggests the data region to be locked for maximum security. On the other hand, they also * claim that the key is not readable from the device even if the data zone remains unlocked so the need for locking the data region is optional * for MySensors usage.
* For devices that does not have serial debug possibilities, it is possible to set @ref SKIP_UART_CONFIRMATION, but it is required to set - * @ref USER_KEY_DATA if this option is enabled since a generated and potentially unknown key could be written to the device and thus rendering + * @ref USER_KEY if this option is enabled since a generated and potentially unknown key could be written to the device and thus rendering * it useless (if the data zone is also locked).
* For devices with serial debug possibilities it is recommended to not use @ref SKIP_UART_CONFIRMATION as the sketch without that setting will * ask user to send a ‘space’ character on the serial terminal before any locking operations are executed as an additional confirmation that @@ -232,7 +229,7 @@ * -# Disable @ref LOCK_DATA * -# Enable @ref SKIP_KEY_STORAGE * -# Disable @ref SKIP_UART_CONFIRMATION - * -# Disable @ref USER_KEY_DATA + * -# Disable @ref USER_KEY * - Execute the sketch on the “master” device to obtain a randomized key. Save this key to a secure location and keep it confidential so that\n you can retrieve it if you need to personalize more devices later on. * - Now reconfigure the sketch with these settings: @@ -241,10 +238,29 @@ * according to Atmel, but they also claim that key is not readable even if data region remains unlocked from the slot we are using) * -# Disable @ref SKIP_KEY_STORAGE * -# Enable @ref SKIP_UART_CONFIRMATION - * -# Enable @ref USER_KEY_DATA + * -# Enable @ref USER_KEY * - Put the saved key in the user_key_data variable. * - Now execute the sketch on all devices you want to personalize with this secret key. * + * For software signing the personalization procedure looks slightly different.
+ * - If you do not have the ATSHA204A device and need to generate random keys: + * -# Enable @ref USE_SOFT_SIGNING + * - If you do have the ATSHA204A and want to use it to generate random keys for soft signing: + * -# Disable @ref USE_SOFT_SIGNING + * - If you want to review existing EEPROM configuration to determine if anything needs to be updated: + * -# Make sure to disable any ATSHA204A update features if you use it (enable @ref SKIP_KEY_STORAGE, disable @ref LOCK_CONFIGURATION and @ref LOCK_DATA) + * -# Disable @ref STORE_SOFT_KEY + * -# Disable @ref STORE_SOFT_SERIAL + * -# Disable @ref STORE_AES_KEY + * - Execute the sketch and the EEPROM configuration will be printed on the serial console. + * - Decide what you want to update and enable the corresponding flags (@ref STORE_SOFT_KEY, @ref STORE_SOFT_SERIAL, @ref STORE_AES_KEY). + * - If you have existing keys and want to use them instead of having the values randomized: + * - Enable the corresponding flag (@ref USER_SOFT_KEY, @ref USER_SOFT_SERIAL, @ref USER_AES_KEY) and also set the appropriate values + * (@ref user_soft_key_data, @ref user_soft_serial, @ref user_aes_key) + * + * The personalizer also takes care of generation and storage of the AES key used for RF traffic encryption. + * See the software signing personalization flow for how to manage it. + * * That’s it. Personalization is done and the device is ready to execute signing operations which are valid only on your personal network. * * If a node does require signing, any unsigned message sent to the node will be rejected.
@@ -288,9 +304,8 @@ * remove it from the nodes whitelist, and it will no longer be able to communicate signed messages to the door node. * * In case you want to be able to "whitelist" trusted nodes (in order to be able to revoke them in case they are lost) you also need to take note - * of the serial number of the ATSHA device. This is unique for each device. The serial number is printed in a copy+paste friendly format by the - * personalizer for this purpose. For the software backend, it is defined by @ref MY_SIGNING_SOFT_SERIAL. You should keep this value unique for each - * node in the network.
+ * of the serial number of the ATSHA device or the software value stored in EEPROM. This is unique for each device. The serial number is printed + * in a copy+paste friendly format by the personalizer for this purpose.
* The whitelist is stored on the node that require signatures. When a received message is verified, the serial of the sender is looked up in a * list stored on the receiving node, and the corresponding serial stored in the list for that sender is then included in the signature verification * process. The list is stored as the value of the flag that enables whitelisting, @ref MY_SIGNING_NODE_WHITELISTING.
@@ -315,29 +330,24 @@ * In this example, there are two nodes in the whitelist; the gateway, and a separate node that communicates directly with this node (with signed * messages). You do not need to do anything special for the sending nodes, apart from making sure they support signing. * - * The "soft" backend of course also support whitelisting. However, since it does not contain a unique identifier, you have to provide an additional - * setting (@ref MY_SIGNING_SOFT_SERIAL) for all nodes that communicate to a node which has whitelisting enabled. Example: + * The "soft" backend of course also support whitelisting. Example: * @code{.cpp} * #define MY_SIGNING_SOFT - * #define MY_SIGNING_SOFT_SERIAL 0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78 * #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 - * #define MY_SIGNING_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x11,0x22 * #define MY_SIGNING_REQUEST_SIGNATURES * #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}},{.nodeId = 2,.serial = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}}} * #include * ... * @endcode * - * For a node that should transmit whitelisted messages but not receive whitelisted messages, you do not need any special configurations except to define - * a unique serial if using the software backend: + * For a node that should transmit whitelisted messages but not receive whitelisted messages, you do not need any special configurations: * @code{.cpp} * #define MY_SIGNING_SOFT - * #define MY_SIGNING_SOFT_SERIAL 0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78 * #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 - * #define MY_SIGNING_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x11,0x22 * @endcode * Remember that you always need to select a signing backend for all nodes that communicate to a node that require whitelisting. * Also, note that a node that use whitelisting will not accept messages from nodes that are not present in it's whitelist. + * And you have to personalize all nodes that use signing with a common HMAC key but different serial numbers (ATSHA204A always has unique serials). * * @section MySigningtechnical The technical stuff * @@ -411,9 +421,7 @@ * Configuration example for a motion sensor:
* @code{.cpp} * #define MY_SIGNING_SOFT - * #define MY_SIGNING_SOFT_SERIAL 0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78 * #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 - * #define MY_SIGNING_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x11,0x22 * #define MY_SIGNING_REQUEST_SIGNATURES * #include * ... @@ -422,9 +430,7 @@ * The gateway needs to configured with a whitelist (and it have to have an entry for all nodes that send and/or require signed messages):
* @code{.cpp} * #define MY_SIGNING_SOFT - * #define MY_SIGNING_SOFT_SERIAL 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 * #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 - * #define MY_SIGNING_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x11,0x22 * #define MY_SIGNING_REQUEST_SIGNATURES * #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = MOTION_SENSOR_ID,.serial = {0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78}}} * #include @@ -446,9 +452,7 @@ * Configuration example for the door controller node (should require signing from anyone who wants to control it):
* @code{.cpp} * #define MY_SIGNING_SOFT - * #define MY_SIGNING_SOFT_SERIAL 0x12,0x34,0x56,0x78,0x90,0x12,0x34,0x56,0x78 * #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 - * #define MY_SIGNING_SOFT_HMAC_KEY 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x11,0x22 * #define MY_SIGNING_REQUEST_SIGNATURES * #define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88}},{.nodeId = KEYFOB_ID,.serial = {}}} * #include @@ -458,7 +462,7 @@ * @subsection MySigningsketches Relevant sketches * * - @ref SecureActuator.ino - * - @ref Sha204Personalizer.ino + * - @ref SecurityPersonalizer.ino */ /** diff --git a/libraries/MySensors/core/MySigningAtsha204.cpp b/libraries/MySensors/core/MySigningAtsha204.cpp index ce78678..61a1293 100644 --- a/libraries/MySensors/core/MySigningAtsha204.cpp +++ b/libraries/MySensors/core/MySigningAtsha204.cpp @@ -86,6 +86,9 @@ static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, #define DEBUG_SIGNING_PRINTBUF(str, buf, sz) #endif +void signerAtsha204Init(void) { +} + bool signerAtsha204CheckTimer(void) { if (_signing_verification_ongoing) { if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) { diff --git a/libraries/MySensors/core/MySigningAtsha204Soft.cpp b/libraries/MySensors/core/MySigningAtsha204Soft.cpp index 2b89fac..037905a 100644 --- a/libraries/MySensors/core/MySigningAtsha204Soft.cpp +++ b/libraries/MySensors/core/MySigningAtsha204Soft.cpp @@ -40,11 +40,11 @@ unsigned long _signing_timestamp; bool _signing_verification_ongoing = false; uint8_t _signing_current_nonce[NONCE_NUMIN_SIZE_PASSTHROUGH]; uint8_t _signing_temp_message[32]; -static uint8_t _signing_hmac_key[32] = { MY_SIGNING_SOFT_HMAC_KEY }; +static uint8_t _signing_hmac_key[32]; uint8_t _signing_hmac[32]; extern uint8_t _doWhitelist[32]; -const uint8_t _signing_node_serial_info[SHA204_SERIAL_SZ] = {MY_SIGNING_SOFT_SERIAL}; +static uint8_t _signing_node_serial_info[9]; #ifdef MY_SIGNING_NODE_WHITELISTING const whitelist_entry_t _signing_whitelist[] = MY_SIGNING_NODE_WHITELISTING; #endif @@ -89,6 +89,14 @@ static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, #define DEBUG_SIGNING_PRINTBUF(str, buf, sz) #endif +void signerAtsha204SoftInit(void) { + // initialize pseudo-RNG + randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN)); + // Set secrets + hwReadConfigBlock((void*)_signing_hmac_key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32); + hwReadConfigBlock((void*)_signing_node_serial_info, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9); +} + bool signerAtsha204SoftCheckTimer(void) { if (_signing_verification_ongoing) { if (millis() < _signing_timestamp || millis() > _signing_timestamp + MY_VERIFICATION_TIMEOUT_MS) { diff --git a/libraries/MySensors/core/MyTransportNRF24.cpp b/libraries/MySensors/core/MyTransportNRF24.cpp index 1a62766..3d2ac1d 100644 --- a/libraries/MySensors/core/MyTransportNRF24.cpp +++ b/libraries/MySensors/core/MyTransportNRF24.cpp @@ -38,7 +38,7 @@ uint8_t _address; #if defined(MY_RF24_ENABLE_ENCRYPTION) AES _aes; uint8_t _dataenc[32] = {0}; - uint8_t _psk[] = { MY_RF24_ENCRYPTKEY }; + uint8_t _psk[16]; #endif bool transportInit() { @@ -65,7 +65,9 @@ bool transportInit() { #if defined(MY_RF24_ENABLE_ENCRYPTION) + hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); _aes.set_key(_psk, 16); //set up AES-key + memset(_psk, 0, 16); // Make sure it is purged from memory when set #endif //_rf24.printDetails(); diff --git a/libraries/MySensors/core/MyTransportRFM69.cpp b/libraries/MySensors/core/MyTransportRFM69.cpp index f6ded5f..35305ce 100644 --- a/libraries/MySensors/core/MyTransportRFM69.cpp +++ b/libraries/MySensors/core/MyTransportRFM69.cpp @@ -30,7 +30,10 @@ bool transportInit() { // Start up the radio library (_address will be set later by the MySensors library) if (_radio.initialize(MY_RFM69_FREQUENCY, _address, MY_RFM69_NETWORKID)) { #ifdef MY_RFM69_ENABLE_ENCRYPTION - _radio.encrypt(RFM69_ENCRYPTKEY); + uint8_t _psk[16]; + hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); + _radio.encrypt(_psk); + memset(_psk, 0, 16); // Make sure it is purged from memory when set #endif return true; } diff --git a/libraries/MySensors/drivers/AES/AES.h b/libraries/MySensors/drivers/AES/AES.h index a37a1e5..1d92c8c 100644 --- a/libraries/MySensors/drivers/AES/AES.h +++ b/libraries/MySensors/drivers/AES/AES.h @@ -35,7 +35,7 @@ /* code was modified by george spanos * 16/12/14 */ - +/** AES class */ class AES { public: @@ -351,7 +351,7 @@ class AES * @defgroup aeslib AES library for Arduino and Raspberry pi * @ingroup internals * - * @section Goals design Goals + * @section AesGoals design Goals * * This library is AESigned to be... * @li Fast and efficient. @@ -393,10 +393,10 @@ class AES * cd examples_Rpi
* sudo ./\

* - * @section News News + * @section AesNews News * * If issues are discovered with the documentation, please report them here - * @section Useful Useful References + * @section AesUseful Useful References * * Please refer to: * @@ -405,7 +405,7 @@ class AES * @li Source Code * @li All spaniakos Documentation Main Page * - * @section Board_Support Board Support + * @section AesBoard_Support Board Support * * Most standard Arduino based boards are supported: * - Arduino diff --git a/libraries/MySensors/examples/SecureActuator/SecureActuator.ino b/libraries/MySensors/examples/SecureActuator/SecureActuator.ino index 3e6c6bb..308b8e9 100644 --- a/libraries/MySensors/examples/SecureActuator/SecureActuator.ino +++ b/libraries/MySensors/examples/SecureActuator/SecureActuator.ino @@ -37,7 +37,6 @@ * is defined by @ref LOCK_1. The number of locks is controlled by @ref NOF_LOCKS .
* The sketch will require incoming messages to be signed and the use of signing backend is selected * by @ref MY_SIGNING_ATSHA204 or @ref MY_SIGNING_SOFT. Hard or soft ATSHA204 signing is supported.
- * If soft signing is chosen, make sure to use a correct HMAC key (see @ref MY_SIGNING_SOFT_HMAC_KEY).
* Whitelisting can be enabled through @ref MY_SIGNING_NODE_WHITELISTING in which case a single entry * is provided in this example which typically should map to the gateway of the network. */ @@ -60,11 +59,6 @@ // SETTINGS FOR MY_SIGNING_SOFT -/// Set the soft_serial value to an arbitrary value for proper security (9 bytes) -#define MY_SIGNING_SOFT_SERIAL 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09 -/// Key to use for HMAC calculation in soft signing (32 bytes) -#define MY_SIGNING_SOFT_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 - #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 //!< Unconnected analog pin for random seed // SETTINGS FOR MY_SIGNING_ATSHA204 diff --git a/libraries/MySensors/examples/Sha204Personalizer/Sha204Personalizer.ino b/libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino similarity index 73% rename from libraries/MySensors/examples/Sha204Personalizer/Sha204Personalizer.ino rename to libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino index 0634283..43e25be 100644 --- a/libraries/MySensors/examples/Sha204Personalizer/Sha204Personalizer.ino +++ b/libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino @@ -21,16 +21,20 @@ /** * @ingroup MySigninggrp * @{ - * @file Sha204Personalizer.ino - * @brief SHA204 personalization sketch + * @file SecurityPersonalizer.ino + * @brief Security personalization sketch * * REVISION HISTORY - * - See git log (git log libraries/MySensors/examples/Sha204Personalizer/Sha204Personalizer.ino) + * - See git log (git log libraries/MySensors/examples/SecurityPersonalizer/SecurityPersonalizer.ino) */ /** - * @example Sha204Personalizer.ino - * This sketch will write factory default settings to the configuration zone + * @example SecurityPersonalizer.ino + * This sketch will personalize either none-volatile memory or ATSHA204A for security functions + * available in the MySensors library. + * + * For ATSHA204A: + * It will write factory default settings to the configuration zone * and then lock it.
* It will then either
* -# Generate a random value to use as a key which will be stored in @@ -45,13 +49,41 @@ * turn on the locking. Furthermore, user have to send a SPACE character on serial * console when prompted to do any locking. On boards that does not provide UART * input it is possible to configure the sketch to skip this confirmation. - * Default settings use ATSHA204 on @ref ATSHA204_PIN. + * Default settings use ATSHA204A on @ref MY_SIGNING_ATSHA204_PIN. + * + * For Soft signing: + * It will
+ * -# Generate a random value to use as a key which will be stored in EEPROM. + * The key is printed on UART (115200) in clear text for the user to be ablle to + * use it as a user-supplied key in other personalization executions where the same + * key is needed. + * -# Use a user-supplied value to use as a key which will be stored in EEPROM. + * -# Generate a random value to use as a serial number which will be stored in EEPROM. + * The serial number is printed on UART (115200) in clear text for the user to be ablle to + * use it as a user-supplied serial number in other personalization executions where the + * serial is needed (typically for a whitelist). + * -# Use a user-supplied value to use as a serial which will be stored in EEPROM. + * + * For Encryption support: + * -# Generate a random value to use as a AES key which will be stored in EEPROM. + * The AES key is printed on UART (115200) in clear text for the user to be ablle to + * use it as a user-supplied AES key in other personalization executions where the + * AES key is needed (typically for RF encryption). + * -# Use a user-supplied value to use as a AES key which will be stored in EEPROM. + * + * Personalizing EEPROM or ATSHA204A still require the appropriate configuration of the + * library to actually have an effect. There is no problem personalizing EEPROM and + * ATSHA204A at the same time. There is however a security risk with using the same + * data for EEPROM and ATSHA204A so it is recommended to use different serial and HMAC + * keys on the same device for ATSHA204A vs soft signing settings. * * Details on personalization procedure is given in @ref perzonalization. */ #include #include +#define MY_CORE_ONLY +#include // Doxygen specific constructs, not included when built normally // This is used to enable disabled macros/definitions to be included in the documentation as well. @@ -59,12 +91,17 @@ #define LOCK_CONFIGURATION #define LOCK_DATA #define SKIP_KEY_STORAGE -#define USER_KEY_DATA +#define USER_KEY #define SKIP_UART_CONFIRMATION +#define USE_SOFT_SIGNING +#define STORE_SOFT_KEY +#define USER_SOFT_KEY +#define STORE_SOFT_SERIAL +#define USER_SOFT_SERIAL +#define STORE_AES_KEY +#define USER_AES_KEY #endif -#define ATSHA204_PIN 17 //!< The pin the ATSHA204 is connected on (A3). - /** * @def LOCK_CONFIGURATION * @brief Uncomment this to enable locking the configuration zone. @@ -89,13 +126,13 @@ * @def SKIP_KEY_STORAGE * @brief Uncomment this to skip key storage (typically once key has been written once) */ -//#define SKIP_KEY_STORAGE +#define SKIP_KEY_STORAGE /** - * @def USER_KEY_DATA + * @def USER_KEY * @brief Uncomment this to skip key generation and use @ref user_key_data as key instead. */ -//#define USER_KEY_DATA +//#define USER_KEY /** * @def SKIP_UART_CONFIRMATION @@ -106,19 +143,84 @@ */ //#define SKIP_UART_CONFIRMATION -#if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY_DATA) -#error You have to define USER_KEY_DATA for boards that does not have UART +/** + * @def USE_SOFT_SIGNING + * @brief Uncomment this to store data to EEPROM instead of ATSHA204A + */ +//#define USE_SOFT_SIGNING + +/** + * @def STORE_SOFT_KEY + * @brief Uncomment this to store soft HMAC key to EEPROM + */ +//#define STORE_SOFT_KEY + +/** + * @def USER_SOFT_KEY + * @brief Uncomment this to skip soft HMAC key generation and use @ref user_soft_key_data as HMAC key instead. + */ +//#define USER_SOFT_KEY + +/** + * @def STORE_SOFT_SERIAL + * @brief Uncomment this to store soft serial to EEPROM + */ +//#define STORE_SOFT_SERIAL + +/** + * @def USER_SOFT_SERIAL + * @brief Uncomment this to skip soft serial generation and use @ref user_soft_serial as serial instead. + */ +//#define USER_SOFT_SERIAL + +/** + * @def STORE_AES_KEY + * @brief Uncomment this to store AES key to EEPROM + */ +//#define STORE_AES_KEY + +/** + * @def USER_AES_KEY + * @brief Uncomment this to skip AES key generation and use @ref user_aes_key as key instead. + */ +//#define USER_AES_KEY + +#if defined(SKIP_UART_CONFIRMATION) && !defined(USER_KEY) +#error You have to define USER_KEY for boards that does not have UART #endif -#ifdef USER_KEY_DATA +#ifdef USER_KEY /** @brief The user-defined HMAC key to use for personalization */ #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 /** @brief The data to store in key slot 0 */ const uint8_t user_key_data[32] = {MY_HMAC_KEY}; #endif -const int sha204Pin = ATSHA204_PIN; //!< The IO pin to use for ATSHA204 +#ifdef USER_SOFT_KEY +/** @brief The user-defined soft HMAC key to use for EEPROM personalization */ +#define MY_SOFT_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 +/** @brief The data to store as soft HMAC key in EEPROM */ +const uint8_t user_soft_key_data[32] = {MY_SOFT_HMAC_KEY}; +#endif + +#ifdef USER_SOFT_SERIAL +/** @brief The user-defined soft serial to use for EEPROM personalization */ +#define MY_SOFT_SERIAL 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +/** @brief The data to store as soft serial in EEPROM */ +const uint8_t user_soft_serial[9] = {MY_SOFT_SERIAL}; +#endif + +#ifdef USER_AES_KEY +/** @brief The user-defined AES key to use for EEPROM personalization */ +#define MY_AES_KEY 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +/** @brief The data to store as AES key in EEPROM */ +const uint8_t user_aes_key[16] = {MY_AES_KEY}; +#endif + +#ifndef USE_SOFT_SIGNING +const int sha204Pin = MY_SIGNING_ATSHA204_PIN; //!< The IO pin to use for ATSHA204A atsha204Class sha204(sha204Pin); +#endif /** @brief Print a error notice and halt the execution */ void halt() @@ -127,6 +229,7 @@ void halt() while(1); } +#ifndef USE_SOFT_SIGNING /** * @brief Write default configuration and return CRC of the configuration bits * @returns CRC over the configuration bits @@ -275,14 +378,53 @@ void write_key(uint8_t* key) halt(); } } +#endif // not USE_SOFT_SIGNING /** @brief Dump current configuration to UART */ void dump_configuration() { + uint8_t buffer[32]; +#ifndef USE_SOFT_SIGNING + Serial.println(F("EEPROM DATA:")); +#endif + hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32); + Serial.print(F("SOFT_HMAC_KEY | ")); + for (int j=0; j<32; j++) + { + if (buffer[j] < 0x10) + { + Serial.print('0'); // Because Serial.print does not 0-pad HEX + } + Serial.print(buffer[j], HEX); + } + Serial.println(); + hwReadConfigBlock((void*)buffer, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9); + Serial.print(F("SOFT_SERIAL | ")); + for (int j=0; j<9; j++) + { + if (buffer[j] < 0x10) + { + Serial.print('0'); // Because Serial.print does not 0-pad HEX + } + Serial.print(buffer[j], HEX); + } + Serial.println(); + hwReadConfigBlock((void*)buffer, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); + Serial.print(F("AES_KEY | ")); + for (int j=0; j<16; j++) + { + if (buffer[j] < 0x10) + { + Serial.print('0'); // Because Serial.print does not 0-pad HEX + } + Serial.print(buffer[j], HEX); + } + Serial.println(); +#ifndef USE_SOFT_SIGNING uint8_t tx_buffer[SHA204_CMD_SIZE_MAX]; uint8_t rx_buffer[SHA204_RSP_SIZE_MAX]; uint8_t ret_code; - + Serial.println(F("ATSHA204A DATA:")); for (int i=0; i < 88; i += 4) { ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, i); @@ -712,25 +854,36 @@ void dump_configuration() Serial.println(); } } +#endif // not USE_SOFT_SIGNING } /** @brief Sketch setup code */ void setup() { + // Delay startup a bit for serial consoles to catch up + unsigned long enter = hwMillis(); + while (hwMillis() - enter < (unsigned long)500); +#ifndef USE_SOFT_SIGNING uint8_t tx_buffer[SHA204_CMD_SIZE_MAX]; uint8_t rx_buffer[SHA204_RSP_SIZE_MAX]; - uint8_t key[32]; uint8_t ret_code; uint8_t lockConfig = 0; uint8_t lockValue = 0; uint16_t crc; (void)crc; +#else + // initialize pseudo-RNG + randomSeed(analogRead(MY_SIGNING_SOFT_RANDOMSEED_PIN)); +#endif + uint8_t key[32]; + (void)key; Serial.begin(115200); - Serial.println(F("ATSHA204 personalization sketch for MySensors usage.")); - Serial.println(F("----------------------------------------------------")); + Serial.println(F("Personalization sketch for MySensors usage.")); + Serial.println(F("-------------------------------------------")); +#ifndef USE_SOFT_SIGNING // Wake device before starting operations ret_code = sha204.sha204c_wakeup(rx_buffer); if (ret_code != SHA204_SUCCESS) @@ -738,7 +891,171 @@ void setup() Serial.print(F("Failed to wake device. Response: ")); Serial.println(ret_code, HEX); halt(); } + // Read out lock config bits to determine if locking is possible + ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2); + if (ret_code != SHA204_SUCCESS) + { + Serial.print(F("Failed to determine device lock status. Response: ")); Serial.println(ret_code, HEX); + halt(); + } + else + { + lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3]; + lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2]; + } +#endif +#ifdef STORE_SOFT_KEY +#ifdef USER_SOFT_KEY + memcpy(key, user_soft_key_data, 32); + Serial.println(F("Using this user supplied soft HMAC key:")); +#else + // Retrieve random value to use as soft HMAC key +#ifdef USE_SOFT_SIGNING + for (int i = 0; i < 32; i++) { + key[i] = random(256) ^ micros(); + unsigned long enter = hwMillis(); + while (hwMillis() - enter < (unsigned long)2); + } + Serial.println(F("This value will be stored in EEPROM as soft HMAC key:")); +#else + ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE); + if (ret_code != SHA204_SUCCESS) + { + Serial.print(F("Random key generation failed. Response: ")); Serial.println(ret_code, HEX); + halt(); + } + else + { + memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32); + } + if (lockConfig == 0x00) + { + Serial.println(F("This value will be stored in EEPROM as soft HMAC key:")); + } + else + { + Serial.println(F("Key is not randomized (configuration not locked):")); + } +#endif // not USE_SOFT_SIGNING +#endif // not USER_SOFT_KEY + Serial.print("#define MY_SOFT_HMAC_KEY "); + for (int i=0; i<32; i++) + { + Serial.print("0x"); + if (key[i] < 0x10) + { + Serial.print('0'); // Because Serial.print does not 0-pad HEX + } + Serial.print(key[i], HEX); + if (i < 31) Serial.print(','); + } + Serial.println(); + hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32); +#endif // STORE_SOFT_KEY + +#ifdef STORE_SOFT_SERIAL +#ifdef USER_SOFT_SERIAL + memcpy(key, user_soft_serial, 9); + Serial.println(F("Using this user supplied soft serial:")); +#else + // Retrieve random value to use as serial +#ifdef USE_SOFT_SIGNING + for (int i = 0; i < 9; i++) { + key[i] = random(256) ^ micros(); + unsigned long enter = hwMillis(); + while (hwMillis() - enter < (unsigned long)2); + } + Serial.println(F("This value will be stored in EEPROM as soft serial:")); +#else + ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE); + if (ret_code != SHA204_SUCCESS) + { + Serial.print(F("Random serial generation failed. Response: ")); Serial.println(ret_code, HEX); + halt(); + } + else + { + memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 9); + } + if (lockConfig == 0x00) + { + Serial.println(F("This value will be stored in EEPROM as soft serial:")); + } + else + { + Serial.println(F("Serial is not randomized (configuration not locked):")); + } +#endif // not USE_SOFT_SIGNING +#endif // not USER_SOFT_SERIAL + Serial.print("#define MY_SOFT_SERIAL "); + for (int i=0; i<9; i++) + { + Serial.print("0x"); + if (key[i] < 0x10) + { + Serial.print('0'); // Because Serial.print does not 0-pad HEX + } + Serial.print(key[i], HEX); + if (i < 8) Serial.print(','); + } + Serial.println(); + hwWriteConfigBlock((void*)key, (void*)EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9); +#endif // STORE_SOFT_SERIAL + +#ifdef STORE_AES_KEY +#ifdef USER_AES_KEY + memcpy(key, user_aes_key, 16); + Serial.println(F("Using this user supplied AES key:")); +#else + // Retrieve random value to use as key +#ifdef USE_SOFT_SIGNING + for (int i = 0; i < 16; i++) { + key[i] = random(256) ^ micros(); + unsigned long enter = hwMillis(); + while (hwMillis() - enter < (unsigned long)2); + } + Serial.println(F("This key will be stored in EEPROM as AES key:")); +#else + ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE); + if (ret_code != SHA204_SUCCESS) + { + Serial.print(F("Random key generation failed. Response: ")); Serial.println(ret_code, HEX); + halt(); + } + else + { + memcpy(key, rx_buffer+SHA204_BUFFER_POS_DATA, 32); + } + if (lockConfig == 0x00) + { + Serial.println(F("This key will be stored in EEPROM as AES key:")); + } + else + { + Serial.println(F("Key is not randomized (configuration not locked):")); + } +#endif // not USE_SOFT_SIGNING +#endif // not USER_AES_KEY + Serial.print("#define MY_AES_KEY "); + for (int i=0; i<16; i++) + { + Serial.print("0x"); + if (key[i] < 0x10) + { + Serial.print('0'); // Because Serial.print does not 0-pad HEX + } + Serial.print(key[i], HEX); + if (i < 15) Serial.print(','); + } + Serial.println(); + hwWriteConfigBlock((void*)key, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); +#endif // STORE_AES_KEY + +#ifdef USE_SOFT_SIGNING + Serial.println(F("EEPROM configuration:")); + dump_configuration(); +#else // Output device revision on console ret_code = sha204.sha204m_dev_rev(tx_buffer, rx_buffer); if (ret_code != SHA204_SUCCESS) @@ -794,19 +1111,6 @@ void setup() Serial.println(); } - // Read out lock config bits to determine if locking is possible - ret_code = sha204.sha204m_read(tx_buffer, rx_buffer, SHA204_ZONE_CONFIG, 0x15<<2); - if (ret_code != SHA204_SUCCESS) - { - Serial.print(F("Failed to determine device lock status. Response: ")); Serial.println(ret_code, HEX); - halt(); - } - else - { - lockConfig = rx_buffer[SHA204_BUFFER_POS_DATA+3]; - lockValue = rx_buffer[SHA204_BUFFER_POS_DATA+2]; - } - if (lockConfig != 0x00) { // Write config and get CRC for the updated config @@ -886,9 +1190,9 @@ void setup() #ifdef SKIP_KEY_STORAGE Serial.println(F("Disable SKIP_KEY_STORAGE to store key.")); #else -#ifdef USER_KEY_DATA +#ifdef USER_KEY memcpy(key, user_key_data, 32); - Serial.println(F("Using this user supplied key:")); + Serial.println(F("Using this user supplied HMAC key:")); #else // Retrieve random value to use as key ret_code = sha204.sha204m_random(tx_buffer, rx_buffer, RANDOM_SEED_UPDATE); @@ -1022,9 +1326,11 @@ void setup() { Serial.println(F("Skipping OTP/data zone lock (zone already locked).")); } +#endif // not USE_SOFT_SIGNING Serial.println(F("--------------------------------")); Serial.println(F("Personalization is now complete.")); +#ifndef USE_SOFT_SIGNING Serial.print(F("Configuration is ")); if (lockConfig == 0x00) { @@ -1043,6 +1349,7 @@ void setup() { Serial.println("UNLOCKED"); } +#endif } /** @brief Sketch execution code */ diff --git a/libraries/MySensors/keywords.txt b/libraries/MySensors/keywords.txt index 257dcbf..fc148be 100644 --- a/libraries/MySensors/keywords.txt +++ b/libraries/MySensors/keywords.txt @@ -60,10 +60,7 @@ MY_VERIFICATION_TIMEOUT_MS LITERAL1 MY_SIGNING_NODE_WHITELISTING LITERAL1 MY_SIGNING_ATSHA204_PIN LITERAL1 MY_SIGNING_SOFT_RANDOMSEED_PIN LITERAL1 -MY_SIGNING_SOFT_SERIAL LITERAL1 -MY_SIGNING_SOFT_HMAC_KEY LITERAL1 MY_RF24_ENABLE_ENCRYPTION LITERAL1 -MY_RF24_ENCRYPTKEY LITERAL1 MY_RF24_CE_PIN LITERAL1 MY_RF24_CS_PIN LITERAL1 MY_RF24_PA_LEVEL LITERAL1 @@ -81,7 +78,7 @@ MY_RFM69_NETWORKID LITERAL1 MY_RF69_IRQ_PIN LITERAL1 MY_RF69_SPI_CS LITERAL1 MY_RF69_IRQ_NUM LITERAL1 -MY_RFM69_ENCRYPTKEY LITERAL1 +MY_RFM69_ENABLE_ENCRYPTION LITERAL1 MY_GATEWAY_SERIAL LITERAL1 MY_GATEWAY_W5100 LITERAL1 MY_GATEWAY_ENC28J60 LITERAL1