@@ -42,10 +42,11 @@ A full TLS 1.3 (RFC 8446) client and server state machine in pure Standard ML:
4242 catch-all backstop maps any unexpected exception to ` decode_error ` , so
4343 untrusted input cannot crash ` step ` .
4444
45- ** Test coverage:** 306 passing tests on both MLton and Poly/ML, including RFC
45+ ** Test coverage:** 317 passing tests on both MLton and Poly/ML (357 in the FFI
46+ build), including RFC
46478448 vector tests, round-trip tests, negative / tamper tests, PSK-resumption
4748accept + negative-binder tests, FFI cross-implementation byte-equality tests,
48- and key-zeroization tests.
49+ and in-place key-zeroization tests.
4950
5051### Interoperability (J2)
5152
@@ -170,13 +171,31 @@ to compile faithfully rather than an in-logic `compile` evaluation (GAP B).
170171The remaining hello/cert/ticket codecs and the full crypto-bearing
171172mid-handshake simulation are not yet refined.
172173
173- ### 4. Memory zeroing (partially addressed, best-effort)
174-
175- ` TlsClient.zeroize ` / ` TlsServer.zeroize ` / ` zeroizeConfig ` overwrite traffic
176- keys, derived secrets, and ` serverConfig.rsaPrivateKeyDer ` via ` sodium_memzero `
177- (an FFI call the optimizer cannot elide). ** Best-effort caveat:** SML strings
178- are immutable and the GC may have copied secrets before zeroization; only the
179- currently-referenced buffers are overwritten, so prior copies may survive.
174+ ### 4. Memory zeroing (real in-place erasure for per-connection secrets)
175+
176+ Per-connection secret material (traffic keys/IVs, derived handshake/application
177+ secrets, ephemeral private keys, the server's RSA private key, and the PSK
178+ ticket store) now lives in a mutable, reference-shared ` Secret ` cell backed by a
179+ ` Word8Array ` . ` TlsClient.zeroize ` / ` TlsServer.zeroize ` wipe these buffers ** in
180+ place** via ` SecureZero.zero ` (` sodium_memzero ` in the FFI build, an un-elidable
181+ ` Word8Array.modify ` in the pure build), so the erasure is observable through the
182+ ** original** state handle — not merely a rebind on the returned value. This is
183+ verified by ` test/zeroize.sml ` , which captures secrets, calls ` zeroize ` on the
184+ original handle, then re-reads the same handle and asserts all-zero, on both
185+ compilers.
186+
187+ ** Residual caveats (honest):**
188+ - ` TlsKeySchedule ` outputs and the AEAD interface are still ` string ` -typed;
189+ secrets are converted to bytes only at those boundaries via ` Secret.toBytes ` ,
190+ leaving a short-lived transient copy that the GC — not ` sodium_memzero ` —
191+ reclaims.
192+ - ` zeroizeConfig ` (client and server) still rebinds the remaining ` string ` -typed
193+ config fields to zeros (prior semantics); only the per-connection state
194+ secrets are wiped truly in place.
195+ - No memory pinning (` sodium_malloc ` /` mlock ` ): holding a persistent C pointer
196+ across the purely-functional state threading isn't clean on both compilers,
197+ and since the crypto APIs copy ` string ` s anyway it buys little over the
198+ reference-shared ` Word8Array ` mechanism (` Secret.pinned = false ` ).
180199
181200### 5. No audit
182201
@@ -224,7 +243,11 @@ Completed (see `AUDIT.md`, `proof/PROOF_STATUS.md`, `proof/PROOF_CHAIN.md`):
2242435 . ✅ ** Constant-time crypto** (FFI build): X25519 + ChaCha20-Poly1305 via
225244 libsodium; AES-128/256-GCM + RSA-PSS-SHA256 via OpenSSL libcrypto, with the
226245 live handshake routed through them in the ` sources-ffi.mlb ` build.
227- 6 . ✅ ** Memory zeroing** : ` zeroize ` API via ` sodium_memzero ` (best-effort).
246+ 6 . ✅ ** Memory zeroing** : ` zeroize ` wipes per-connection secrets (traffic
247+ keys/IVs, derived secrets, ephemeral + RSA private keys, PSK ticket store)
248+ ** in place** through a reference-shared ` Word8Array ` -backed ` Secret ` cell, so
249+ erasure is observable on the original state handle on both compilers (see
250+ item 4 for residual ` string ` -boundary / config caveats).
2282517 . ✅ ** PSK resumption (accept path)** : server ticket store, binder
229252 verification, PSK key schedule.
230253
0 commit comments