diff --git a/MyConfig.h b/MyConfig.h index c08b1f2..8a48503 100644 --- a/MyConfig.h +++ b/MyConfig.h @@ -817,6 +817,18 @@ */ //#define MY_DEBUG_VERBOSE_RFM95 +/** + * @def MY_RFM95_ENABLE_ENCRYPTION + * @brief Define this to enable software based %AES encryption. + * + * All nodes and gateway must have this enabled, and all must be personalized with the same %AES + * key. + * @see @ref personalization + * + * @warning This driver always sets the initialization vector to 0 so encryption is weak. + */ +//#define MY_RFM95_ENABLE_ENCRYPTION + /** * @def MY_RFM95_FREQUENCY * @brief The frequency to use. @@ -1799,7 +1811,7 @@ /** * @def MY_SIGNING_FEATURE * @ingroup internals - * @brief Helper flag to indicate that some signing feature is enabled + * @brief Helper flag to indicate that some signing feature is enabled, set automatically */ #if defined(MY_SIGNING_ATSHA204) || defined(MY_SIGNING_SOFT) #define MY_SIGNING_FEATURE @@ -1812,7 +1824,7 @@ * @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 + * @see MY_RF24_ENABLE_ENCRYPTION, MY_RFM69_ENABLE_ENCRYPTION, MY_NRF5_ESB_ENABLE_ENCRYPTION, MY_RFM95_ENABLE_ENCRYPTION * @{ */ @@ -1845,14 +1857,18 @@ #ifndef MY_NRF5_ESB_ENABLE_ENCRYPTION #define MY_NRF5_ESB_ENABLE_ENCRYPTION #endif +#ifndef MY_RFM95_ENABLE_ENCRYPTION +#define MY_RFM95_ENABLE_ENCRYPTION +#endif #endif /** * @def MY_ENCRYPTION_FEATURE * @ingroup internals - * @brief Helper flag to indicate that some encryption feature is enabled + * @brief Helper flag to indicate that some encryption feature is enabled, set automatically + * @see MY_RF24_ENABLE_ENCRYPTION, MY_RFM69_ENABLE_ENCRYPTION, MY_NRF5_ESB_ENABLE_ENCRYPTION, MY_RFM95_ENABLE_ENCRYPTION */ -#if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_RFM69_ENABLE_ENCRYPTION) || defined(MY_NRF5_ESB_ENABLE_ENCRYPTION) +#if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_RFM69_ENABLE_ENCRYPTION) || defined(MY_NRF5_ESB_ENABLE_ENCRYPTION) || defined(MY_RFM95_ENABLE_ENCRYPTION) #define MY_ENCRYPTION_FEATURE #endif /** @}*/ // End of EncryptionSettingGrpPub group @@ -2303,6 +2319,7 @@ // RFM95 #define MY_RADIO_RFM95 #define MY_DEBUG_VERBOSE_RFM95 +#define MY_RFM95_ENABLE_ENCRYPTION #define MY_RFM95_ATC_MODE_DISABLED #define MY_RFM95_RST_PIN #define MY_RFM95_MODEM_CONFIGRUATION diff --git a/configure b/configure index dcca71b..b545e29 100755 --- a/configure +++ b/configure @@ -85,6 +85,10 @@ MySensors options: Enables RFM69 encryption. All nodes and gateway must have this enabled, and all must be personalized with the same AES key. + --my-rfm95-encryption-enabled + Enables RFM95 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] @@ -450,6 +454,10 @@ for opt do encryption=true CPPFLAGS="-DMY_RFM69_ENABLE_ENCRYPTION $CPPFLAGS" ;; + --my-rfm95-encryption-enabled*) + encryption=true + CPPFLAGS="-DMY_RFM95_ENABLE_ENCRYPTION $CPPFLAGS" + ;; --my-rs485-serial-port=*) CPPFLAGS="-DMY_RS485_HWSERIAL=\\\"${optarg}\\\" $CPPFLAGS" ;; diff --git a/core/MyCapabilities.h b/core/MyCapabilities.h index d83875c..629ea6b 100644 --- a/core/MyCapabilities.h +++ b/core/MyCapabilities.h @@ -218,14 +218,14 @@ * @def MY_CAP_ENCR * @brief Indicate the encryption setting. * - * @see MY_RF24_ENABLE_ENCRYPTION, MY_RFM69_ENABLE_ENCRYPTION, MY_NRF5_ESB_ENABLE_ENCRYPTION + * @see MY_ENCRYPTION_FEATURE * * | Setting | Indicator * |------------|---------- * | Enabled | X * | Disabled | - */ -#if defined(MY_RF24_ENABLE_ENCRYPTION) || defined(MY_RFM69_ENABLE_ENCRYPTION) || defined (MY_NRF5_ESB_ENABLE_ENCRYPTION) +#if defined(MY_ENCRYPTION_FEATURE) #define MY_CAP_ENCR "X" #else #define MY_CAP_ENCR "-" diff --git a/hal/transport/RFM95/MyTransportRFM95.cpp b/hal/transport/RFM95/MyTransportRFM95.cpp index 7003012..5e3bd64 100644 --- a/hal/transport/RFM95/MyTransportRFM95.cpp +++ b/hal/transport/RFM95/MyTransportRFM95.cpp @@ -18,6 +18,14 @@ */ #include "drivers/RFM95/RFM95.h" +#if defined(MY_RFM95_ENABLE_ENCRYPTION) +#include "drivers/AES/AES.h" +#endif + +#if defined(MY_RFM95_ENABLE_ENCRYPTION) +AES RFM95_aes; +uint8_t RFM95_dataenc[32] = {0}; +#endif #if defined(MY_RFM95_ENABLE_ENCRYPTION) #include "drivers/AES/AES.cpp" @@ -25,6 +33,20 @@ bool transportInit(void) { +#if defined(MY_RFM95_ENABLE_ENCRYPTION) + uint8_t RFM95_psk[16]; +#ifdef MY_SIGNING_SIMPLE_PASSWD + memset(RFM95_psk, 0, 16); + memcpy(RFM95_psk, MY_SIGNING_SIMPLE_PASSWD, strnlen(MY_SIGNING_SIMPLE_PASSWD, 16)); +#else + hwReadConfigBlock((void*)RFM95_psk, (void*)EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16); +#endif + //set up AES-key + RFM95_aes.set_key(RFM95_psk, 16); + // Make sure it is purged from memory when set + memset(RFM95_psk, 0, 16); +#endif + const bool result = RFM95_initialise(MY_RFM95_FREQUENCY); #if defined(MY_RFM95_TCXO) RFM95_enableTCXO(); @@ -48,11 +70,26 @@ uint8_t transportGetAddress(void) bool transportSend(const uint8_t to, const void *data, const uint8_t len, const bool noACK) { +#if defined(MY_RFM95_ENABLE_ENCRYPTION) + // copy input data because it is read-only + (void)memcpy(RFM95_dataenc,data,len); + // has to be adjusted, WIP! + RFM95_aes.set_IV(0); + const uint8_t finalLength = len > 16 ? 32 : 16; + //encrypt data + RFM95_aes.cbc_encrypt(RFM95_dataenc, RFM95_dataenc, finalLength /16); + if (noACK) { + (void)RFM95_sendWithRetry(to, RFM95_dataenc, finalLength, 0, 0); + return true; + } + return RFM95_sendWithRetry(to, RFM95_dataenc, finalLength); +#else if (noACK) { (void)RFM95_sendWithRetry(to, data, len, 0, 0); return true; } return RFM95_sendWithRetry(to, data, len); +#endif } bool transportAvailable(void) @@ -68,7 +105,15 @@ bool transportSanityCheck(void) uint8_t transportReceive(void *data) { - const uint8_t len = RFM95_receive((uint8_t *)data, MAX_MESSAGE_LENGTH); + uint8_t len = RFM95_receive((uint8_t*)data, MAX_MESSAGE_LENGTH); +#if defined(MY_RFM95_ENABLE_ENCRYPTION) + // has to be adjusted, WIP! + RFM95_aes.set_IV(0); + // decrypt data + if (RFM95_aes.cbc_decrypt((uint8_t*)(data), (uint8_t*)(data), len > 16 ? 2 : 1) != AES_SUCCESS) { + len = 0; + } +#endif return len; } diff --git a/keywords.txt b/keywords.txt index b22e5fd..2643bae 100644 --- a/keywords.txt +++ b/keywords.txt @@ -192,6 +192,7 @@ MY_RFM95_TCXO LITERAL1 MY_RFM95_TX_POWER LITERAL1 MY_RFM95_TX_POWER_DBM LITERAL1 MY_RFM95_TX_TIMEOUT_MS LITERAL1 +MY_RFM95_ENABLE_ENCRYPTION LITERAL1 # RFM69 MY_DEBUG_VERBOSE_RFM69 LITERAL1 diff --git a/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino b/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino index 510c72c..67fc11e 100644 --- a/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino +++ b/tests/Arduino/sketches/hard_signing_whitelisting_full_debug_rfm95_rsa/hard_signing_whitelisting_full_debug_rfm95_rsa.ino @@ -33,6 +33,6 @@ #ifndef MY_SIGNING_ATSHA204_PIN #define MY_SIGNING_ATSHA204_PIN 17 #endif -#define MY_RFM69_ENABLE_ENCRYPTION +#define MY_RFM95_ENABLE_ENCRYPTION #include