diff --git a/platformio.ini b/platformio.ini index ed5118c2..bdbdcab9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -342,6 +342,7 @@ build_flags = -D RADIO_CLASS=CustomSX1276 -D WRAPPER_CLASS=CustomSX1276Wrapper -D LORA_TX_POWER=20 + -D USE_ESP32_ENCRYPTION=true ; ============= [LilyGo_T3S3_sx1262] @@ -376,11 +377,9 @@ build_flags = -D ADVERT_LAT=-37.0 -D ADVERT_LON=145.0 -D ADMIN_PASSWORD="\"password\"" - -D MESH_PACKET_LOGGING=1 - -D MESH_DEBUG=1 - -D CORE_DEBUG_LEVEL=3 - -D SPI_MAX_DMA_LEN=1024 - -D BLE_TASK_SIZE=4096 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +; -D CORE_DEBUG_LEVEL=3 [env:LilyGo_T3_sx1276_terminal_chat] extends = LilyGo_T3_sx1276 @@ -417,7 +416,7 @@ build_flags = -D MAX_CONTACTS=100 -D MAX_GROUP_CHANNELS=1 -D BLE_PIN_CODE=123456 - -D BLE_DEBUG_LOGGING=1 +; -D BLE_DEBUG_LOGGING=1 ; -D ENABLE_PRIVATE_KEY_IMPORT=1 ; -D ENABLE_PRIVATE_KEY_EXPORT=1 ; -D MESH_PACKET_LOGGING=1 diff --git a/src/Identity.cpp b/src/Identity.cpp index e7c57d7e..aa035856 100644 --- a/src/Identity.cpp +++ b/src/Identity.cpp @@ -3,6 +3,11 @@ #define ED25519_NO_SEED 1 #include +// For ESP32, we use libsodium for cryptographic operations to reduce stack usage +#ifdef USE_ESP32_ENCRYPTION +#include +#endif + namespace mesh { Identity::Identity() { @@ -14,7 +19,14 @@ Identity::Identity(const char* pub_hex) { } bool Identity::verify(const uint8_t* sig, const uint8_t* message, int msg_len) const { - return ed25519_verify(sig, message, msg_len, pub_key); + #ifdef USE_ESP32_ENCRYPTION + // Using libsodium for verification on ESP32 to reduce stack usage + // This function performs signature verification with much lower stack requirements + // than the default implementation + return crypto_sign_ed25519_verify_detached(sig, message, msg_len, pub_key) == 0; + #else + return ed25519_verify(sig, message, msg_len, pub_key); + #endif } bool Identity::readFrom(Stream& s) { @@ -32,6 +44,7 @@ void Identity::printTo(Stream& s) const { LocalIdentity::LocalIdentity() { memset(prv_key, 0, sizeof(prv_key)); } + LocalIdentity::LocalIdentity(const char* prv_hex, const char* pub_hex) : Identity(pub_hex) { Utils::fromHex(prv_key, PRV_KEY_SIZE, prv_hex); } @@ -39,7 +52,21 @@ LocalIdentity::LocalIdentity(const char* prv_hex, const char* pub_hex) : Identit LocalIdentity::LocalIdentity(RNG* rng) { uint8_t seed[SEED_SIZE]; rng->random(seed, SEED_SIZE); - ed25519_create_keypair(pub_key, prv_key, seed); + + #ifdef USE_ESP32_ENCRYPTION + // Use libsodium for keypair generation on ESP32 to reduce stack usage + // NOTE: Format differences between implementations: + // - The current ed25519 implementation (orlp/ed25519) uses a 64-byte private key format + // - Libsodium also uses a 64-byte format for Ed25519 secret keys, where: + // * First 32 bytes: the actual private key seed + // * Last 32 bytes: the corresponding public key + + // Generate keypair using libsodium with the provided seed + // This avoids the deep stack usage of the default implementation + crypto_sign_ed25519_seed_keypair(pub_key, prv_key, seed); + #else + ed25519_create_keypair(pub_key, prv_key, seed); + #endif } bool LocalIdentity::readFrom(Stream& s) { @@ -77,17 +104,51 @@ void LocalIdentity::readFrom(const uint8_t* src, size_t len) { memcpy(pub_key, &src[PRV_KEY_SIZE], PUB_KEY_SIZE); } else if (len == PRV_KEY_SIZE) { memcpy(prv_key, src, PRV_KEY_SIZE); - // now need to re-calculate the pub_key - ed25519_derive_pub(pub_key, prv_key); + + #ifdef USE_ESP32_ENCRYPTION + // In libsodium, the private key already contains the public key in its last 32 bytes + // We can just extract it directly, avoiding the expensive derivation calculation + // This significantly reduces stack usage on ESP32 + memcpy(pub_key, prv_key + 32, 32); + #else + // now need to re-calculate the pub_key + ed25519_derive_pub(pub_key, prv_key); + #endif } } void LocalIdentity::sign(uint8_t* sig, const uint8_t* message, int msg_len) const { - ed25519_sign(sig, message, msg_len, pub_key, prv_key); + #ifdef USE_ESP32_ENCRYPTION + // Use libsodium for signing on ESP32 to reduce stack usage + // The libsodium implementation uses less stack space than the default ed25519 implementation + crypto_sign_ed25519_detached(sig, NULL, message, msg_len, prv_key); + #else + ed25519_sign(sig, message, msg_len, pub_key, prv_key); + #endif } void LocalIdentity::calcSharedSecret(uint8_t* secret, const uint8_t* other_pub_key) { - ed25519_key_exchange(secret, other_pub_key, prv_key); + #ifdef USE_ESP32_ENCRYPTION + // NOTE: To calculate a shared secret with Ed25519 keys and libsodium, we need to: + // 1. Convert the Ed25519 keys to Curve25519 (X25519) format + // 2. Perform the key exchange using the converted keys + // + // The default implementation handles this conversion internally, + // but with libsodium we need to do these steps explicitly. + // This approach uses less stack space compared to the original implementation. + + unsigned char x25519_pk[crypto_scalarmult_curve25519_BYTES]; + unsigned char x25519_sk[crypto_scalarmult_curve25519_BYTES]; + + // Convert Ed25519 keys to Curve25519 keys for ECDH + crypto_sign_ed25519_pk_to_curve25519(x25519_pk, other_pub_key); + crypto_sign_ed25519_sk_to_curve25519(x25519_sk, prv_key); + + // Calculate shared secret using X25519 + crypto_scalarmult_curve25519(secret, x25519_sk, x25519_pk); + #else + ed25519_key_exchange(secret, other_pub_key, prv_key); + #endif } } \ No newline at end of file