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