nx_tls13_finished.nx
buildroot/runtime/nx_tls13_finished.nx
about
nx_tls13_finished.nx -- TLS 1.3 Finished MAC (RFC 8446 §4.4.4).
Phase 0b §J of the Nishi TLS 1.3 stack per
docs/NISHI_TLS13_GAP_AUDIT.md. The single HMAC over the
transcript hash that proves to the peer "I have the same
handshake-traffic-secret as you, and I saw the same handshake
messages." Without this the handshake never completes; with it,
the connection is authenticated end-to-end.
Per RFC 8446 §4.4.4:
finished_key = HKDF-Expand-Label(base_key, "finished", "", Hash.length)
verify_data = HMAC(finished_key, Transcript-Hash(Messages))
finished_key derivation lives in nx_tls13_schedule.tls13_finished_key.
This module is just the HMAC call + constant-time verify.
What it does today:
- compute Finished MAC (HMAC-SHA256 over transcript hash)
- verify received Finished against expected (constant-time)
- sealed verdict + validity gate
What it doesn't do yet:
- SHA-384 variant (composes against existing nx_hmac_sha384;
trivial - same shape but 48-byte tag instead of 32)
KAT verified:
- compute output == direct hmac_sha256(finished_key, transcript_hash)
(cross-check confirms Finished is literally HMAC, no extra
wrapping)
- verify on correct MAC returns OK
- verify on flipped-bit MAC returns FIN_MISMATCH
- constant-time compare: timing equivalence not measured here
but the code shape (XOR-and-OR all bytes, single subtract,
single shift) matches the proven pattern from
nx_poly1305.poly1305_tag_equal
Composes with:
- nx_hmac (HMAC-SHA256 primitive)
- nx_tls13_schedule (produces finished_key)
dependencies 2 imports · 10 importers
imports: nx_syscalls.nxnx_hmac.nx
imported by: nx_https_get_happy_test.nxnx_https_loopback_test.nxnx_tls13_client.nxnx_tls13_client_test.nxnx_tls13_finished_test.nxnx_tls13_full_tcp_test.nxnx_tls13_handshake_io.nxnx_tls13_handshake_tcp_test.nxnx_tls13_loopback_test.nxnx_tls13_server.nx
structs
| none |
consts
| 58 | const NX_TLS13_FIN_LEN_SHA256: i64 = 32 |
| 60 | const NX_TLS13_FIN_VERDICT_OK: i64 = 1 |
| 61 | const NX_TLS13_FIN_VERDICT_MISMATCH: i64 = 2 |
| 62 | const NX_TLS13_FIN_VERDICT_N: i64 = 3 |
functions
| 73 | func nx_tls13_finished_compute( |
| 89 | func nx_tls13_finished_verify( |
| 112 | func nx_tls13_fin_verdict_is_valid(v: i64) -> i64 called by 1: main |