Files
lneto/x/nts/definitions.go
T
Marvin Drees 5f8ca45859 feat(x/nts): add NTS support (#88)
Implement NTS (RFC 8915) with KERecord zero-copy frame, PerformKE
(TLS 1.3 + ExportKeyingMaterial), DeriveKeys, and Client state
machine implementing lneto.StackNode. Client handles cookie pool
management, auth body codec with nonce/ciphertext, and two-exchange
NTP flow with UniqueID verification and AEAD authentication.

Add NTS Server wrapping ntp.Server with AEAD verification/sealing,
and HandleKE for server-side NTS Key Exchange over TLS 1.3.

Use internal.LogAttrs for non-allocating structured logging
throughout the NTS client, matching existing conventions.

Generated with LLM assistance.

Signed-off-by: Marvin Drees <marvin.drees@9elements.com>
2026-06-15 11:42:10 -03:00

74 lines
3.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package nts implements the Network Time Security (NTS) key exchange and
// authenticated NTP packet construction as specified in RFC 8915.
//
// # Protocol overview
//
// NTS adds an authentication layer on top of NTPv4. It has two phases:
//
// 1. Key Exchange (NTS-KE, TCP port 4460): a TLS 1.3 handshake followed by
// a small application-layer record exchange that negotiates the AEAD
// algorithm and distributes opaque cookies. Use [PerformKE] to run this
// phase over a caller-owned *tls.Conn.
//
// 2. Authenticated NTP: each request carries a Unique-ID extension field, a
// Cookie extension field (from the pool obtained in phase 1), and an
// NTS-Authenticator-and-EEF field sealed with the C2S AEAD key. Use
// [Client] as the lneto [StackNode] for this phase.
//
// # Cipher note
//
// RFC 8915 §5.1 mandates AEAD_AES_SIV_CMAC_256 ([AlgAESSIVCMAC256]); it is the
// only algorithm a compliant implementation must support and the sole one
// registered at the time of writing. This algorithm is not part of the Go
// standard library, and lneto deliberately does not ship cryptographic
// primitives. Callers must therefore supply their own [cipher.AEAD]
// implementation, keyed with the C2S and S2C material in [KESecrets], via
// [ClientConfig] and [ServerConfig]. Any external or standard-library
// [cipher.AEAD] may be plugged in, but only AEAD_AES_SIV_CMAC_256 is
// guaranteed to interoperate with other RFC 8915 peers.
//
//go:generate stringer -type=KERecordType,AEADAlgorithmID -linecomment -output stringers.go
package nts
// KEPort is the IANA-assigned TCP port for the NTS Key Exchange protocol.
const KEPort = 4460
// MaxCookies is the maximum number of cookies the client stores at one time.
// RFC 8915 §5.7 says servers SHOULD send eight cookies.
const MaxCookies = 8
// MaxCookieLen is the maximum byte length of a single NTS cookie.
// Real-world servers typically use 100200 bytes; 256 provides headroom.
const MaxCookieLen = 256
// maxNonceLen is the largest nonce we pre-allocate space for.
// AES-SIV uses 16 bytes; GCM uses 12 bytes.
const maxNonceLen = 16
// KERecordType identifies NTS-KE record types (RFC 8915 §4.1.2).
type KERecordType uint16
const (
RecordEndOfMessage KERecordType = 0 // end of message
RecordNextProtoNeg KERecordType = 1 // next protocol negotiation
RecordError KERecordType = 2 // error
RecordWarning KERecordType = 3 // warning
RecordAEADAlgNeg KERecordType = 4 // AEAD algorithm negotiation
RecordNewCookie KERecordType = 5 // new cookie for NTPv4
RecordNTPv4Server KERecordType = 6 // NTPv4 server negotiation
RecordNTPv4Port KERecordType = 7 // NTPv4 port negotiation
)
// AEADAlgorithmID identifies AEAD algorithms used in NTS (RFC 8915 §5.1).
type AEADAlgorithmID uint16
const (
// AlgAESSIVCMAC256 is AEAD_AES_SIV_CMAC_256 (algorithm number 15).
// This is the only algorithm mandated by RFC 8915 §5.1 and the sole
// registered algorithm at time of writing.
AlgAESSIVCMAC256 AEADAlgorithmID = 15 // AEAD_AES_SIV_CMAC_256
)
// ntpv4ProtocolID is the NTS-KE protocol identifier for NTPv4 (RFC 8915 §4).
const ntpv4ProtocolID uint16 = 0