1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-24 19:42:27 +03:00

- Make it possible to transfer Strings containing null values via ESP-NOW and FloodingMesh.

- Add uint8ArrayToMultiString and bufferedUint8ArrayToMultiString TypeConversionFunctions to facilitate transfer of Strings containing null values.

- Add HKDF to CryptoInterface.

- Add ChaCha20 + Poly1305 AEAD to CryptoInterface.

- Add customizable nonce generator to CryptoInterface.

- Add ability to automatically encrypt/decrypt ESP-NOW messages via AEAD (ChaCha20 + Poly1305), independent from encrypted ESP-NOW connections.

- Greatly improve performance of incrementSessionKey, espnowGetMessageID, espnowSetMessageID and all non-template TypeConversionFunctions. The average performance increase is roughly a factor 5. Fun fact: Printing a MAC to a HEX String is now over twice as fast when using TypeConversionFunctions compared to using standard functionality like sprintf.

- Add uint64ToUint8Array and uint8ArrayToUint64 TypeConversionFunctions.

- Make it possible to use String values as ESP-NOW and FloodingMesh key seeds, instead of just requiring plain key arrays.

- Add customizable responseTransmittedHook to sendEspnowResponses.

- Add _responsesToSendMutex to make the new responseTransmittedHook safe to use.

- Remove verboseModePrinting from sendPeerRequestConfirmations method to reduce performance variations.

- Fix faulty messageID generation in FloodingMesh.

- Make assert checks more complete and easier to understand in the setMetadataDelimiter method of FloodingMesh.

- Rename EspnowEncryptionKey to EspnowEncryptedConnectionKey since there are now multiple encryption keys.

- Rename acceptsUnencryptedRequests to acceptsUnverifiedRequests, unencryptedMessageID to unsynchronizedMessageID, receivedEncryptedMessage to receivedEncryptedTransmission, since there are now multiple modes of encryption.

- Rename resultArrayLength to outputLength in CryptoInterface and remove its value restrictions in order to match the BearSSL functionality.

- Improve performance of FloodingMesh::encryptedBroadcast.

- Rename FloodingMesh methods maxUnencryptedMessageSize/maxEncryptedMessageSize to maxUnencryptedMessageLength/maxEncryptedMessageLength, so that String length naming is consistent within the library.

- Update examples to illustrate the new features.

- Improve comments.
This commit is contained in:
Anders
2019-12-04 02:30:16 +01:00
parent 2fef67dcb0
commit 962a23d253
20 changed files with 1202 additions and 318 deletions

View File

@ -42,7 +42,7 @@
* This enables flexible easy-to-use encrypted ESP-NOW communication. 'P' and 'C' messages can be encrypted.
* The encryption pairing process works as follows (from top to bottom):
*
* Encryption pairing process, schematic overview:
* Encrypted connection pairing process, schematic overview:
*
* Connection | Peer sends ('C'): | Peer requester sends ('P'): | Connection
* encrypted: | | | encrypted:
@ -66,6 +66,13 @@
* Messages of type 'A' and 'C' are response types, and thus use the same session key as the corresponding 'R' and 'P' message they are responding to.
* This means they can never cause a desynchronization to occur, and therefore they do not trigger 'S' messages.
*
* In addition to using encrypted ESP-NOW connections the framework can also send automatically encrypted messages (AEAD) over both encrypted and unencrypted connections.
* Using AEAD will only encrypt the message content, not the transmission metadata.
* The AEAD encryption does not require any pairing, and is thus faster for single messages than establishing a new encrypted connection before transfer.
* AEAD encryption also works with ESP-NOW broadcasts and supports an unlimited number of nodes, which is not true for encrypted connections.
* Encrypted ESP-NOW connections do however come with built in replay attack protection, which is not provided by the framework when using AEAD encryption,
* and allow EspnowProtocolInterpreter::aeadMetadataSize extra message bytes per transmission.
* Transmissions via encrypted connections are also slightly faster than via AEAD once a connection has been established.
*/
#ifndef __ESPNOWMESHBACKEND_H__
@ -81,6 +88,7 @@
#include <map>
#include <list>
#include "EspnowNetworkInfo.h"
#include "CryptoInterface.h"
typedef enum
{
@ -127,6 +135,7 @@ class EspnowMeshBackend : public MeshBackendBase {
protected:
typedef std::function<bool(String &, EspnowMeshBackend &)> broadcastFilterType;
typedef std::function<bool(const String &, const uint8_t *, uint32_t, EspnowMeshBackend &)> responseTransmittedHookType;
public:
@ -140,7 +149,7 @@ public:
* @param networkFilter The callback handler for deciding which WiFi networks to connect to.
* @param broadcastFilter The callback handler for deciding which ESP-NOW broadcasts to accept.
* @param meshPassword The WiFi password for the mesh network.
* @param espnowEncryptionKey An uint8_t array containing the key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections.
* @param espnowEncryptedConnectionKey An uint8_t array containing the secret key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections.
* @param espnowHashKey An uint8_t array containing the secret key used by this EspnowMeshBackend to generate HMACs for encrypted ESP-NOW connections.
* @param ssidPrefix The prefix (first part) of the node SSID.
* @param ssidSuffix The suffix (last part) of the node SSID.
@ -154,10 +163,37 @@ public:
*
*/
EspnowMeshBackend(requestHandlerType requestHandler, responseHandlerType responseHandler, networkFilterType networkFilter, broadcastFilterType broadcastFilter,
const String &meshPassword, const uint8_t espnowEncryptionKey[EspnowProtocolInterpreter::espnowEncryptionKeyLength],
const String &meshPassword, const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength],
const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength], const String &ssidPrefix,
const String &ssidSuffix, bool verboseMode = false, uint8 meshWiFiChannel = 1);
/**
* ESP-NOW constructor method. Creates an ESP-NOW node, ready to be initialised.
*
* @param requestHandler The callback handler for dealing with received requests. Takes a string as an argument which
* is the request string received from another node and returns the string to send back.
* @param responseHandler The callback handler for dealing with received responses. Takes a string as an argument which
* is the response string received from another node. Returns a transmission status code as a transmission_status_t.
* @param networkFilter The callback handler for deciding which WiFi networks to connect to.
* @param broadcastFilter The callback handler for deciding which ESP-NOW broadcasts to accept.
* @param meshPassword The WiFi password for the mesh network.
* @param espnowEncryptedConnectionKeySeed A string containing the seed that will generate the secret key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections.
* @param espnowHashKeySeed A string containing the seed that will generate the secret key used by this EspnowMeshBackend to generate HMACs for encrypted ESP-NOW connections.
* @param ssidPrefix The prefix (first part) of the node SSID.
* @param ssidSuffix The suffix (last part) of the node SSID.
* @param verboseMode Determines if we should print the events occurring in the library to Serial. Off by default. This setting is shared by all EspnowMeshBackend instances.
* @param meshWiFiChannel The WiFi channel used by the mesh network. Valid values are integers from 1 to 13. Defaults to 1.
* WARNING: The ESP8266 has only one WiFi channel, and the the station/client mode is always prioritized for channel selection.
* This can cause problems if several mesh instances exist on the same ESP8266 and use different WiFi channels.
* In such a case, whenever the station of one mesh instance connects to an AP, it will silently force the
* WiFi channel of any active AP on the ESP8266 to match that of the station. This will cause disconnects and possibly
* make it impossible for other stations to detect the APs whose WiFi channels have changed.
*
*/
EspnowMeshBackend(requestHandlerType requestHandler, responseHandlerType responseHandler, networkFilterType networkFilter, broadcastFilterType broadcastFilter,
const String &meshPassword, const String &espnowEncryptedConnectionKeySeed, const String &espnowHashKeySeed, const String &ssidPrefix,
const String &ssidSuffix, bool verboseMode = false, uint8 meshWiFiChannel = 1);
~EspnowMeshBackend() override;
/**
@ -327,20 +363,50 @@ public:
*
* NOTE: Encrypted connections added before the encryption key change will retain their old encryption key.
* Only changes the encryption key used by this EspnowMeshBackend instance, so each instance can use a separate key.
* Both Kok and encryption key must match in an encrypted connection pair for encrypted communication to be possible.
* Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible.
* Otherwise the transmissions will never reach the recipient, even though acks are received by the sender.
*
* @param espnowEncryptionKey An array containing the espnowEncryptionKeyLength bytes that will be used as the encryption key.
* @param espnowEncryptedConnectionKey An array containing the espnowEncryptedConnectionKeyLength bytes that will be used as the encryption key.
*/
void setEspnowEncryptionKey(const uint8_t espnowEncryptionKey[EspnowProtocolInterpreter::espnowEncryptionKeyLength]);
void setEspnowEncryptedConnectionKey(const uint8_t espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]);
/**
* Change the key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections.
* Will apply to any new received requests for encrypted connection if this EspnowMeshBackend instance is the current request manager.
* Will apply to any new encrypted connections requested or added by this EspnowMeshBackend instance.
*
* NOTE: Encrypted connections added before the encryption key change will retain their old encryption key.
* Only changes the encryption key used by this EspnowMeshBackend instance, so each instance can use a separate key.
* Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible.
* Otherwise the transmissions will never reach the recipient, even though acks are received by the sender.
*
* @param espnowHashKeySeed A string that will be used to generate the encryption key. The same string will always generate the same key.
* A minimum of 8 random characters are recommended to ensure sufficient key variation.
*/
void setEspnowEncryptedConnectionKey(const String &espnowEncryptedConnectionKeySeed);
/**
* Get the encryption key used by this EspnowMeshBackend instance for creating encrypted ESP-NOW connections.
*
* @return The current espnowEncryptionKey for this EspnowMeshBackend instance.
* @return The current espnowEncryptedConnectionKey for this EspnowMeshBackend instance.
*/
const uint8_t *getEspnowEncryptionKey();
uint8_t *getEspnowEncryptionKey(uint8_t resultArray[EspnowProtocolInterpreter::espnowEncryptionKeyLength]);
const uint8_t *getEspnowEncryptedConnectionKey();
uint8_t *getEspnowEncryptedConnectionKey(uint8_t resultArray[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]);
/**
* Change the key used to encrypt/decrypt the encrypted connection key when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) If no Kok is provided by the user, a default Kok is used.
* Will apply to any new encrypted connections.
* Must be called after begin() to take effect.
*
* NOTE: Encrypted connections added before the Kok change will retain their old Kok.
* This changes the Kok for all EspnowMeshBackend instances on this ESP8266.
* Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible.
* Otherwise the transmissions will never reach the recipient, even though acks are received by the sender.
*
* @param espnowEncryptionKok An array containing the espnowEncryptedConnectionKeyLength bytes that will be used as the Kok.
* @return True if Kok was changed successfully. False if Kok was not changed.
*/
static bool setEspnowEncryptionKok(uint8_t espnowEncryptionKok[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength]);
/**
* Change the key used to encrypt/decrypt the encryption key when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) If no Kok is provided by the user, a default Kok is used.
@ -349,13 +415,14 @@ public:
*
* NOTE: Encrypted connections added before the Kok change will retain their old Kok.
* This changes the Kok for all EspnowMeshBackend instances on this ESP8266.
* Both Kok and encryption key must match in an encrypted connection pair for encrypted communication to be possible.
* Both Kok and encrypted connection key must match in an encrypted connection pair for encrypted communication to be possible.
* Otherwise the transmissions will never reach the recipient, even though acks are received by the sender.
*
* @param espnowEncryptionKok An array containing the espnowEncryptionKeyLength bytes that will be used as the Kok.
* @param espnowEncryptionKokSeed A string that will be used to generate the KoK. The same string will always generate the same KoK.
* A minimum of 8 random characters are recommended to ensure sufficient KoK variation.
* @return True if Kok was changed successfully. False if Kok was not changed.
*/
static bool setEspnowEncryptionKok(uint8_t espnowEncryptionKok[EspnowProtocolInterpreter::espnowEncryptionKeyLength]);
static bool setEspnowEncryptionKok(const String &espnowEncryptionKokSeed);
/**
* Get the key used to encrypt the encryption keys when creating encrypted ESP-NOW connections. (Kok = key of keys, perhaps) Returns nullptr if no Kok has been provided by the user.
@ -364,7 +431,7 @@ public:
*/
static const uint8_t *getEspnowEncryptionKok();
/**
/**
* Change the secret key used to generate HMACs for encrypted ESP-NOW connections.
* Will apply to any new received requests for encrypted connection if this EspnowMeshBackend instance is the current request manager.
* Will apply to any new encrypted connections requested or added by this EspnowMeshBackend instance.
@ -375,12 +442,75 @@ public:
* @param espnowHashKey An array containing the espnowHashKeyLength bytes that will be used as the HMAC key.
*/
void setEspnowHashKey(const uint8_t espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength]);
/**
* Change the secret key used to generate HMACs for encrypted ESP-NOW connections.
* Will apply to any new received requests for encrypted connection if this EspnowMeshBackend instance is the current request manager.
* Will apply to any new encrypted connections requested or added by this EspnowMeshBackend instance.
*
* NOTE: Encrypted connections added before the key change will retain their old key.
* Only changes the secret hash key used by this EspnowMeshBackend instance, so each instance can use a separate secret key.
*
* @param espnowHashKeySeed A string that will be used to generate the HMAC key. The same string will always generate the same key.
* A minimum of 8 random characters are recommended to ensure sufficient key variation.
*/
void setEspnowHashKey(const String &espnowHashKeySeed);
const uint8_t *getEspnowHashKey();
/**
* Change the key used to encrypt/decrypt messages when using AEAD encryption.
* If no message encryption key is provided by the user, a default key consisting of all zeroes is used.
*
* This changes the message encryption key for all EspnowMeshBackend instances on this ESP8266.
*
* @param espnowMessageEncryptionKey An array containing the CryptoInterface::ENCRYPTION_KEY_LENGTH bytes that will be used as the message encryption key.
*/
static void setEspnowMessageEncryptionKey(uint8_t espnowMessageEncryptionKey[CryptoInterface::ENCRYPTION_KEY_LENGTH]);
/**
* Change the key used to encrypt/decrypt messages when using AEAD encryption.
* If no message encryption key is provided by the user, a default key consisting of all zeroes is used.
*
* This changes the message encryption key for all EspnowMeshBackend instances on this ESP8266.
*
* @param espnowMessageEncryptionKeySeed A string that will be used to generate the message encryption key. The same string will always generate the same key.
* A minimum of 8 random characters are recommended to ensure sufficient key variation.
*/
static void setEspnowMessageEncryptionKey(const String &espnowMessageEncryptionKeySeed);
/**
* Get the key used to encrypt/decrypt messages when using AEAD encryption.
*
* @return An uint8_t array with size CryptoInterface::ENCRYPTION_KEY_LENGTH containing the currently used message encryption key.
*/
static const uint8_t *getEspnowMessageEncryptionKey();
/**
* If true, AEAD will be used to encrypt/decrypt all messages sent/received by this node via ESP-NOW, regardless of whether the connection is encrypted or not.
* All nodes this node wishes to communicate with must then also use encrypted messages with the same getEspnowMessageEncryptionKey(), or messages will not be accepted.
* Note that using encrypted messages will reduce the number of message bytes that can be transmitted.
*
* Using AEAD will only encrypt the message content, not the transmission metadata.
* The AEAD encryption does not require any pairing, and is thus faster for single messages than establishing a new encrypted connection before transfer.
* AEAD encryption also works with ESP-NOW broadcasts and supports an unlimited number of nodes, which is not true for encrypted connections.
* Encrypted ESP-NOW connections do however come with built in replay attack protection, which is not provided by the framework when using AEAD encryption,
* and allow EspnowProtocolInterpreter::aeadMetadataSize extra message bytes per transmission.
* Transmissions via encrypted connections are also slightly faster than via AEAD once a connection has been established.
*
* useEncryptedMessages() is false by default.
*
* @param useEncryptedMessages If true, AEAD encryption/decryption is enabled. If false, AEAD encryption/decryption is disabled.
*/
static void setUseEncryptedMessages(bool useEncryptedMessages);
static bool useEncryptedMessages();
/**
* Hint: Use String.length() to get the ASCII length of a String.
*
* @return The maximum number of bytes (or ASCII characters) a transmission can contain. Note that non-ASCII characters usually require the space of at least two ASCII characters each.
* @return The maximum number of bytes (or ASCII characters) a transmission can contain.
* Note that non-ASCII characters usually require the space of at least two ASCII characters each.
* Also note that this value will be reduced by EspnowProtocolInterpreter::aeadMetadataSize if useEncryptedMessages() is true.
*/
static uint32_t getMaxMessageBytesPerTransmission();
@ -402,7 +532,9 @@ public:
/**
* Hint: Use String.length() to get the ASCII length of a String.
*
* @return The maximum length in bytes an ASCII message is allowed to be when transmitted/broadcasted by this node. Note that non-ASCII characters usually require at least two bytes each.
* @return The maximum length in bytes an ASCII message is allowed to be when transmitted/broadcasted by this node.
* Note that non-ASCII characters usually require at least two bytes each.
* Also note that this value will be reduced if useEncryptedMessages() is true.
*/
static uint32_t getMaxMessageLength();
@ -506,6 +638,19 @@ public:
void setBroadcastFilter(broadcastFilterType broadcastFilter);
broadcastFilterType getBroadcastFilter();
/**
* Set a function that should be called after each successful ESP-NOW response transmission, just before the response is removed from the waiting list.
* If a particular response is not sent, there will be no function call for it.
* Only the hook of the EspnowMeshBackend instance that is getEspnowRequestManager() will be called.
*
* The hook should return a bool.
* If this return value is true, the response transmission process will continue with the next response in the waiting list.
* If it is false, the response transmission process will stop after removing the just sent response from the waiting list.
* The default responseTransmittedHook always returns true.
*/
void setResponseTransmittedHook(responseTransmittedHookType responseTransmittedHook);
responseTransmittedHookType getResponseTransmittedHook();
/**
* Get the MAC address of the sender of the most recently received ESP-NOW request, response or broadcast to this EspnowMeshBackend instance.
@ -546,11 +691,11 @@ public:
uint8_t *getSenderAPMac(uint8_t *macArray);
/**
* Get whether the ESP-NOW request, response or broadcast which was most recently received by this EspnowMeshBackend instance was encrypted or not.
* Get whether the ESP-NOW request, response or broadcast which was most recently received by this EspnowMeshBackend instance was sent over an encrypted connection or not.
*
* @return If true, the request, response or broadcast was encrypted. If false, it was unencrypted.
* @return If true, the request, response or broadcast was sent over an encrypted connection. If false, the connection was unencrypted.
*/
bool receivedEncryptedMessage();
bool receivedEncryptedTransmission();
/**
* Should be used together with serializeUnencryptedConnection() if the node sends unencrypted transmissions
@ -563,10 +708,10 @@ public:
*/
static bool addUnencryptedConnection(const String &serializedConnectionState);
// Updates connection with current stored encryption key.
// Updates connection with current stored encrypted connection key.
// At least one of the leftmost 32 bits in each of the session keys should be 1, since the key otherwise indicates the connection is unencrypted.
encrypted_connection_status_t addEncryptedConnection(uint8_t *peerStaMac, uint8_t *peerApMac, uint64_t peerSessionKey, uint64_t ownSessionKey);
// Note that the espnowEncryptionKey, espnowEncryptionKok and espnowHashKey are not serialized.
// Note that the espnowEncryptedConnectionKey, espnowEncryptionKok, espnowHashKey and espnowMessageEncryptionKey are not serialized.
// These will be set to the values of the EspnowMeshBackend instance that is adding the serialized encrypted connection.
// @param ignoreDuration Ignores any stored duration serializedConnectionState, guaranteeing that the created connection will be permanent. Returns: ECS_REQUEST_TRANSMISSION_FAILED indicates malformed serializedConnectionState.
encrypted_connection_status_t addEncryptedConnection(const String &serializedConnectionState, bool ignoreDuration = false);
@ -575,7 +720,7 @@ public:
// As with all these methods, changes will only take effect once the requester proves it has the ability to decrypt the session key.
// At least one of the leftmost 32 bits in each of the session keys should be 1, since the key otherwise indicates the connection is unencrypted.
encrypted_connection_status_t addTemporaryEncryptedConnection(uint8_t *peerStaMac, uint8_t *peerApMac, uint64_t peerSessionKey, uint64_t ownSessionKey, uint32_t duration);
// Note that the espnowEncryptionKey, espnowEncryptionKok and espnowHashKey are not serialized.
// Note that the espnowEncryptedConnectionKey, espnowEncryptionKok, espnowHashKey and espnowMessageEncryptionKey are not serialized.
// These will be set to the values of the EspnowMeshBackend instance that is adding the serialized encrypted connection.
// Uses duration argument instead of any stored duration in serializedConnectionState. Returns: ECS_REQUEST_TRANSMISSION_FAILED indicates malformed serializedConnectionState.
encrypted_connection_status_t addTemporaryEncryptedConnection(const String &serializedConnectionState, uint32_t duration);
@ -593,15 +738,17 @@ public:
encrypted_connection_removal_outcome_t requestEncryptedConnectionRemoval(uint8_t *peerMac);
/**
* Set whether this EspnowMeshBackend instance will accept unencrypted ESP-NOW requests or not, when acting as EspnowRequestManager.
* Set whether this EspnowMeshBackend instance will accept ESP-NOW requests from unencrypted connections or not, when acting as EspnowRequestManager.
* When set to false and combined with already existing encrypted connections, this can be used to ensure only encrypted transmissions are processed.
* When set to false it will also make it impossible to send unencrypted requests for encrypted connection to the node,
* When set to false it will also make it impossible to send requests for encrypted connection to the node over an unencrypted connection,
* which can be useful if too many such requests could otherwise be expected.
*
* @param acceptsUnencryptedRequests If and only if true, unencrypted requests will be processed when this EspnowMeshBackend instance is acting as EspnowRequestManager. True by default.
* True by default.
*
* @param acceptsUnverifiedRequests If and only if true, requests from unencrypted connections will be processed when this EspnowMeshBackend instance is acting as EspnowRequestManager.
*/
void setAcceptsUnencryptedRequests(bool acceptsUnencryptedRequests);
bool acceptsUnencryptedRequests();
void setAcceptsUnverifiedRequests(bool acceptsUnverifiedRequests);
bool acceptsUnverifiedRequests();
/**
* Set a soft upper limit on the number of encrypted connections this node can have when receiving encrypted connection requests.
@ -609,12 +756,14 @@ public:
* Each EspnowMeshBackend instance can have a separate value. The value used is that of the current EspnowRequestManager.
* The hard upper limit is 6 encrypted connections, mandated by the ESP-NOW API.
*
* Default is 6.
*
* When a request for encrypted connection is received from a node to which there is no existing permanent encrypted connection,
* and the number of encrypted connections exceeds the soft limit,
* this request will automatically be converted to an autoEncryptionRequest.
* This means it will be a temporary connection with very short duration (with default framework settings).
*
* @param softLimit The new soft limit. Valid values are 0 to 6. Default is 6.
* @param softLimit The new soft limit. Valid values are 0 to 6.
*/
void setEncryptedConnectionsSoftLimit(uint8_t softLimit);
uint8_t encryptedConnectionsSoftLimit();
@ -749,11 +898,11 @@ protected:
void setSenderAPMac(uint8_t *macArray);
/**
* Set whether the most recently received ESP-NOW request, response or broadcast is presented as having been encrypted or not.
* Set whether the most recently received ESP-NOW request, response or broadcast is presented as having been sent over an encrypted connection or not
*
* @param receivedEncryptedMessage If true, the request, response or broadcast is presented as having been encrypted.
* @param receivedEncryptedTransmission If true, the request, response or broadcast is presented as having been sent over an encrypted connection.
*/
void setReceivedEncryptedMessage(bool receivedEncryptedMessage);
void setReceivedEncryptedTransmission(bool receivedEncryptedTransmission);
static bool temporaryEncryptedConnectionToPermanent(uint8_t *peerMac);
@ -767,6 +916,11 @@ protected:
*/
static bool _espnowConnectionQueueMutex;
/**
* Will be true when no responsesToSend element should be removed.
*/
static bool _responsesToSendMutex;
/**
* Check if there is an ongoing ESP-NOW transmission in the library. Used to avoid interrupting transmissions.
*
@ -814,6 +968,9 @@ protected:
private:
EspnowMeshBackend(requestHandlerType requestHandler, responseHandlerType responseHandler, networkFilterType networkFilter, broadcastFilterType broadcastFilter,
const String &meshPassword, const String &ssidPrefix, const String &ssidSuffix, bool verboseMode, uint8 meshWiFiChannel);
typedef std::function<String(const String &, const ExpiringTimeTracker &)> encryptionRequestBuilderType;
static String defaultEncryptionRequestBuilder(const String &requestHeader, const uint32_t durationMs, const uint8_t *hashKey, const String &requestNonce, const ExpiringTimeTracker &existingTimeTracker);
static String flexibleEncryptionRequestBuilder(const uint32_t minDurationMs, const uint8_t *hashKey, const String &requestNonce, const ExpiringTimeTracker &existingTimeTracker);
@ -908,6 +1065,7 @@ private:
static bool _espnowSendConfirmed;
broadcastFilterType _broadcastFilter;
responseTransmittedHookType _responseTransmittedHook = [](const String &, const uint8_t *, uint32_t, EspnowMeshBackend &){ return true; };
uint8_t _broadcastTransmissionRedundancy = 1;
@ -923,17 +1081,19 @@ private:
static bool usesConstantSessionKey(char messageType);
bool _acceptsUnencryptedRequests = true;
bool _acceptsUnverifiedRequests = true;
uint8_t _espnowEncryptionKey[EspnowProtocolInterpreter::espnowEncryptionKeyLength] {0};
uint8_t _espnowEncryptedConnectionKey[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength] {0};
uint8_t _espnowHashKey[EspnowProtocolInterpreter::espnowHashKeyLength] {0};
static uint8_t _espnowEncryptionKok[EspnowProtocolInterpreter::espnowEncryptionKeyLength];
static uint8_t _espnowEncryptionKok[EspnowProtocolInterpreter::espnowEncryptedConnectionKeyLength];
static bool _espnowEncryptionKokSet;
static uint32_t _unencryptedMessageID;
static uint8_t _espnowMessageEncryptionKey[CryptoInterface::ENCRYPTION_KEY_LENGTH];
static bool _useEncryptedMessages;
static uint32_t _unsynchronizedMessageID;
uint8_t _senderMac[6] = {0};
uint8_t _senderAPMac[6] = {0};
bool _receivedEncryptedMessage = false;
bool _receivedEncryptedTransmission = false;
static bool _espnowSendToNodeMutex;
static uint8_t _transmissionTargetBSSID[6];