🛡️ Sentinel: [CRITICAL] Timing Attack on Static Public Key Comparison#56
🛡️ Sentinel: [CRITICAL] Timing Attack on Static Public Key Comparison#56
Conversation
Replaced `std.mem.eql` with `std.crypto.timing_safe.eql` in the Noise handshake (`consumeInitiation` and `consumeInitiationFast`) when comparing the decrypted initiator static public key with the expected remote peer static public key. This mitigates a timing side-channel that could potentially leak information about expected public keys within the cryptographic state machine. Co-authored-by: igorls <4753812+igorls@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Pull request overview
This PR addresses a timing-attack vulnerability in the WireGuard Noise protocol handshake implementation. Two public key comparisons in consumeInitiation and consumeInitiationFast were using std.mem.eql, which short-circuits on the first mismatched byte, potentially leaking timing information about the expected peer's public key. The fix replaces these with std.crypto.timing_safe.eql, consistent with how MAC1 comparisons are already handled in the same file.
Changes:
- Replaced
std.mem.eqlwithstd.crypto.timing_safe.eql([32]u8, ...)in the two public key verification sites innoise.zig - Added
SECURITY:doc comments explaining the rationale at each changed site - Logged the finding and fix in
.jules/sentinel.md
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/wireguard/noise.zig |
Replaced non-constant-time std.mem.eql with std.crypto.timing_safe.eql for static public key identity checks in both consumeInitiation and consumeInitiationFast |
.jules/sentinel.md |
Added audit log entry documenting the vulnerability, the learning, and the prevention strategy |
One issue was found:
The date recorded in the new sentinel.md entry (2026-10-25) is approximately 8 months in the future. It should reflect the actual date the fix was made.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Closing: superseded by docs audit fixes and direct commits to main. See PR #67 (merged) for codec bounds check, and direct commit for timing-safe fix in noise.zig. |
Understood. Acknowledging that this PR has been superseded and closed. I will stop work on this task. |
🛡️ Sentinel: [CRITICAL] Timing Attack on Static Public Key Comparison
Vulnerability:
In
src/wireguard/noise.zig, theconsumeInitiationandconsumeInitiationFastfunctions usedstd.mem.eqlto verify the decrypted initiator's static public key against the expected remote peer's static public key.std.mem.eqlterminates early on the first mismatched byte, exposing a timing oracle. An attacker could potentially use this side-channel to glean information about expected public keys within the Noise protocol state machine.Fix:
Replaced
std.mem.eqlwithstd.crypto.timing_safe.eql([32]u8, ...)to ensure the comparison executes in constant time, eliminating the timing side-channel. AddedSECURITYdoc comments explaining the reasoning.Verification:
zig buildpasses.zig build testpasses.zig build -Doptimize=ReleaseSafepasses..jules/sentinel.md.PR created automatically by Jules for task 9138395867358392351 started by @igorls