diff --git a/MyConfig.h b/MyConfig.h index 598b686..865f44d 100644 --- a/MyConfig.h +++ b/MyConfig.h @@ -1476,12 +1476,44 @@ * @ingroup MyConfigGrp * @brief These options control security related configurations. * - * Note that some encryption configurations are on a per-radio basis as these are specific to each - * radio. + * Overview over all security related settings and how/where to apply them: + * | Setting | Description | Arduino | Raspberry PI @c configure argument + * |--------------------------|-------------|---------|------------- + * | @ref MY_SECURITY_SIMPLE_PASSWD | Enables security (signing and encryption) without the need for @ref personalization | "#define" in the top of your sketch | Not supported (use the other two "simple" options) + * | @ref MY_SIGNING_SIMPLE_PASSWD | Enables signing without the need for @ref personalization | "#define" in the top of your sketch | @verbatim --my-signing=password --my-security-password= @endverbatim + * | @ref MY_ENCRYPTION_SIMPLE_PASSWD | Enables encryption without the need for @ref personalization | "#define" in the top of your sketch | @verbatim --my-security-password= @endverbatim and encryption enabled on the chosen transport + * | @ref MY_DEBUG_VERBOSE_SIGNING | Enables verbose signing debugging | "#define" in the top of your sketch | @verbatim --my-signing-debug @endverbatim + * | @ref MY_SIGNING_ATSHA204 | Enables support to sign messages backed by ATSHA204A hardware | "#define" in the top of your sketch | Not supported + * | @ref MY_SIGNING_SOFT | Enables support to sign messages backed by software | "#define" in the top of your sketch | @verbatim --my-signing=software @endverbatim + * | @ref MY_SIGNING_REQUEST_SIGNATURES | Enables node/gw to require signed messages | "#define" in the top of your sketch | @verbatim --my-signing-request-signatures @endverbatim + * | @ref MY_SIGNING_WEAK_SECURITY | Weakens signing security, useful for testing before deploying signing "globally" | "#define" in the top of your sketch | @verbatim --my-signing-weak_security @endverbatim + * | @ref MY_VERIFICATION_TIMEOUT_MS | Change default signing timeout | "#define" in the top of your sketch | @verbatim --my-signing-verification-timeout-ms= @endverbatim + * | @ref MY_SIGNING_NODE_WHITELISTING | Defines a whitelist of trusted nodes | "#define" in the top of your sketch | @verbatim --my-signing-whitelist="" @endverbatim + * | @ref MY_SIGNING_ATSHA204_PIN | Change default ATSHA204A communication pin | "#define" in the top of your sketch | Not supported + * | @ref MY_SIGNING_SOFT_RANDOMSEED_PIN | Change default software RNG seed pin | "#define" in the top of your sketch | Not supported + * | @ref MY_RF24_ENABLE_ENCRYPTION | Enables encryption on RF24 radios | "#define" in the top of your sketch | @verbatim --my-rf24-encryption-enabled @endverbatim + * | @ref MY_RFM69_ENABLE_ENCRYPTION | Enables encryption on %RFM69 radios | "#define" in the top of your sketch | @verbatim --my-rfm69-encryption-enabled @endverbatim + * | @ref MY_NRF5_ESB_ENABLE_ENCRYPTION | Enables encryption on nRF5 radios | "#define" in the top of your sketch | Not supported + * | @ref MY_NODE_LOCK_FEATURE | Enables the node locking feature | "#define" in the top of your sketch | Not supported + * | @ref MY_NODE_UNLOCK_PIN | Change default unlock pin | "#define" in the top of your sketch | Not supported + * | @ref MY_NODE_LOCK_COUNTER_MAX | Change default "malicious activity" counter max value | "#define" in the top of your sketch | Not supported * - * @see MY_RF24_ENABLE_ENCRYPTION, MY_RFM69_ENABLE_ENCRYPTION, MY_NRF5_ESB_ENABLE_ENCRYPTION * @{ */ +/** + * @def MY_SECURITY_SIMPLE_PASSWD + * @brief Enables SW backed signing functionality and encryption functionality in library and uses + * provided password as key. + * + * For details on the effects, see the references. + * @see MY_SIGNING_SIMPLE_PASSWD, MY_ENCRYPTION_SIMPLE_PASSWD + */ +//#define MY_SECURITY_SIMPLE_PASSWD "MyInsecurePassword" +#if defined(MY_SECURITY_SIMPLE_PASSWD) +#define MY_SIGNING_SIMPLE_PASSWD MY_SECURITY_SIMPLE_PASSWD +#define MY_ENCRYPTION_SIMPLE_PASSWD MY_SECURITY_SIMPLE_PASSWD +#endif + /** * @defgroup SigningSettingGrpPub Signing * @ingroup SecuritySettingGrpPub @@ -1500,8 +1532,10 @@ * @def MY_SIGNING_SIMPLE_PASSWD * @brief Enables SW backed signing functionality in library and uses provided password as key. * - * This flag will enable signing, signature requests and encryption. It has to be identical on ALL - * nodes in the network. + * This flag is automatically set if @ref MY_SECURITY_SIMPLE_PASSWD is used. + * + * This flag will enable signing and signature requests. It has to be identical on ALL nodes in the + * network. * * Whitelisting is supported and serial will be the first 8 characters of the password, the ninth * character will be the node ID (to make each node have a unique serial). @@ -1509,22 +1543,22 @@ * As with the regular signing modes, whitelisting is only activated if a whitelist is specified in * the sketch. * - * No personalization is required for this mode. + * No @ref personalization is required for this mode. * * It is allowed to set @ref MY_SIGNING_WEAK_SECURITY for deployment purposes in this mode as it is * with the regular software and ATSHA204A based modes. * - * If the provided password is shorter than the size of the HMAC or %AES key, it will be null-padded + * If the provided password is shorter than the size of the HMAC key, it will be null-padded * to accommodate the key size in question. A 32 character password is the maximum length. Any * password longer than that will be truncated. + * + * @see MY_SECURITY_SIMPLE_PASSWD + * */ //#define MY_SIGNING_SIMPLE_PASSWD "MyInsecurePassword" #if defined(MY_SIGNING_SIMPLE_PASSWD) #define MY_SIGNING_SOFT #define MY_SIGNING_REQUEST_SIGNATURES -#define MY_RF24_ENABLE_ENCRYPTION -#define MY_RFM69_ENABLE_ENCRYPTION -#define MY_NRF5_ESB_ENABLE_ENCRYPTION #endif /** @@ -1624,6 +1658,47 @@ #if defined(MY_SIGNING_ATSHA204) || defined(MY_SIGNING_SOFT) #define MY_SIGNING_FEATURE #endif +/** @}*/ // End of SigningSettingGrpPub group + +/** + * @defgroup EncryptionSettingGrpPub Encryption + * @ingroup SecuritySettingGrpPub + * @brief These options control encryption related configurations. + * + * Note that encryption is toggled on a per-radio basis. + * @see MY_RF24_ENABLE_ENCRYPTION, MY_RFM69_ENABLE_ENCRYPTION, MY_NRF5_ESB_ENABLE_ENCRYPTION + * @{ + */ + +/** + * @def MY_ENCRYPTION_SIMPLE_PASSWD + * @brief Enables encryption on all radio transports that supports it and uses provided password as key. + * + * This flag is automatically set if @ref MY_SECURITY_SIMPLE_PASSWD is used. + * + * This flag will enable encryption. It has to be identical on ALL nodes in the network. + * + * No @ref personalization is required for this mode. + * + * If the provided password is shorter than the size of the %AES key, it will be null-padded + * to accommodate the key size in question. A 16 character password is the maximum length. Any + * password longer than that will be truncated. + * + * @see MY_SECURITY_SIMPLE_PASSWD + */ +//#define MY_ENCRYPTION_SIMPLE_PASSWD "MyInsecurePassword" +#if defined(MY_ENCRYPTION_SIMPLE_PASSWD) +#ifndef MY_RF24_ENABLE_ENCRYPTION +#define MY_RF24_ENABLE_ENCRYPTION +#endif +#ifndef MY_RFM69_ENABLE_ENCRYPTION +#define MY_RFM69_ENABLE_ENCRYPTION +#endif +#ifndef MY_NRF5_ESB_ENABLE_ENCRYPTION +#define MY_NRF5_ESB_ENABLE_ENCRYPTION +#endif +#endif + /** * @def MY_ENCRYPTION_FEATURE * @ingroup internals @@ -1632,7 +1707,7 @@ #if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_RFM69_ENABLE_ENCRYPTION) || defined(MY_NRF5_ESB_ENABLE_ENCRYPTION) #define MY_ENCRYPTION_FEATURE #endif -/** @}*/ // End of SigningSettingGrpPub group +/** @}*/ // End of EncryptionSettingGrpPub group /** * @defgroup MyLockgrppub Node locking @@ -1949,7 +2024,9 @@ #define MY_DEFAULT_TX_LED_PIN #define MY_DEFAULT_RX_LED_PIN // signing +#define MY_SECURITY_SIMPLE_PASSWD "MyInsecurePassword" #define MY_SIGNING_SIMPLE_PASSWD "MyInsecurePassword" +#define MY_ENCRYPTION_SIMPLE_PASSWD "MyInsecurePassword" #define MY_SIGNING_ATSHA204 #define MY_SIGNING_SOFT #define MY_SIGNING_REQUEST_SIGNATURES diff --git a/configure b/configure index 8618eef..81c6efd 100755 --- a/configure +++ b/configure @@ -72,7 +72,7 @@ MySensors options: --my-rf24-encryption-enabled Enables RF24 encryption. All nodes and gateway must have this enabled, and all must be - personalized with the same AES key + personalized with the same AES key. --my-rx-message-buffer-size= Buffer size for incoming messages when using rf24 interrupts. [20] --my-rfm69-frequency=[315|433|868|915] @@ -80,6 +80,10 @@ MySensors options: --my-is-rfm69hw Enable high-powered rfm69hw. --my-rfm69-irq-pin= Pin number connected to RFM69 IRQ pin. --my-rfm69-cs-pin= Pin number to use for RFM69 Chip-Select. + --my-rfm69-encryption-enabled + Enables RFM69 encryption. + All nodes and gateway must have this enabled, and all must be + personalized with the same AES key. --my-rs485-serial-port= RS485 serial port. You must provide a port. --my-rs485-baudrate= RS485 baudrate. [9600] @@ -98,8 +102,13 @@ MySensors options: gateway signature. --my-signing-weak_security Enable this to permit downgrade of security preferences and relaxed gateway signing requirements. - --my-signing-password= - If you are using password as the signature type, set your password here. + --my-signing-whitelist= + If you want to use a whitelist, provide it here, make sure to avoid + spaces in the expression. + --my-signing-verification-timeout-ms= + Signing timeout. [5000] + --my-security-password= + If you are using password for signing/encryption, set your password here. EOF } @@ -258,6 +267,7 @@ gateway_type=ethernet transport_type=nrf24 signing=none signing_request_signatures=false +encryption=false params="SOC CFLAGS CXXFLAGS CPPFLAGS LDFLAGS PREFIX CC CXX ARDUINO_LIB_DIR BUILDDIR BINDIR GATEWAY_DIR INIT_SYSTEM SPI_DRIVER" @@ -398,6 +408,7 @@ for opt do CPPFLAGS="-DMY_RX_MESSAGE_BUFFER_FEATURE -DMY_RF24_IRQ_PIN=${optarg} $CPPFLAGS" ;; --my-rf24-encryption-enabled*) + encryption=true CPPFLAGS="-DMY_RF24_ENABLE_ENCRYPTION $CPPFLAGS" ;; --my-rx-message-buffer-size=*) @@ -425,6 +436,10 @@ for opt do --my-rfm69-cs-pin=*) CPPFLAGS="-DMY_RFM69_CS_PIN=${optarg} $CPPFLAGS" ;; + --my-rfm69-encryption-enabled*) + encryption=true + CPPFLAGS="-DMY_RFM69_ENABLE_ENCRYPTION $CPPFLAGS" + ;; --my-rs485-serial-port=*) CPPFLAGS="-DMY_RS485_HWSERIAL=\\\"${optarg}\\\" $CPPFLAGS" ;; @@ -461,8 +476,14 @@ for opt do --my-signing-weak_security*) CPPFLAGS="-DMY_SIGNING_WEAK_SECURITY $CPPFLAGS" ;; - --my-signing-password=*) - signing_password=${optarg} + --my-signing-whitelist*) + CPPFLAGS="-DMY_SIGNING_NODE_WHITELISTING=${optarg} $CPPFLAGS" + ;; + --my-signing-verification-timeout-ms*) + CPPFLAGS="-DMY_VERIFICATION_TIMEOUT_MS=${optarg} $CPPFLAGS" + ;; + --my-security-password=*) + security_password=${optarg} ;; *) echo "[WARNING] Unknown option detected:$opt, ignored" @@ -573,15 +594,25 @@ elif [[ ${signing} == "software" ]]; then CPPFLAGS="-DMY_SIGNING_REQUEST_SIGNATURES $CPPFLAGS" fi elif [[ ${signing} == "password" ]]; then - if [ -z "${signing_password}" ]; then - die "You need to set the password for signing with --my-signing-password= option" 6 + if [ -z "${security_password}" ]; then + die "You need to set the password for signing with --my-security-password= option" 6 fi echo "Simplified signing using password" - CPPFLAGS="-DMY_SIGNING_SIMPLE_PASSWD=\\\"${signing_password}\\\" $CPPFLAGS" + CPPFLAGS="-DMY_SIGNING_SIMPLE_PASSWD=\\\"${security_password}\\\" $CPPFLAGS" else die "Invalid signing type." 7 fi +if [[ ${encryption} == true ]]; then + # Encryption enabled on some transport + if [ -z "${security_password}" ]; then + echo "Encryption key from configuration" + else + echo "Simplified encryption using password" + CPPFLAGS="-DMY_ENCRYPTION_SIMPLE_PASSWD=\\\"${security_password}\\\" $CPPFLAGS" + fi +fi + LDFLAGS="-pthread $LDFLAGS" CPPFLAGS="$CPUFLAGS $CPPFLAGS" diff --git a/core/MySigning.h b/core/MySigning.h index cce6309..4c6df24 100644 --- a/core/MySigning.h +++ b/core/MySigning.h @@ -177,6 +177,16 @@ * personalization has finished, you just program the sketch you plan to use (with the appropriate * signing flags set). * + * If you are using a Raspberry PI-based gateway, personalizaion is done slightly differently: + * 1. Generate keys, execute @c mysgw with arguments + * * To generate HMAC key @verbatim --gen-soft-hmac-key @endverbatim + * * To generate %AES key @verbatim --gen-aes-key @endverbatim + * * To generate a soft serial number @verbatim --gen-soft-serial @endverbatim + * 2. Store keys/values to the gateway, execute @c mysgw with arguments + * * To store HMAC key @verbatim --set-soft-hmac-key= @endverbatim + * * To store %AES key @verbatim --set-aes-key= @endverbatim + * * To store soft serial number @verbatim --set-soft-serial-key= @endverbatim + * * You are now set and ready to use message signing in your network. * As of now, the following restrictions will be applied to your nodes: * * If a node does require signing, any unsigned message sent to the node will be rejected. @@ -393,8 +403,7 @@ * is to set your preferences in your sketch and personalize accordingly. * That is enough to enable protection from both Eve and Mallory in your network * although if you do not also enable encryption, Eve can eavesdrop, but not do anything about, - * your messages (except possibly preventing them from arriving). @ref MY_SIGNING_SIMPLE_PASSWD also - * enable encryption automatically. + * your messages (except possibly preventing them from arriving). * * How are the messages actually affected by the signing?
* The following illustration shows what part of the message is signed, and where the signature is diff --git a/hal/architecture/Linux/MyMainLinux.cpp b/hal/architecture/Linux/MyMainLinux.cpp index f67ea2f..6faf52e 100644 --- a/hal/architecture/Linux/MyMainLinux.cpp +++ b/hal/architecture/Linux/MyMainLinux.cpp @@ -134,7 +134,7 @@ void print_soft_sign_hmac_key(uint8_t *key_ptr = NULL) printf("\n\n"); printf("The next line is intended to be used in SecurityPersonalizer.ino:\n"); - printf("#define MY_SOFT_HMAC_KEY "); + printf("#define MY_HMAC_KEY "); for (int i=0; i<32; i++) { printf("%#02X", key_ptr[i]); if (i < 31) { @@ -265,9 +265,9 @@ void print_aes_key(uint8_t *key_ptr = NULL) uint8_t key[16]; if (key_ptr == NULL) { -#ifdef MY_SIGNING_SIMPLE_PASSWD +#ifdef MY_ENCRYPTION_SIMPLE_PASSWD memset(key, 0, 16); - memcpy(key, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD, 16)); + memcpy(key, MY_ENCRYPTION_SIMPLE_PASSWD, strnlen(MY_ENCRYPTION_SIMPLE_PASSWD, 16)); #else hwReadConfigBlock(&key, reinterpret_castEEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); #endif diff --git a/hal/transport/MyTransportNRF5_ESB.cpp b/hal/transport/MyTransportNRF5_ESB.cpp index 93f1366..49d2f25 100644 --- a/hal/transport/MyTransportNRF5_ESB.cpp +++ b/hal/transport/MyTransportNRF5_ESB.cpp @@ -39,9 +39,9 @@ uint8_t _psk[16]; bool transportInit(void) { #if defined(MY_NRF5_ESB_ENABLE_ENCRYPTION) -#ifdef MY_SIGNING_SIMPLE_PASSWD +#ifdef MY_ENCRYPTION_SIMPLE_PASSWD memset(_psk, 0, 16); - memcpy(_psk, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD, 16)); + memcpy(_psk, MY_ENCRYPTION_SIMPLE_PASSWD, strnlen(MY_ENCRYPTION_SIMPLE_PASSWD, 16)); #else hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); #endif diff --git a/hal/transport/MyTransportRF24.cpp b/hal/transport/MyTransportRF24.cpp index 10d6949..a858d5b 100644 --- a/hal/transport/MyTransportRF24.cpp +++ b/hal/transport/MyTransportRF24.cpp @@ -68,9 +68,9 @@ uint8_t _psk[16]; bool transportInit(void) { #if defined(MY_RF24_ENABLE_ENCRYPTION) -#ifdef MY_SIGNING_SIMPLE_PASSWD +#ifdef MY_ENCRYPTION_SIMPLE_PASSWD memset(_psk, 0, 16); - memcpy(_psk, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD, 16)); + memcpy(_psk, MY_ENCRYPTION_SIMPLE_PASSWD, strnlen(MY_ENCRYPTION_SIMPLE_PASSWD, 16)); #else hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); #endif diff --git a/hal/transport/MyTransportRFM69.cpp b/hal/transport/MyTransportRFM69.cpp index 31501bf..d21cbb1 100644 --- a/hal/transport/MyTransportRFM69.cpp +++ b/hal/transport/MyTransportRFM69.cpp @@ -35,9 +35,9 @@ bool transportInit(void) #ifdef MY_RFM69_ENABLE_ENCRYPTION uint8_t _psk[16]; -#ifdef MY_SIGNING_SIMPLE_PASSWD +#ifdef MY_ENCRYPTION_SIMPLE_PASSWD memset(_psk, 0, 16); - memcpy(_psk, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD, 16)); + memcpy(_psk, MY_ENCRYPTION_SIMPLE_PASSWD, strnlen(MY_ENCRYPTION_SIMPLE_PASSWD, 16)); #else hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); #endif @@ -170,9 +170,9 @@ bool transportInit(void) if (_radio.initialize(MY_RFM69_FREQUENCY, _address, MY_RFM69_NETWORKID)) { #ifdef MY_RFM69_ENABLE_ENCRYPTION uint8_t _psk[16]; -#ifdef MY_SIGNING_SIMPLE_PASSWD +#ifdef MY_ENCRYPTION_SIMPLE_PASSWD memset(_psk, 0, 16); - memcpy(_psk, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD, 16)); + memcpy(_psk, MY_ENCRYPTION_SIMPLE_PASSWD, strnlen(MY_ENCRYPTION_SIMPLE_PASSWD, 16)); #else hwReadConfigBlock((void*)_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); #endif diff --git a/keywords.txt b/keywords.txt index 15fa12a..86e9943 100644 --- a/keywords.txt +++ b/keywords.txt @@ -84,7 +84,9 @@ MY_DEBUG_OTA_DISABLE_ACK LITERAL1 # Signing MY_DEBUG_VERBOSE_SIGNING LITERAL1 +MY_SECURITY_SIMPLE_PASSWD LITERAL1 MY_SIGNING_SIMPLE_PASSWD LITERAL1 +MY_ENCRYPTION_SIMPLE_PASSWD LITERAL1 MY_SIGNING_ATSHA204 LITERAL1 MY_SIGNING_SOFT LITERAL1 MY_VERIFICATION_TIMEOUT_MS LITERAL1