From 341f3148954484775a696e4306799e4943a83bdb Mon Sep 17 00:00:00 2001 From: Alexey Zholtikov Date: Thu, 19 Jan 2023 18:36:57 +0300 Subject: [PATCH] Version 1.4 Added simple XOR crypting. --- README.md | 26 ++++++++++++++++++-------- examples/Receiver/main.cpp | 1 + examples/Transmitter/main.cpp | 1 + library.properties | 2 +- src/ZHNetwork.cpp | 33 +++++++++++++++++++++++++++++++-- src/ZHNetwork.h | 4 +++- 6 files changed, 55 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 88f5c51..bc07624 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ A simple library for creating ESP-NOW based Mesh network for ESP8266/ESP32. ## Features -1. The maximum size of transmitted data is 200 bytes. Currently only unencrypted messages. -2. All nodes are not visible to the network scanner. -3. Not required a pre-pairings for data transfer. -4. Broadcast or unicast data transmission. -5. There are no periodic/synchronous messages on the network. All devices are in "silent mode" and do not "hum" into the air. -6. Each node has its own independent routing table, updated only as needed. -7. Each node will receive/send a message if it "sees" at least one device on the network. -8. The number of devices on the network and the area of use is not limited (hypothetically). :-) +1. The maximum size of transmitted data is 200 bytes. +2. Encrypted and unencrypted messages. Simple XOR crypting. +3. All nodes are not visible to the network scanner. +4. Not required a pre-pairings for data transfer. +5. Broadcast or unicast data transmissions. +6. There are no periodic/synchronous messages on the network. All devices are in "silent mode" and do not "hum" into the air. +7. Each node has its own independent routing table, updated only as needed. +8. Each node will receive/send a message if it "sees" at least one device on the network. +9. The number of devices on the network and the area of use is not limited (hypothetically). :-) ## Testing @@ -126,6 +127,14 @@ uint8_t mac[6] myNet.stringToMac(string, mac); ``` +### Sets crypt key + +1-20 characters. + +```cpp +myNet.setCryptKey("VERY_LONG_CRYPT_KEY"); +``` + ### Sets max number of attempts to send message 1-10. 3 default value. @@ -188,6 +197,7 @@ void setup() Serial.begin(115200); Serial.println(); myNet.begin("ZHNetwork"); + myNet.setCryptKey("VERY_LONG_CRYPT_KEY"); myNet.setOnBroadcastReceivingCallback(onBroadcastReceiving); myNet.setOnUnicastReceivingCallback(onUnicastReceiving); myNet.setOnConfirmReceivingCallback(onConfirmReceiving); diff --git a/examples/Receiver/main.cpp b/examples/Receiver/main.cpp index a88ded1..efb9cf2 100644 --- a/examples/Receiver/main.cpp +++ b/examples/Receiver/main.cpp @@ -10,6 +10,7 @@ void setup() Serial.begin(115200); Serial.println(); myNet.begin("ZHNetwork"); + myNet.setCryptKey("VERY_LONG_CRYPT_KEY"); myNet.setOnBroadcastReceivingCallback(onBroadcastReceiving); myNet.setOnUnicastReceivingCallback(onUnicastReceiving); Serial.print("MAC: "); diff --git a/examples/Transmitter/main.cpp b/examples/Transmitter/main.cpp index a1774a2..da4d161 100644 --- a/examples/Transmitter/main.cpp +++ b/examples/Transmitter/main.cpp @@ -13,6 +13,7 @@ void setup() Serial.begin(115200); Serial.println(); myNet.begin("ZHNetwork"); + myNet.setCryptKey("VERY_LONG_CRYPT_KEY"); myNet.setOnConfirmReceivingCallback(onConfirmReceiving); Serial.print("MAC: "); Serial.print(myNet.getNodeMac()); diff --git a/library.properties b/library.properties index 9639481..908c312 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ZHNetwork -version=1.32 +version=1.4 author=Alexey Zholtikov maintainer=Alexey Zholtikov sentence=ESP-NOW based Mesh network for ESP8266/ESP32 diff --git a/src/ZHNetwork.cpp b/src/ZHNetwork.cpp index e4f13a2..ce4a6e5 100644 --- a/src/ZHNetwork.cpp +++ b/src/ZHNetwork.cpp @@ -11,6 +11,7 @@ bool ZHNetwork::sentMessageSemaphore{false}; bool ZHNetwork::confirmReceivingSemaphore{false}; bool ZHNetwork::confirmReceiving{false}; char ZHNetwork::netName_[20]{0}; +char ZHNetwork::key_[20]{0}; uint8_t ZHNetwork::localMAC[6]{0}; uint16_t ZHNetwork::lastMessageID[10]{0}; @@ -35,7 +36,7 @@ ZHNetwork &ZHNetwork::setOnConfirmReceivingCallback(on_confirm_t onConfirmReceiv error_code_t ZHNetwork::begin(const char *netName, const bool gateway) { randomSeed(analogRead(0)); - if (strlen(netName) > 1 && strlen(netName) < 20) + if (strlen(netName) >= 1 && strlen(netName) <= 20) strcpy(netName_, netName); #ifdef PRINT_LOG Serial.begin(115200); @@ -192,7 +193,12 @@ void ZHNetwork::maintenance() Serial.println(F(" received.")); #endif if (onBroadcastReceivingCallback) + { + if (key_[0]) + for (uint8_t i{0}; i < strlen(incomingData.transmittedData.message); ++i) + incomingData.transmittedData.message[i] = incomingData.transmittedData.message[i] ^ key_[i % strlen(key_)]; onBroadcastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC); + } forward = true; break; case UNICAST: @@ -208,7 +214,12 @@ void ZHNetwork::maintenance() if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC)) { if (onUnicastReceivingCallback) + { + if (key_[0]) + for (uint8_t i{0}; i < strlen(incomingData.transmittedData.message); ++i) + incomingData.transmittedData.message[i] = incomingData.transmittedData.message[i] ^ key_[i % strlen(key_)]; onUnicastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC); + } } else unicastMessage(incomingData.transmittedData.message, incomingData.transmittedData.originalTargetMAC, incomingData.transmittedData.originalSenderMAC, UNICAST); @@ -226,7 +237,12 @@ void ZHNetwork::maintenance() if (macToString(incomingData.transmittedData.originalTargetMAC) == macToString(localMAC)) { if (onUnicastReceivingCallback) + { + if (key_[0]) + for (uint8_t i{0}; i < strlen(incomingData.transmittedData.message); ++i) + incomingData.transmittedData.message[i] = incomingData.transmittedData.message[i] ^ key_[i % strlen(key_)]; onUnicastReceivingCallback(incomingData.transmittedData.message, incomingData.transmittedData.originalSenderMAC); + } confirmation_id_t id; memcpy(&id.messageID, &incomingData.transmittedData.messageID, 2); char temp[sizeof(transmitted_data_t::message)]; @@ -405,7 +421,7 @@ void ZHNetwork::maintenance() for (uint16_t i{0}; i < confirmationVector.size(); ++i) { confirmation_waiting_data_t confirmationData = confirmationVector[i]; - if ((millis() - confirmationData.time) > 1000) + if ((millis() - confirmationData.time) > maxTimeForRoutingInfoWaiting_) { confirmationVector.erase(confirmationVector.begin() + i); broadcastMessage("", confirmationData.targetMAC, SEARCH_REQUEST); @@ -448,6 +464,13 @@ uint8_t *ZHNetwork::stringToMac(const String &string, uint8_t *mac) return mac; } +error_code_t ZHNetwork::setCryptKey(const char *key) +{ + if (strlen(key) >= 1 && strlen(key) <= 20) + strcpy(key_, key); + return SUCCESS; +} + error_code_t ZHNetwork::setMaxNumberOfAttempts(const uint8_t maxNumberOfAttempts) { if (maxNumberOfAttempts < 1 || maxNumberOfAttempts > 10) @@ -551,6 +574,9 @@ uint16_t ZHNetwork::broadcastMessage(const char *data, const uint8_t *target, me memcpy(&outgoingData.transmittedData.originalTargetMAC, target, 6); memcpy(&outgoingData.transmittedData.originalSenderMAC, &localMAC, 6); strcpy(outgoingData.transmittedData.message, data); + if (key_[0] && outgoingData.transmittedData.messageType == BROADCAST) + for (uint8_t i{0}; i < strlen(outgoingData.transmittedData.message); ++i) + outgoingData.transmittedData.message[i] = outgoingData.transmittedData.message[i] ^ key_[i % strlen(key_)]; memcpy(&outgoingData.intermediateTargetMAC, &broadcastMAC, 6); queueForOutgoingData.push(outgoingData); #ifdef PRINT_LOG @@ -586,6 +612,9 @@ uint16_t ZHNetwork::unicastMessage(const char *data, const uint8_t *target, cons memcpy(&outgoingData.transmittedData.originalTargetMAC, target, 6); memcpy(&outgoingData.transmittedData.originalSenderMAC, sender, 6); strcpy(outgoingData.transmittedData.message, data); + if (key_[0] && macToString(outgoingData.transmittedData.originalSenderMAC) == macToString(localMAC) && outgoingData.transmittedData.messageType != DELIVERY_CONFIRM_RESPONSE) + for (uint8_t i{0}; i < strlen(outgoingData.transmittedData.message); ++i) + outgoingData.transmittedData.message[i] = outgoingData.transmittedData.message[i] ^ key_[i % strlen(key_)]; for (uint16_t i{0}; i < routingVector.size(); ++i) { routing_table_t routingTable = routingVector[i]; diff --git a/src/ZHNetwork.h b/src/ZHNetwork.h index 992a023..d23fa58 100644 --- a/src/ZHNetwork.h +++ b/src/ZHNetwork.h @@ -108,6 +108,7 @@ public: static String macToString(const uint8_t *mac); uint8_t *stringToMac(const String &string, uint8_t *mac); + error_code_t setCryptKey(const char *key = ""); error_code_t setMaxNumberOfAttempts(const uint8_t maxNumberOfAttempts); uint8_t getMaxNumberOfAttempts(void); error_code_t setMaxWaitingTimeBetweenTransmissions(const uint8_t maxWaitingTimeBetweenTransmissions); @@ -129,8 +130,9 @@ private: static uint8_t localMAC[6]; static uint16_t lastMessageID[10]; static char netName_[20]; + static char key_[20]; - const char *firmware{"1.32"}; + const char *firmware{"1.4"}; const uint8_t broadcastMAC[6]{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t maxNumberOfAttempts_{3}; uint8_t maxWaitingTimeBetweenTransmissions_{50};