HF-TMC51x0 Driver (TMC5130 & TMC5160) 0.1.0-dev
Hardware Agnostic C++ Driver for the TMC51x0 (TMC5130 & TMC5160)
Loading...
Searching...
No Matches
espnow_security.hpp File Reference

ESP-NOW security and pairing protocol definitions. More...

#include <cstdint>
#include <cstdio>
#include <cstring>
#include "esp_random.h"
#include "mbedtls/md.h"
Include dependency graph for espnow_security.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  PairingRequestPayload
 Pairing request payload - sent by initiator (broadcast). More...
 
struct  PairingResponsePayload
 Pairing response payload - sent by responder (unicast). More...
 
struct  PairingConfirmPayload
 Pairing confirmation payload - sent by initiator to complete. More...
 
struct  PairingRejectPayload
 Pairing rejection payload. More...
 
struct  ApprovedPeer
 Information about an approved (paired) peer. More...
 
struct  SecuritySettings
 Security settings stored in NVS. More...
 

Namespaces

namespace  PairingSecretParser
 Compile-time hex string to byte array parser.
 
namespace  PairingMsgType
 Security/Pairing message type values.
 

Macros

#define ESPNOW_PAIRING_SECRET_HEX   "00000000deadbeefcafebabedeadbeef"
 

Enumerations

enum class  DeviceType : uint8_t { Unknown = 0 , RemoteController = 1 , FatigueTester = 2 }
 Device type identifiers for mutual verification. More...
 
enum class  PairingRejectReason : uint8_t {
  NotInPairingMode = 0 , WrongDeviceType = 1 , HmacFailed = 2 , AlreadyPaired = 3 ,
  ProtocolMismatch = 4
}
 

Functions

constexpr uint8_t PairingSecretParser::HexCharToNibble (char c) noexcept
 Convert a single hex character to its numeric value (0-15)
 
constexpr uint8_t PairingSecretParser::HexByte (const char *s, size_t i) noexcept
 Convert two hex characters at position i*2 to a single byte.
 
void ComputePairingHmac (const uint8_t *challenge, size_t challenge_len, uint8_t out[HMAC_SIZE]) noexcept
 Compute HMAC-SHA256, truncated to HMAC_SIZE bytes.
 
bool VerifyPairingHmac (const uint8_t *challenge, size_t challenge_len, const uint8_t received_hmac[HMAC_SIZE]) noexcept
 Verify an HMAC response using constant-time comparison.
 
void GenerateChallenge (uint8_t out[CHALLENGE_SIZE]) noexcept
 Generate a random challenge nonce.
 
bool IsZeroMac (const uint8_t mac[6]) noexcept
 Check if a MAC address is all zeros.
 
bool IsBroadcastMac (const uint8_t mac[6]) noexcept
 Check if a MAC address is the broadcast address.
 
bool MacEquals (const uint8_t a[6], const uint8_t b[6]) noexcept
 Compare two MAC addresses.
 
void FormatMac (const uint8_t mac[6], char *out, size_t out_size) noexcept
 Format MAC address to string buffer (needs 18 bytes: XX:XX:XX:XX:XX:XX\0)
 

Variables

static constexpr uint8_t PAIRING_SECRET [16]
 Pre-shared pairing secret (16 bytes).
 
static constexpr size_t CHALLENGE_SIZE = 8
 Challenge nonce size in bytes.
 
static constexpr size_t HMAC_SIZE = 16
 HMAC output size (truncated SHA-256)
 
static constexpr size_t MAX_APPROVED_PEERS = 4
 Maximum number of approved peers to store in NVS.
 
static constexpr size_t MAX_DEVICE_NAME_LEN = 16
 Maximum device name length.
 
static constexpr uint32_t PAIRING_MODE_TIMEOUT_SEC = 30
 Pairing mode timeout in seconds (default)
 
static constexpr uint32_t PAIRING_RESPONSE_TIMEOUT_MS = 10000
 Pairing response timeout in milliseconds.
 
static constexpr uint8_t BROADCAST_MAC [6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
 Broadcast MAC address for discovery.
 
static constexpr uint8_t PairingMsgType::PairingRequest = 20
 Initiate pairing (broadcast)
 
static constexpr uint8_t PairingMsgType::PairingResponse = 21
 Response with HMAC proof.
 
static constexpr uint8_t PairingMsgType::PairingConfirm = 22
 Final confirmation.
 
static constexpr uint8_t PairingMsgType::PairingReject = 23
 Explicit rejection.
 
static constexpr uint8_t PairingMsgType::Unpair = 24
 Remove a paired device.
 

Detailed Description

ESP-NOW security and pairing protocol definitions.

This header defines the secure pairing mechanism for ESP-NOW communication. Both the remote controller and test unit must share this file for protocol compatibility.

Security Model:

  • Pre-shared pairing secret compiled into both devices
  • Challenge-response HMAC for mutual authentication
  • Explicit pairing mode required (device must be put in pairing mode)
  • Approved peers stored in NVS for persistence
  • All non-pairing messages validated against approved peer list

Backward Compatibility:

  • Pre-configured MAC addresses (hardcoded) are always trusted
  • Pairing is an additional feature, not a replacement

Macro Definition Documentation

◆ ESPNOW_PAIRING_SECRET_HEX

#define ESPNOW_PAIRING_SECRET_HEX   "00000000deadbeefcafebabedeadbeef"

Enumeration Type Documentation

◆ DeviceType

enum class DeviceType : uint8_t
strong

Device type identifiers for mutual verification.

During pairing, devices verify they're connecting to the expected type.

Enumerator
Unknown 
RemoteController 

UI board / M5Dial remote controller.

FatigueTester 

Fatigue test unit.

◆ PairingRejectReason

enum class PairingRejectReason : uint8_t
strong
Enumerator
NotInPairingMode 

Device not in pairing mode.

WrongDeviceType 

Requester looking for wrong device type.

HmacFailed 

HMAC verification failed.

AlreadyPaired 

Already paired (peer list full)

ProtocolMismatch 

Protocol version mismatch.

Function Documentation

◆ ComputePairingHmac()

void ComputePairingHmac ( const uint8_t * challenge,
size_t challenge_len,
uint8_t out[HMAC_SIZE] )
inlinenoexcept

Compute HMAC-SHA256, truncated to HMAC_SIZE bytes.

Parameters
challengeThe challenge nonce to authenticate
challenge_lenLength of challenge in bytes
outOutput buffer (must be at least HMAC_SIZE bytes)
Here is the caller graph for this function:

◆ FormatMac()

void FormatMac ( const uint8_t mac[6],
char * out,
size_t out_size )
inlinenoexcept

Format MAC address to string buffer (needs 18 bytes: XX:XX:XX:XX:XX:XX\0)

◆ GenerateChallenge()

void GenerateChallenge ( uint8_t out[CHALLENGE_SIZE])
inlinenoexcept

Generate a random challenge nonce.

Parameters
outOutput buffer (must be at least CHALLENGE_SIZE bytes)
Here is the caller graph for this function:

◆ IsBroadcastMac()

bool IsBroadcastMac ( const uint8_t mac[6])
inlinenoexcept

Check if a MAC address is the broadcast address.

◆ IsZeroMac()

bool IsZeroMac ( const uint8_t mac[6])
inlinenoexcept

Check if a MAC address is all zeros.

Here is the caller graph for this function:

◆ MacEquals()

bool MacEquals ( const uint8_t a[6],
const uint8_t b[6] )
inlinenoexcept

Compare two MAC addresses.

Here is the caller graph for this function:

◆ VerifyPairingHmac()

bool VerifyPairingHmac ( const uint8_t * challenge,
size_t challenge_len,
const uint8_t received_hmac[HMAC_SIZE] )
inlinenoexcept

Verify an HMAC response using constant-time comparison.

Parameters
challengeThe challenge that was sent
challenge_lenLength of challenge in bytes
received_hmacThe HMAC response to verify
Returns
true if HMAC matches (peer knows the secret)
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ BROADCAST_MAC

constexpr uint8_t BROADCAST_MAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
staticconstexpr

Broadcast MAC address for discovery.

◆ CHALLENGE_SIZE

constexpr size_t CHALLENGE_SIZE = 8
staticconstexpr

Challenge nonce size in bytes.

◆ HMAC_SIZE

constexpr size_t HMAC_SIZE = 16
staticconstexpr

HMAC output size (truncated SHA-256)

◆ MAX_APPROVED_PEERS

constexpr size_t MAX_APPROVED_PEERS = 4
staticconstexpr

Maximum number of approved peers to store in NVS.

◆ MAX_DEVICE_NAME_LEN

constexpr size_t MAX_DEVICE_NAME_LEN = 16
staticconstexpr

Maximum device name length.

◆ PAIRING_MODE_TIMEOUT_SEC

constexpr uint32_t PAIRING_MODE_TIMEOUT_SEC = 30
staticconstexpr

Pairing mode timeout in seconds (default)

◆ PAIRING_RESPONSE_TIMEOUT_MS

constexpr uint32_t PAIRING_RESPONSE_TIMEOUT_MS = 10000
staticconstexpr

Pairing response timeout in milliseconds.

◆ PAIRING_SECRET

constexpr uint8_t PAIRING_SECRET[16]
staticconstexpr
Initial value:

Pre-shared pairing secret (16 bytes).

This secret is parsed from ESPNOW_PAIRING_SECRET_HEX at compile time. All devices in the same deployment must use the same secret.

Note
Configure via secrets.local.yml or environment variable.
See also
secrets.template.yml for configuration instructions.