Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESPNow: Encryption not working #415

Open
toi-go opened this issue Apr 24, 2022 · 4 comments
Open

ESPNow: Encryption not working #415

toi-go opened this issue Apr 24, 2022 · 4 comments
Labels

Comments

@toi-go
Copy link

toi-go commented Apr 24, 2022

Documentation at https://github.com/gioblu/PJON/blob/master/src/strategies/ESPNOW/README.md suggests that communication would be encrypted if a PMK is passed to the set_pmk method:

void setup() {
  // Note PMK is 16 bytes, to store it in a char use char[17] or add an extra byte for the null terminator
  char pmk[17] = "\x2b\xb2\x1e\x7a\x83\x13\x76\x9f\xf8\xa9\x3b\x1b\x5b\x52\xd0\x70";
  PJON<ESPNOW> bus(44);

  bus.strategy.set_channel(6);
  bus.strategy.set_pmk(pmk);
}

For me, this is not the case: My two nodes are still able to communicate with each other even if both nodes do the above with a different PMK or if only one of them does set a PMK.

Apparently, add_peer in ESPNOWHelper.h does not set the encrypt flag:

    memset(peer, 0, sizeof(esp_now_peer_info_t));
    peer->channel = _channel;
    peer->ifidx = ESPNOW_WIFI_IF;
    if(IS_BROADCAST_ADDR(mac_addr))
      peer->encrypt = false;
    // else {
    //   peer->encrypt = true;
    //   memcpy(peer->lmk, _esp_pmk, 16);
    // }
    memcpy(peer->peer_addr, mac_addr, ESP_NOW_ETH_ALEN);
    ESP_ERROR_CHECK(esp_now_add_peer(peer));
@gioblu
Copy link
Owner

gioblu commented Apr 25, 2022

Ciao @toi-go thank you very much, this is bad. I will fix it ASAP.
Could you provide with testing? I am now far from my electronics stash.

@gioblu
Copy link
Owner

gioblu commented Apr 25, 2022

Here is the fix: 5f790b3
If you can give it a try.

@toi-go
Copy link
Author

toi-go commented Apr 30, 2022

Hi @gioblu ,

thank you for providing the patch. Unfortunately, with it, my two ESP32 cannot communicate with each other - no matter if I call bus.strategy.set_pmk or not. So, there must be another problem.

To test, I've used the ping example at examples/ESP32/ESPNOW/PlatformIO.
My setup() functions looks like this:

void setup()
{
  Serial.begin(115200);
  Serial.println("Receiver started.");

  // Note PMK is 16 bytes, to store it in a char use char[17] or add an extra byte for the null terminator
  char pmk[17] = "\x2b\xb2\x1e\x7a\x83\x13\x76\x9f\xf8\xa9\x3b\x1b\x5b\x52\xd0\x70";

  bus.strategy.set_channel(6);
  bus.strategy.set_pmk(pmk);

  bus.set_receiver(receiver_function);
  bus.begin();
};
void setup()
{
  Serial.begin(115200);
  Serial.println("Transmitter started.");

  // Note PMK is 16 bytes, to store it in a char use char[17] or add an extra byte for the null terminator
  char pmk[17] = "\x2b\xb2\x1e\x7a\x83\x13\x76\x9f\xf8\xa9\x3b\x1b\x5b\x52\xd0\x70";

  bus.strategy.set_channel(6);
  bus.strategy.set_pmk(pmk);

  bus.set_receiver(receiver_function);
  bus.begin();
  bus.send_repeatedly(44, "P", 1, 100000); // Send P to device 44 10 times per second
};

@toi-go
Copy link
Author

toi-go commented Apr 30, 2022

@gioblu

It seems that the remaining problem is somehow related to autoregistration mode, as it works if it is disabled.

  // Note PMK is 16 bytes, to store it in a char use char[17] or add an extra byte for the null terminator
  char pmk[17] = "\x2b\xb2\x1e\x7a\x83\x13\x76\x9f\xf8\xa9\x3b\x1b\x5b\x52\xd0\x70";

  bus.strategy.set_autoregistration(false);
  bus.strategy.set_channel(6);
  bus.strategy.set_pmk(pmk);

  bus.set_receiver(receiver_function);
  bus.begin();

  uint8_t dev_mac[6] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x11 };  // MAC address of the remote node.
  bus.strategy.add_node(44, dev_mac);

  bus.send_repeatedly(44, "P", 1, 100000); // Send P to device 44 10 times per second

If you register remote nodes manually, you have to use the MAC address of the interface (AP or Station) which is actually in use (depending on CONFIG_STATION_MODE):

From ESPNOWHelper.h

/* ESPNOW can work in both station and softap mode.
   It is configured in menuconfig. */
#if CONFIG_STATION_MODE
  #define ESPNOW_WIFI_MODE WIFI_MODE_STA
  #define ESPNOW_WIFI_IF ESP_IF_WIFI_STA
#else
  #define ESPNOW_WIFI_MODE WIFI_MODE_AP
  #define ESPNOW_WIFI_IF ESP_IF_WIFI_AP
#endif

In my case, CONFIG_STATION_MODE was not defined, so I had to use the MAC address of the AP interface.

To determine the MAC address, I used the following code:

  Serial.println("ESP Board MAC Address:  ");
  #if CONFIG_STATION_MODE
  WiFi.mode(WIFI_MODE_STA);
  Serial.print(" Station interface: ");
  Serial.println(WiFi.macAddress());
  #else
  WiFi.mode(WIFI_MODE_AP);
  Serial.print(" AP interface: ");
  Serial.println(WiFi.softAPmacAddress());
  #endif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants