feat: Add optional Perfect Forward Secrecy for direct messages#9116
Open
krisclarkdev wants to merge 38 commits into
Open
feat: Add optional Perfect Forward Secrecy for direct messages#9116krisclarkdev wants to merge 38 commits into
krisclarkdev wants to merge 38 commits into
Conversation
- BinarySemaphorePosix: Replace delay() stub with pthread_cond_timedwait - doLightSleep: Add 30 second default parameter, matching THIRTY_SECONDS_MS - main_matrix.yml: Fetch branches before merge-base to fix shame job failure
Replace FreeRTOS-specific pdTRUE macro with literal 1 for compatibility with native/POSIX builds that don't have FreeRTOS headers.
- Create PhoneAPIModule to handle packet delivery to phone/API clients - Move phone delivery logic from RoutingModule to dedicated module - Add PhoneAPIModule as friend class to MeshService for handleFromRadio access - Update ESP-IDF deprecation comment to note existing version-conditional handling - Register PhoneAPIModule in Modules.cpp
Reverting meshtastic#6 (PhoneAPIModule) due to concerns about behavioral changes. Keeping meshtastic#8 (ESP-IDF deprecation comment fix) which is safe.
- Add ARCH_PORTDUINO guard to use pthread only on Linux/native - Keep stub implementation for STM32 and other non-POSIX platforms - Fixes CI failure on rak3172 build
Use origin/ prefix for both base and head branches in git merge-base. The branches are fetched as remote refs, not local branches.
The gh run download command does not support --commit flag. Changed to use gh run list --commit to find the run ID first, then download using that run ID. Added fallback for cases where no workflow run exists for the merge base commit.
Fixes 'Not a valid object name' error by: 1. Adding explicit git fetch of base branch before merge-base 2. Using gh run list to find valid run ID before download 3. Adding graceful fallback when no previous artifacts exist
Adds ephemeral key exchange using Triple-DH for forward secrecy when both nodes support it. Falls back to standard PKI encryption for compatibility with stock firmware. Key features: - EphemeralKeyManager: generates/rotates Curve25519 ephemeral key pairs - Triple-DH session key derivation for mutual auth + forward secrecy - Key rotation after 100 messages or 24 hours - LRU cache for remote ephemeral keys (32 entries) - Persistence to flash with checksum validation - Graceful fallback to legacy PKI if PFS unavailable
bc272b4 to
d55417f
Compare
Author
|
I have tested that my proposed changes behave as described. I have tested that my proposed changes do not cause any obvious regressions on the following devices: |
Jorropo
added a commit
to Jorropo/firmware
that referenced
this pull request
Jan 2, 2026
The previous setup would be extremely lenient. AFAIK would basically only enforce tabulation more or less. Add a .clang-format file, the point is you can't accidently have whitespace changes. See meshtastic#9116 for what sitatuation we are in before this patch. The point is there is a single valid way to format the file, and running trunk fmt -a will bring you to it.
Jorropo
added a commit
to Jorropo/firmware
that referenced
this pull request
Jan 2, 2026
The previous setup would be extremely lenient. AFAIK would basically only enforce tabulation more or less. Add a .clang-format file, the point is you can't accidently have whitespace changes. See meshtastic#9116 for what sitatuation we are in before this patch. The point is there is a single valid way to format the file, and running trunk fmt -a will bring you to it.
Jorropo
added a commit
to Jorropo/firmware
that referenced
this pull request
Jan 2, 2026
The previous setup would be extremely lenient. AFAIK would basically only enforce tabulation more or less. Add a .clang-format file, the point is you can't accidently have whitespace changes. See meshtastic#9116 for what sitatuation we are in before this patch. The point is there is a single valid way to format the file, and running trunk fmt -a will bring you to it.
Jorropo
added a commit
to Jorropo/firmware
that referenced
this pull request
Jan 3, 2026
The previous setup would be extremely lenient. AFAIK would basically only enforce tabulation more or less. Add a .clang-format file, the point is you can't accidently have whitespace changes. See meshtastic#9116 for what sitatuation we are in before this patch. The point is there is a single valid way to format the file, and running trunk fmt -a will bring you to it.
Jorropo
added a commit
to Jorropo/firmware
that referenced
this pull request
Jan 3, 2026
The previous setup would be extremely lenient. AFAIK would basically only enforce tabulation more or less. Add a .clang-format file, the point is you can't accidently have whitespace changes. See meshtastic#9116 for what sitatuation we are in before this patch. The point is there is a single valid way to format the file, and running trunk fmt -a will bring you to it.
…ad of symmetric derivation
- Accept upstream for: .gitignore, AdminModule.cpp, sleep.cpp, protobufs - Keep ours for: Router.cpp (PFS decrypt/encode logic), main.cpp (PFS init) - Surgical merge for CryptoEngine.cpp: kept clearKeys(), PFS Triple-DH functions, and adopted upstream smart pointer (unique_ptr) refactoring for aesSetKey and encryptAESCtr
- Remove non-existent Led.h and RAKled.h includes - Remove ledBlinker() and ledPeriodic (replaced by StatusLEDThread in upstream) - Restore RadioInterface *rIf = NULL global - Add missing upstream includes: RadioLibInterface.h, TransmitHistory.h, power/PowerHAL.h, MessageStore.h (HAS_SCREEN) - Add clearKeys() declaration to CryptoEngine.h to match .cpp definition - Remove ARCH_PORTDUINO guard from RadioLibHAL (now always global)
- Remove duplicate UserButtonThread definition (canonical in InputBroker.cpp) - Remove duplicate radioType definition (canonical in RadioInterface.cpp) - Fix router->addInterface() to use unique_ptr<RadioInterface> (upstream API change) - Capture getPacketTime() before ownership transfer to avoid null dereference
- QMC6310 -> QMC6310U + QMC6310N (enum has two variants, not a bare QMC6310) - PMSA0031 -> PMSA003I (typo: trailing digit '1' should be letter 'I')
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds optional Perfect Forward Secrecy (PFS) for direct messages using ephemeral Curve25519 key exchange.
Fully backward compatible - nodes running this code can still communicate with stock firmware.
How It Works
Each node generates an ephemeral keypair at boot. When two nodes both support PFS, messages between them use Triple-DH key derivation:
This provides mutual authentication and forward secrecy.
Key Features
Files Changed
src/mesh/EphemeralKeyManager.h/.cpp- New ephemeral key managersrc/mesh/CryptoEngine.h/.cpp- Triple-DH and PFS encrypt/decryptsrc/mesh/Router.cpp- PFS integration in encode/decode pathssrc/main.cpp- EphemeralKeyManager initializationBuild Status
Tested on tbeam (ESP32) - 95.8% flash usage. Compiles clean.
Testing Needed
I only have one device currently. Would appreciate community testing:
-D PFS_TEST_MODEfor 5-message rotation)