You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Move the QUIC and TLS key-holding structs onto nish:secret #430
nish/net/quic-packet's QuicKeys (key, IV and header-protection key) and nish/net/tls's traffic secrets are held as plain u8[] and are never wiped. QUIC-1 in docs/security/quic.md and TLS-1 in docs/security/tls.md record this.
Since #418, nish:secret is available to std/, and CLAUDE.md asks that secret material be a Secret that is wiped. These modules cannot simply retype their fields, because a Secret may not be a struct field (NL2430). Adopting it means redesigning the key API: keys passed and returned as Secret<u8[]> and computed on inside expose, rather than stored in a struct across calls. QUIC connections (Q2a/Q2b in #395) and the TLS record layer (T2) consume that API, so the redesign should land before Q2's connection keys ship.
Done when QUIC-1 and TLS-1 are closed, or narrowed to what a wipe cannot reach, with a test that pins the wipes under -O2.
Scope check against the records on main at d43ba05. Besides QUIC-1 and TLS-1, three more open findings name this issue as their follow-up, so this issue covers them too:
TLS-2 (std/net/tls/record.ts, TlsRecordProtection): a direction's key, IV and AES key schedule live in fields. The key and IV are wiped with secureZero, but the schedule is zeroed only by ordinary stores.
QUIC-2 (std/net/quic.ts, each level's QuicConnSpace): a connection keeps every level's QuicKeys between calls.
QUIC-5 (QuicServerConfig, QuicListener): the stateless-reset key and the Retry token key are plain fields of the caller's config.
HMAC and HKDF taking Secret keys and wiping their own state is filed separately as #476. The derivations here run through them, so the two should land in a compatible order.
Open, narrowed: TLS-1 and QUIC-1. Each remainder is key material held in a class field, where a Secret may not be stored (NL2430). Those bytes are still volatile-wiped at every end of life; what's missing is the checker's compile-time guarantees.
This issue stays open until #668, which lets a Secret be a field, closes TLS-1 and QUIC-1.
Closing as completed, at the owner's confirmation. The two findings #430's run left Open, narrowed, TLS-1 and QUIC-1, are now Closed by the secret-fields run (#674, plan #668):
QuicConnection holds its traffic secrets in Secret fields, and quicKeys/quicKeysUpdate write into a caller's slot. This closes QUIC-1, and #668 is fixed.
Acceptance on main @ 27f86d9 is recorded on #674. On it, npm test passes 21,322 with 0 failed, wasi, performance and bootstrap --verify are green, and each TLS and QUIC secret is read back as zero at each end of life.
What stays plain, and why, is recorded in docs/security/tls.md and quic.md:
per-record keys (NL2448/NL2450);
the transient install and KeyUpdate clone;
the QUIC reset and config keys, which are not yet held in Secret fields.
Activity
docs(security): link QUIC-1's follow-up to #430, and recount the inde…
docs(std): name #430 as the follow-up for the TLS key-holding structs
feat(std): nish/net/quic-packet — QUIC packets, Initial secrets and h…
amritk commentedon Oct 6, 2026
Scope check against the records on
mainat d43ba05. Besides QUIC-1 and TLS-1, three more open findings name this issue as their follow-up, so this issue covers them too:std/net/tls/record.ts,TlsRecordProtection): a direction's key, IV and AES key schedule live in fields. The key and IV are wiped withsecureZero, but the schedule is zeroed only by ordinary stores.std/net/quic.ts, each level'sQuicConnSpace): a connection keeps every level'sQuicKeysbetween calls.QuicServerConfig,QuicListener): the stateless-reset key and the Retry token key are plain fields of the caller's config.HMAC and HKDF taking
Secretkeys and wiping their own state is filed separately as #476. The derivations here run through them, so the two should land in a compatible order.Generated by Claude Code
feat(crypto): run Wycheproof for HMAC and HKDF, and wipe their state (#…
docs: record the issue-sweep-2 review lessons and correct two stale r…
docs: record the issue-sweep-2 review lessons and correct two stale r…
docs(plan): stage #430's move of TLS and QUIC keys onto nish:secret
amritk commentedon Oct 16, 2026
Status after the #626 run: all five stages are merged.
SecretSecretmay not be stored (NL2430). Those bytes are still volatile-wiped at every end of life; what's missing is the checker's compile-time guarantees.This issue stays open until #668, which lets a
Secretbe a field, closes TLS-1 and QUIC-1.Generated by Claude Code
docs(plan): stage #668's Secret fields
amritk commentedon Oct 19, 2026
Closing as completed, at the owner's confirmation. The two findings #430's run left Open, narrowed, TLS-1 and QUIC-1, are now Closed by the secret-fields run (#674, plan #668):
Secret.Secretmay be areadonlyfield of a class whosewipe()provably wipes it (NL2540–NL2548). This lifts NL2430 for that shape.TlsServerandTlsRecordServerhold their secrets inSecretfields, which closes TLS-1.QuicConnectionholds its traffic secrets inSecretfields, andquicKeys/quicKeysUpdatewrite into a caller's slot. This closes QUIC-1, and #668 is fixed.Acceptance on
main@ 27f86d9 is recorded on #674. On it,npm testpasses 21,322 with 0 failed, wasi, performance andbootstrap --verifyare green, and each TLS and QUIC secret is read back as zero at each end of life.What stays plain, and why, is recorded in
docs/security/tls.mdandquic.md:Secretfields.Generated by Claude Code