mirror of
https://github.com/soypat/lneto.git
synced 2026-08-08 00:43:40 +00:00
5f8ca45859
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>
74 lines
3.1 KiB
Go
74 lines
3.1 KiB
Go
// 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 100–200 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
|