Files
netbird/client/internal/pqkem/callbacks.go
T
riccardom a78d587e7a Introduces a forced WG handshake on initial MLKEM bootstrap.
To ensure two peers agree on a key, we need asymmetry. one peer is
the controller ("initiator") the other is the "responder".

Otherwise imagine two offers in parallel driving two answers at the same time

   A                   B
   | <----B-OFFER----- |
   | -----A-OFFER----> |
   |                   |
   |                   |
   ---------------------------------
  |****** ICE + WG Handshake ****** |
   ---------------------------------
   |                   |
   | <----B-ANSWER---- |
   | -----A-ANSWER---> |

PSK is derived on receive of offer, so A and B derive different PSKs.
When WG handshake takes place it picks misaligned PSKs.

So we impair the two nodes and only the offer of one of the two (the controller/initiator)
carries the KEM material.

This means that if the responder OFFER/ANSWER comes first, when the controller/initiator's one
completes (and the genuine PSK is shared between A and B, we need to force a new WG handshake with
the proper keys.
2026-09-11 14:48:54 +02:00

25 lines
1.4 KiB
Go

package pqkem
// CallbackHandler is implemented by the host and invoked by the library. The
// library only reports events; the host owns the reaction. Keeping this an
// interface — rather than touching the transport or keying directly — is what lets
// the KEM code be extracted as a standalone library.
type CallbackHandler interface {
// OnNewPSKReady fires when a fresh post-quantum PSK has been derived for a peer
// and must be programmed into the consumer's secure channel. It is invoked at
// the commit point of each side: the initiator on receiving the answer, the
// responder on receiving the confirm.
//
// bootstrap is true when the PSK came from a signalling exchange (initial setup or
// a wake re-negotiation) rather than a data-path rotation. On bootstrap the consumer
// must ensure the live channel actually adopts the PSK now (e.g. force a WireGuard
// re-handshake) — the channel may already be up on a pre-PQ key. A rotation
// (bootstrap=false) is adopted at the channel's next natural rekey.
OnNewPSKReady(remoteID RemoteID, psk PSK, bootstrap bool) error
// OnRekeyFailed fires when an exchange fails to converge within the allotted
// time. The host should tear the peer connection down so it re-establishes, and
// log a WARN. The library reports the event; it does not dictate the reaction.
OnRekeyFailed(remoteID RemoteID) error
}