Partial

RFC 7296 - Internet Key Exchange Protocol Version 2 (IKEv2)

Every requirement this repository extracted from RFC 7296, the tests bound to it, and what a reader has verified about them. This summary is enrolled and gated by ./le rfc check.

Overview

Positive

what Ze has

Tested both ways100.0%223 of 223 gated MUSTs

a positive test proves Ze does what the requirement demands and a negative one proves it refuses what the requirement forbids

One polarity plus reason0.0%0 of 223 gated MUSTs

the requirement admits no counter-case, so one polarity plus a recorded reason is the whole proof available for it

One polarity, unexcused0.0%0 of 223 gated MUSTs

one direction is tested, the other is neither tested nor excused, and nothing states which

Partial proof; remaining gap0.0%0 of 223 gated MUSTs

scoped tests exist; the remaining obligation is unmet or unproven, with zero whole-requirement credit

No test at all0.0%0 of 223 gated MUSTs

no test carries the requirement id, whether or not a gap states why

Proven by a recorded break32.8%227 of 693 tagged units

a red was observed once under a recorded procedure, and the unit, the claim and the producer it rested on still hash to what was recorded. The break is not re-run. A test pair is not a proof until one has been observed

Neutral

measures that are neither good news nor bad

Gated MUSTs223of 232 this summary declares

MUST-level requirements the gate HOLDS. A population, not a result: the shares beside it are what says how Ze stands

Out of scope0of 223 gated MUSTs

an obligation that does not bind Ze. A {not-applicable} annotation says it never bound; a {feature-declined} annotation says its condition is an optional feature Ze does not offer, and quotes the RFC sentence that makes it optional. Scope, not coverage: it stays in the denominator every share on this page is taken over

Not applicable0.0%0 of 223 gated MUSTs

a {not-applicable} annotation says the obligation does not bind Ze, so no test is owed for it. It stays in the denominator every share here is taken over

Met below Ze0.0%0 of 223 gated MUSTs

a {lower-layer} annotation says a layer under Ze performs the behavior, on state Ze installs into that layer, and names the producer that installs it. The obligation binds Ze and is met; Ze proves none of it, because its own boundary carries no value the behavior reads

Optional feature declined0.0%0 of 223 gated MUSTs

a {feature-declined} annotation says the obligation is conditional on a feature the RFC makes optional and Ze does not offer, and it quotes the sentence that makes it optional. The condition is false, so nothing is owed and nothing is missing. It stays in the denominator every share here is taken over

Negative

what Ze owes

Audit verdicts92of 223 gated MUSTs judged

1 weak, wrong or unimplemented, 0 no longer current. Each is named below under its own requirement id

The 8 shares marked as a part above are the whole of the 223 gated MUSTs: they add to 100%. Proven by a recorded break is a share of TAGGED UNITS, a different population, so it is not one of them.

How to read the colors

A color names what the measure MEANS, not how well Ze scores on it. Green is a good outcome at any value, red is a bad one, and neither a population nor a scope count is an outcome, so both take no color. The number under the label is what says how far Ze has got.

CardTone hereWhy that color
Gated MUSTs neutral no color: a population is a scale, and a larger one is neither good news nor bad. It is the accounting total
Out of scope neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Tested both ways ok green at every value: a test pair is the outcome this gate exists to produce, and the share under the label is what says how far Ze has got
One polarity plus reason ok green at every value: where no counter-case exists, one polarity IS the complete answer, and a recorded reason is what the gate demands beside it
One polarity, unexcused ok green at zero, RED above it: half a proof with no reason for the other half
Partial proof; remaining gap ok green at zero, RED above it: a tested clause cannot prove the whole requirement
No test at all ok green at zero, RED above it: a binding obligation nothing exercises is a claim with nothing behind it, whether or not a reason is stated
Not applicable neutral no color: an obligation that never bound Ze is neither an achievement nor a failure, and counting it either way would be a claim
Met below Ze neutral no color: an obligation met below Ze is neither a test Ze wrote nor work Ze owes, and the two green shares above are what says how much Ze proves itself
Optional feature declined neutral no color: an obligation whose condition Ze never meets is neither an achievement nor a failure. The absent FEATURE is disclosed on the RFC's own status row, as an implementation gap a later scope decision can revisit
Proven by a recorded break ok green at every value: an observed break is the outcome the discrimination gate exists to produce. The denominator is TAGGED UNITS, not obligations, so this share is not one of the parts above
Audit verdicts bad RED on the first weak, wrong or unimplemented verdict, amber while a verdict is no longer current or a gated MUST is unjudged, green when every one is judged sound and current

At a glance

FieldValue
Public status Partial
Enrolment Enrolled
Requirements 232
Gated MUST-level 223
Not applicable, so out of scope 0
Declared gaps 1
Declared gaps a test demonstrates 0
Gated with no test 0
Nightly-only evidence 0
Test tags 696
Tagged units 693
Recorded audit verdicts 92
Discrimination records 227
Summary rfc/short/rfc7296.md
Requirement shard rfc/requirements/rfc7296.md
RFC text rfc/full/rfc7296.txt

Enrolment

Enrolled: Internet Key Exchange Protocol Version 2 / IKEv2 (RFC 7296): Enrolled with every gated row carrying a positive and a negative `RFC requirement:` tag or an annotation saying why not; `./le rfc check` prints the current row, tag and annotation counts. A tag is its author's claim, not a proof: the independent verdicts in rfc/audit/rfc7296.json say which rows are judged enforced, and the rows judged weak or unimplemented there are open findings, so this enrolment does not claim every row is met. The 2026-08 pilot grew the summary from 23 rows and implemented what was absent: COOKIE (engine/cookie.go), the authenticated and out-of-SA error notifications (engine/notify_error.go), traffic-selector narrowing (engine/ts_narrow.go), per-SPI Child SA Delete (engine/delete.go), Message ID exhaustion (engine/msgid.go), and dual ESP form reception (dataplane/espform_linux.go). Two obligation sets are extracted and stay gated in their destination specs instead of here: the Configuration payload / IRAC role (11 rows, plan/immediate/spec-ipsec-remote-access.md; ze takes no IRAC role, which Section 4 permits) and IPComp (4 rows, plan/spec-ipsec-ipcomp.md). The Section 3.2 extraction walk added the two Critical-bit SENDER obligations the summary never carried, RFC7296-3.2-5 (zero asks the recipient to skip an unrecognized payload) and RFC7296-3.2-6 (one asks it to reject the whole message). The same walk added two more the summary never carried, RFC7296-1.3.3-2 (a CREATE_CHILD_SA that replaces an ESP or AH SA carries the REKEY_SA notification) and RFC7296-4-5 (the four-message IKE_SA_INIT and IKE_AUTH exchange establishes two SAs). rfc/extraction/rfc7296.json is signed off (2026-08-02): 261 sites in 104 sections, all classified, so the bound is a recorded walk of the source rather than the 222 extracted rows alone. 12 sites are relocated-to-spec, carrying obligations owner ruling D-1 moved to plan/immediate/spec-ipsec-remote-access.md and plan/spec-ipsec-ipcomp.md, and 26 requirements are unsourced-ids read from indicative prose that carries no keyword

What the public ledger says

Status: Partial

What the ledger says is covered
  • Wire codec, cryptographic primitives, initiator and responder FSM, IKE_SA_INIT, IKE_AUTH, CREATE_CHILD_SA, INFORMATIONAL, rekey, DPD. Section 1.4 authenticated Delete on operator clear (graceful bounce)
  • Section 2.4 state synchronization: the responder accepts a fresh IKE_SA_INIT in parallel with an established SA and supersedes it only once the new SA authenticates (never on the unauthenticated init)
  • INITIAL_CONTACT emitted on the first IKE_AUTH request and honored on receipt. Section 1.4 liveness probes carry the Encrypted payload and authenticate under the negotiated keys. Section 2.4 refuses a verdict about the peer from an unauthenticated message, because an established SA is served by one handler that decrypts first. Section 2.5 accepts an IKE_AUTH whose payloads arrive in any order, on both the initiator and the responder path. Section 3.6 reads the first CERT payload as the peer certificate. It reads every later one as a chain intermediate. Ze sends its configured intermediate after the device certificate. Section 2.2 Message ID exhaustion: both counters stop at the 32-bit ceiling instead of wrapping. The SA rekeys itself in the headroom below the ceiling. The owner loop closes it at the ceiling (engine/msgid.go, engine/established.go). Section 2.3 window: Ze declares a window of one and accepts exactly one request id. It reads a peer SET_WINDOW_SIZE during IKE_AUTH, refuses a body that is not 4 octets, and reports the value as peer-window-size in show vpn ipsec sa. A peer request that crosses one of ours is accepted and answered, and a request outside the window is never acknowledged. Section 2.3 INVALID_MESSAGE_ID: an out-of-window request that authenticates draws the notification. Ze sends it as a NEW INFORMATIONAL request. That request carries the four-octet invalid Message ID. Ze never sends it as a response. Three bounds apply. Ze decrypts the request first, so an unauthenticated datagram draws nothing at all. Ze sends the notification only when its one request window is free. The notification therefore never displaces a liveness probe, a Delete or a rekey. A token bucket on the SA rate limits it. That bucket satisfies the MUST of Section 2.3 (engine/notify_invalid_msgid.go). Section 2.25: a rekey the peer answers with TEMPORARY_FAILURE waits 60 seconds before it is retried, per rekey kind. Sections 2.21.2, 2.21.3 and 2.21.4 error notifications: a request that fails on an authenticated IKE SA draws an encrypted error notify instead of silence. A refused Child SA rekey draws NO_PROPOSAL_CHOSEN, a malformed request draws INVALID_SYNTAX, and an unrecognized critical payload draws UNSUPPORTED_CRITICAL_PAYLOAD with the one-octet payload type. A datagram that matches no IKE SA draws an unprotected INVALID_IKE_SPI that copies the SPIs, Exchange Type and Message ID. That answer is rate limited. It is never sent in reply to a message marked as a response. It is never sent for an IKE_SA_INIT. An unprotected datagram at a CACHED message id draws no cached response and changes no SA state. This holds on the established path and on the mid-EAP responder path alike (engine/notify_error.go, engine/responder.go replayCachedResponse). The claim is bounded to that message id on purpose. An undecryptable datagram at a message id the responder is still expecting is a different path, and it does change SA state (engine/responder_eap.go handleResponderEAP). Section 3.10.1: an unrecognized error notify in a response fails the request it answers, and an unrecognized status notify is ignored and logged. Section 3.10.1 sender side: Ze adds one status notify of its own, the private-use ZE_PATH_PROBE_PADDING (65280), to the INFORMATIONAL request of the padded path probe that show mtu runs over a live SA
  • its Notification Data pads the datagram to a requested size, and a peer that does not recognize it ignores it and answers an empty response (engine/probe.go, wire/payload_notify.go). Section 3.14 is why SK padding is not that carrier: the Pad Length is one octet, so SK padding cannot pass 255 octets, and an AEAD suite pads nothing (RFC 5282)
  • under CBC the padding rule fixes the encrypted span to the block size, so the probe reaches sizes on a 16-octet grid and refuses the rest by name. Section 2.1: the probe is an ordinary request
  • its retransmission is the same bytes from the IKE header on with only the IP header's DF bit changed, and a probe unanswered through the full budget deems the SA failed exactly as an unanswered Delete does (engine/established.go serviceRequestWindow, unchanged). Sections 1.2 and 2.6 corrected retry: an initiator that guesses the wrong Diffie-Hellman group retries the IKE_SA_INIT under the group the responder names, and refuses a group it never proposed, so a forged unauthenticated notify cannot steer it. The retry re-offers the whole configured suite set and re-anchors the signed IKE_SA_INIT octets. Section 2.6 COOKIE: the responder answers an inbound IKE_SA_INIT with a COOKIE challenge before it commits a half-open slot, and the initiator echoes the cookie as the first payload of a retry that changes nothing else. The cookie is an HMAC over the nonce, the source address and the initiator SPI under a rotating secret, is bounded to 1..64 octets on both the mint and the echo path, and a cookie that does not match is ignored rather than rejected. cookie-threshold sets how many half-open IKE SAs are tolerated before challenging, and defaults to 0 (challenge every initiation). Section 2.6.1: a second challenge replaces the first without failing, and the retry budget is bounded (engine/cookie.go, engine/sa_init_retry.go). Section 3.15.1 Configuration payload codec: the attribute type is 15 bits. Ze masks the Reserved bit on the read path and on the write path. A peer that sets that bit still has its INTERNAL_IP4_ADDRESS recognized (wire/payload_cp.go). Sections 2.19, 2.20 and 3.15.1: Ze builds no Configuration payload. It takes no IRAC role, which Section 4 permits. It ignores CFG_SET, which Section 3.15.1 permits. It sends no CFG_REQUEST, no CFG_REPLY and no CFG_ACK, and it gives out no version string. Section 3.4 key exchange pairing: the initiator refuses an IKE_SA_INIT or IKE-rekey response whose KE payload names a Diffie-Hellman group that no proposal of the same message specifies, and refuses a KE payload at all when no proposal specifies a group. A Transform ID of NONE names no group for both rules (wire/payload_sa.go, engine/fsm.go). Section 3.3.6: an IKE SA negotiation never selects the group NONE, and the one exchange that does select it, a Child SA rekey without PFS, ignores any KE payload the peer sends and omits one from the response (engine/rekey.go). Section 2.4: INITIAL_CONTACT is withheld by an identity that may be replicated. An EAP credential names a user rather than a device, so an EAP peer sends none
  • a pre-shared secret or X.509 device identity still sends it (engine/auth.go). Section 2.8: an IKE SA whose negotiated lifetime has expired is refused for use at the point every protected message is built, not merely scheduled for teardown, and hard expiry is no longer deferred by an in-flight rekey. The rekey trigger is placed a full retransmit budget before the hard time so the replacement exchange still has room (engine/sa.go, engine/auth.go, engine/established.go, engine/rekey.go). Section 4: a rekey the peer refuses with NO_ADDITIONAL_SAS is answered by deleting the old SA and creating a new one through the initial exchanges, instead of retrying an exchange that peer will never accept (engine/rekey.go, engine/inbound.go). Section 3.6 certificate count: certificate-count bounds the chain Ze sends and the chain it accepts, and it defaults to the four the section names. A peer that sends more is refused, never truncated (engine/cert_payload.go). Section 3.6 Hash and URL: hash-and-url turns on both encodings. Ze sends encoding 12 for one certificate and encoding 13 for a bundle, and it advertises HTTP_CERT_LOOKUP_SUPPORTED. It resolves a payload a peer sends through a bounded http fetch. That fetch permits the http scheme only. It caps the body at 64 KiB and times out after 5 seconds. It follows no redirect. It denies loopback, private, link-local and metadata addresses. It verifies the SHA-1 before any parser reads the bytes. The leaf defaults to false, so no fetch is reachable until an operator asks for one (engine/certurl.go, engine/certbundle.go). Section 2.9 traffic-selector narrowing: the responder narrows the initiator's proposed TSi/TSr to a subset its configured traffic-selector list allows, leads that subset with the initiator's first choices, and answers TS_UNACCEPTABLE when nothing is acceptable. A peer with no configured selectors accepts whatever it is offered, which is the behavior of every configuration written before the list existed. The selectors Ze puts on the wire are the selectors it programs: a proposal it cannot program exactly is narrowed further, never rounded outward (engine/ts_narrow.go, ipsec/traffic_selector.go). Section 2.9.2: a rekey is never narrowed below the scope currently in use (engine/rekey.go). Sections 1.3.1 and 2.23.1 transport mode: mode transport sends USE_TRANSPORT_MODE with the Child SA request and pins TSi and TSr to the IKE SA's own OBSERVED address pair, one address each. A responder accepts the request only when its own configuration asks for transport mode, and echoes the notification when it does. A peer that declines leaves a tunnel-mode Child SA, and transport-required makes that decline delete the SA instead (engine/transport_mode.go, engine/child.go). Section 2.23.1 address substitution: with a NAT on the path, both roles replace the transport-mode selector addresses before those selectors are used for anything except storing the originals. The responder substitutes the TSi address with the observed remote address when the peer is behind a NAT, and the TSr address with its own local address when it is, before the policy lookup that is Ze's SPD lookup. The initiator substitutes the mirror pair before the answer is checked against what it proposed and before the SAD entry is created. The substituted address is always one this node observed, never one the peer asserted, so the narrowing guard still refuses an answer outside the proposal. The SA records which SIDE each translation is on, separately from whether a NAT is present, and stores the pre-substitution addresses the section requires be kept. Tunnel mode and a NAT-free path are unchanged. Proven against strongSwan across a netfilter box that really rewrites both addresses, in test/interop-ipsec/scenarios/real-nat-transport-ze-initiator, real-nat-transport-ze-responder and real-nat-tunnel-control (engine/ts_nat_substitute.go, engine/ts_narrow.go, engine/sa.go). Section 3.13.1 port selectors: a selector carries all ports (0/65535) or one port under a protocol that defines ports (ipsec/traffic_selector.go). Section 4 conformance set: Ze accepts PKIX certificates signed by RSA keys of 1024 and 2048 bits. The identity passed can be ID_FQDN, ID_RFC822_ADDR or ID_DER_ASN1_DN, which binds against the certificate subject exactly. remote-id-type key-id lets an operator accept ID_KEY_ID, which corresponds to no certificate field. The same leaf pins one identity type per peer (engine/remote_id.go). Section 3.3 transform alternatives: one proposal CAN carry several transforms of the same Transform Type. Ze reads every one of them as an alternative, and it does not keep only the last. A peer CAN offer two Diffie-Hellman groups, two key lengths, two PRFs or two integrity algorithms in one proposal. Ze considers all of them, in the order the peer listed them. Ze selects the peer's first choice that it supports. The number of combinations one proposal expands to is bounded, so an unauthenticated peer cannot turn a cross product into unbounded work (engine/initiator.go). Section 1.4.1 Delete: an inbound Child SA Delete is resolved to the pair the peer named by SPI and that pair is closed, and the response carries a Delete payload naming the paired SA going in the other direction. A Delete that crosses one Ze already sent for the same pair is answered without a Delete payload, and the two halves of the pair go at the two points the section names. An IKE SA Delete still draws an empty response (engine/delete.go). Section 1.5: the out-of-SA notification emitter is a fixed point, so its own output fed back to it produces nothing and two nodes cannot trade messages forever (engine/notify_error.go). Section 2.12: closing an IKE SA erases SK_d and the rest of SK_*, the Diffie-Hellman private value and the EAP MSK, and releases the nonces, on every path that ends an SA including an abandoned half-open handshake. The two holders that live on the peer SESSION rather than on the SA are released on the same exit: the Diffie-Hellman private value of a rekey that never got its answer, and a whole IKE SA built while answering the peer's rekey and never confirmed by the peer's Delete. The session outlives the SA, so either one left behind would carry key material into the next reconnect cycle (engine/sa.go, engine/established.go, engine/fsm.go). Section 2.16: the EAP shared key generates the AUTH payloads that follow EAP Success, and the responder sends Success on a completed method and Failure on a refused one (eap/eap.go, engine/eap_auth.go). Section 2.24 ECN: no config leaf and no negotiated parameter can reach an ECN knob, and the netlink state Ze fills carries no flags field, so XFRM_STATE_NOECN is unreachable and the kernel's ECN propagation stands (dataplane/xfrm_linux.go). Section 3.1: a liveness probe sets the I bit from the ORIGINAL initiator role rather than hardcoding it (engine/dpd.go). Section 3.5: an ID_FQDN or ID_RFC822_ADDR carrying a terminator octet is refused, on the receive path against a peer's asserted identity and at commit against local-id and remote-id (engine/remote_id.go, ipsec/validate.go). Section 3.3 ESP alternatives: every transform of a type in one ESP proposal is read as an alternative, and a key length is only ever compared beside the id of the transform that carried it (engine/responder.go). Section 2.7 Extended Sequence Numbers: Ze keys a 32-bit ESP sequence space, so it offers and answers Transform Type 5 value 0 and selects that value from a proposal that offers both. A proposal offering value 1 alone is refused with NO_PROPOSAL_CHOSEN rather than answered with a transform the peer never proposed, and an answer selecting value 1 ends the exchange on the initiator side (engine/responder.go, engine/initiator.go). Proven against strongSwan in test/interop-ipsec/scenarios/esn-extended-only-refused and esn-both-offered. Section 2.23 NAT-T: one Child SA receives BOTH ESP forms, and the form Ze SENDS follows the NAT verdict alone. Reception and transmission are two decisions. The inbound XFRM state carries the encapsulation template when a NAT was detected or the IKE SA runs on port 4500, so the kernel serves that form on its fast path. The other form is served beside the kernel: a raw IPPROTO_ESP reader takes the bare datagram XFRM refused and re-presents it through port 4500, which carries UDP_ENCAP, so the kernel hands XFRM the encapsulation type the template wants. Ze encapsulates on transmission only when it detected a NAT, which RFC 7296 Section 2.23 makes mandatory there and leaves free otherwise. Reading the port as a transmission signal broke interop against a strongSwan that floats to port 4500 for MOBIKE with no NAT present and then sends bare ESP (engine/child.go, dataplane/espform.go, dataplane/espform_linux.go, transport/encap_linux.go). Section 2.2 two counters: each end keeps its own next Message ID. A responder-role SA raises its first request at the id a conforming peer expects. It took the peer's id before this fix, so it raised no DPD, no Delete and no rekey (engine/responder.go, engine/msgid.go). Section 2.9 narrowing orientation: the responder narrows against the orientation of the exchange in hand. The IKE SA role is a different question. A Child SA rekey the peer starts on a tunnel Ze initiated is answered rather than refused with TS_UNACCEPTABLE (engine/ts_narrow.go). Section 2.8 rekey on the XFRM dataplane: the replacement Child SA inherits the retired pair's selectors and their orientation. The make-before-break window holds one policy, and retiring the superseded pair removes no selector the live pair still needs. test/ipsec/ipsec-child-rekey-xfrm.ci measures it on the real backend with the two roles crossed (engine/rekey.go, engine/child.go). Section 2.21.2 childless IKE SA: an IKE_AUTH whose AUTH verifies keeps the IKE SA when its Child SA is refused, in both roles. The responder answers IDr, CERT and AUTH with the error notify and no SAr2, and the initiator establishes from that answer and sends no Delete. The IKE SA initiator then asks for its Child SA with a CREATE_CHILD_SA new-child request (Section 1.3.1), with KEi when pfs is on, retried on a doubling schedule from 30 to 300 seconds
  • either role answers a peer's new-child request on a childless IKE SA, and answers NO_ADDITIONAL_SAS while it holds one (engine/responder.go, engine/fsm.go, engine/create_child.go, engine/inbound.go).
What the ledger says remains

No MUST gap remains gated in rfc/short/rfc7296.md. The Delete-payload echo that RFC7296-1.4-1 recorded is implemented: an inbound Child SA Delete now closes the pair the peer designated by SPI and the response names the paired SA going the other way (engine/delete.go). Two platform limits are gated and disclosed, and neither is left as a gap. Section 3.13.1 OPAQUE ports: Ze implements the 65535/0 encoding and proves it. Ze refuses OPAQUE at commit and at negotiation. The kernel policy selector derives its port mask from the port value, so an exact match on port 0 would install as any-port. That is wider than the selector negotiated. Section 2.23 ESP forms: the platform limit is LIFTED. One established Child SA now receives both UDP-encapsulated and bare ESP, so a peer that changes form on that SA is served. TestEncapOneStateAcceptsBothForms measures it against a real kernel: ONE state on ONE SPI, the encapsulated form on the kernel fast path and the bare form read off a raw IPPROTO_ESP socket and re-presented, both reaching the crypto check (dataplane/encap_hybrid_integration_linux_test.go). That test re-presents the datagram by hand, so it measures the kernel mechanism and not the shipped path. TestEncapEstablishedSAServesAPeerFormChange measures the shipped path: the SA is installed through the production backend, a live SA carries one form, the peer switches to the other, then back, and the kernel's state table shows ONE state with an unchanged add time throughout (dataplane/encap_formchange_integration_linux_test.go). The claim is also proven against strongSwan, over a real interface, in test/interop-ipsec/scenarios/esp-form-change: a live Child SA whose peer sends the form Ze's kernel state refuses carries traffic in both directions and is neither rekeyed nor deleted. That scenario is what caught the one defect that made this claim false in a real deployment. Linux runs xfrm4_policy_check before it queues a packet to a raw socket, and Ze's own inbound Child SA policy rejected the datagrams the receiver exists to recover, so the kernel dropped every one of them. The reader now carries a per-socket inbound bypass, scoped to that socket alone (dataplane/espform_linux.go). No loopback test can see that defect, because a loopback dst entry carries DST_NOPOLICY and the check is skipped. One Linux XFRM state still binds one form, which TestEncapKernelBindsOneESPFormPerState records, so the second form is served beside the kernel rather than through it (dataplane/encap_integration_linux_test.go). Two states on one SPI do NOT help, and that is now MEASURED rather than reasoned. The kernel refuses to install the second state with file exists, both with identical addresses and with a differing source, because the uniqueness key and the lookup key are the same tuple. The earlier text said the lookup returns the first match and the encapsulation check then drops the packet.

That mechanism is wrong: the second state never exists (dataplane/encap_dualform_integration_linux_test.go). One combination stays unreachable and is bounded by the RFC rather than by Ze: a template-free inbound state cannot receive the encapsulated form, because the port-4500 socket carries UDP_ENCAP and the kernel consumes that datagram before any userspace reader sees it (TestEncapEncapsulatedESPHiddenFromUserspaceWhenSocketDecapsulates). No conforming peer produces it. RFC 3948 Section 2.1 requires the ESP-in-UDP ports to equal the IKE ports, and RFC 7296 Section 2.23 forbids encapsulation on port 500, so a peer that encapsulates ESP runs its IKE on port 4500 and Ze templates that SA.

Coverage

BucketCountWhat it counts
Positive and negative tests 223 one part of the gated population
Annotated (including scoped evidence) 0 one part of the gated population
One polarity only 0 one part of the gated population
No test and no annotation 0 one part of the gated population
Partial proof; remaining gap (subset of annotated; zero whole-requirement credit) 0 an overlay: each of these is also counted by the part it falls in
Evidence that runs nightly only 0 an overlay: each of these is also counted by the part it falls in
Derived from other rows 0 outside the gated population: each asserts nothing and derives its state from the rows it names, which the parts above already count
Gated MUST-level requirements223every gated MUST falls in exactly one bucket above

Positive and negative tests (223): RFC7296-1.2-1, RFC7296-2.6-1, RFC7296-2.7-1, RFC7296-3.3-1, RFC7296-3.3-2, RFC7296-3.3.2-1, RFC7296-1.3.3-1, RFC7296-1.3.3-2, RFC7296-1.3.3-3, RFC7296-1.3.3-4, RFC7296-2.9-1, RFC7296-2.9-2, RFC7296-2.9.2-1, RFC7296-2.9.2-2, RFC7296-1.3.1-1, RFC7296-1.3.1-2, RFC7296-2.23.1-1, RFC7296-2.23.1-2, RFC7296-2.23.1-3, RFC7296-3.13.1-1, RFC7296-3.13.1-2, RFC7296-3.13.1-3, RFC7296-2.23-1, RFC7296-2.23-2, RFC7296-2.23-3, RFC7296-2.4-1, RFC7296-2.8-2, RFC7296-1-1, RFC7296-1.2-2, RFC7296-1.2-3, RFC7296-1.2-4, RFC7296-1.2-5, RFC7296-1.2-6, RFC7296-2.4-11, RFC7296-2.4-12, RFC7296-2.4-13, RFC7296-2.7-2, RFC7296-2.10-4, RFC7296-2.11-1, RFC7296-2.11-2, RFC7296-2.11-3, RFC7296-2.16-11, RFC7296-2.16-6, RFC7296-2.16-7, RFC7296-2.23-7, RFC7296-2.23-8, RFC7296-2.23-9, RFC7296-2.23-10, RFC7296-2.23-11, RFC7296-2.23-12, RFC7296-3.9-2, RFC7296-1.3-2, RFC7296-2.8.2-1, RFC7296-3.3.6-3, RFC7296-1.4-3, RFC7296-1.4-4, RFC7296-1.4-5, RFC7296-1.4.1-6, RFC7296-1.4.1-7, RFC7296-1.5-1, RFC7296-2.12-1, RFC7296-2.24-1, RFC7296-2.24-2, RFC7296-2.16-12, RFC7296-2.16-13, RFC7296-2.16-14, RFC7296-2.16-15, RFC7296-3.1-13, RFC7296-3.5-5, RFC7296-3.5-6, RFC7296-1.4.1-1, RFC7296-1.4.1-4, RFC7296-1.4.1-5, RFC7296-2.4-9, RFC7296-2.4-10, RFC7296-2.16-5, RFC7296-3.4-1, RFC7296-1.3-1, RFC7296-2.1-3, RFC7296-2.1-4, RFC7296-2.1-5, RFC7296-2.1-6, RFC7296-2.1-7, RFC7296-2.1-8, RFC7296-2.2-1, RFC7296-2.2-2, RFC7296-2.2-3, RFC7296-2.3-2, RFC7296-2.3-4, RFC7296-2.3-5, RFC7296-2.3-7, RFC7296-2.3-8, RFC7296-2.3-9, RFC7296-2.25-1, RFC7296-2.8-5, RFC7296-2.8-6, RFC7296-2.8-7, RFC7296-2.8.1-1, RFC7296-2.18-2, RFC7296-2.18-3, RFC7296-3.16-1, RFC7296-3.16-2, RFC7296-3.16-3, RFC7296-3.16-4, RFC7296-1.7-2, RFC7296-2-1, RFC7296-2.5-1, RFC7296-2.5-2, RFC7296-2.5-6, RFC7296-2.5-7, RFC7296-2.5-8, RFC7296-2.5-9, RFC7296-2.5-11, RFC7296-2.5-13, RFC7296-2.5-14, RFC7296-2.5-15, RFC7296-2.5-16, RFC7296-2.5-17, RFC7296-2.5-18, RFC7296-2.21.2-1, RFC7296-2.21.2-2, RFC7296-2.21.2-3, RFC7296-2.21.3-1, RFC7296-2.21.4-1, RFC7296-2.21.4-2, RFC7296-2.21.4-3, RFC7296-2.21.4-4, RFC7296-2.21.4-5, RFC7296-2.21.4-6, RFC7296-2.21.4-7, RFC7296-3.10.1-1, RFC7296-3.10.1-2, RFC7296-3.10.1-3, RFC7296-2.6-2, RFC7296-2.6-3, RFC7296-2.6-4, RFC7296-2.6-5, RFC7296-2.6.1-1, RFC7296-2.10-2, RFC7296-2.10-3, RFC7296-2.13-1, RFC7296-2.13-3, RFC7296-2.13-4, RFC7296-2.15-1, RFC7296-2.15-2, RFC7296-2.17-1, RFC7296-2.17-2, RFC7296-3.1-1, RFC7296-3.1-2, RFC7296-3.1-3, RFC7296-3.1-4, RFC7296-3.1-5, RFC7296-3.1-6, RFC7296-3.1-7, RFC7296-3.1-8, RFC7296-3.1-9, RFC7296-3.1-11, RFC7296-3.1-12, RFC7296-3.2-2, RFC7296-3.2-3, RFC7296-3.2-4, RFC7296-3.2-5, RFC7296-3.2-6, RFC7296-3.3-3, RFC7296-3.3-4, RFC7296-3.3-5, RFC7296-3.3-6, RFC7296-3.3-7, RFC7296-3.3.1-1, RFC7296-3.3.1-2, RFC7296-3.3.3-1, RFC7296-3.3.4-2, RFC7296-3.3.4-3, RFC7296-3.3.5-1, RFC7296-3.3.5-2, RFC7296-3.3.5-3, RFC7296-3.3.5-4, RFC7296-3.3.5-5, RFC7296-3.3.6-4, RFC7296-3.3.6-5, RFC7296-3.3.6-7, RFC7296-3.9-1, RFC7296-3.10-3, RFC7296-3.10-4, RFC7296-3.10-5, RFC7296-3.11-1, RFC7296-3.11-2, RFC7296-3.12-2, RFC7296-3.12-3, RFC7296-3.12-4, RFC7296-3.14-2, RFC7296-3.14-3, RFC7296-3.14-4, RFC7296-3.14-5, RFC7296-3.14-6, RFC7296-3.14-7, RFC7296-5-2, RFC7296-5-3, RFC7296-2.19-1, RFC7296-2.19-4, RFC7296-2.20-1, RFC7296-3.15.1-2, RFC7296-3.15.1-5, RFC7296-3.15.1-6, RFC7296-3.15.1-7, RFC7296-2.4-3, RFC7296-2.4-4, RFC7296-3.4-2, RFC7296-3.4-3, RFC7296-3.3.6-8, RFC7296-2.4-14, RFC7296-2.8-8, RFC7296-4-1, RFC7296-2.15-3, RFC7296-3.3.4-4, RFC7296-3.5-2, RFC7296-3.5-3, RFC7296-3.5-4, RFC7296-3.6-1, RFC7296-3.6-2, RFC7296-3.6-3, RFC7296-4-4, RFC7296-4-5

Requirements

RequirementLevelSectionTests
RFC7296-1.2-1The first pair of messages (IKE_SA_INIT) negotiate cryptographic algorithms, exchange nonces, and do a Diffie-Hellman exchange [DH]. The second pair of messages (IKE_AUTH) authenticate the previous messages, exchange identities and certificates, and establish the first Child SA. Parts of these messages are encrypted and integrity protected with keys established through the IKE_SA_INIT exchange, so the identities are hidden from eavesdroppers and all fields in all the messages are authenticated. (§1.2)
MUST 1.2 - The initial exchanges
RFC7296-2.6-1The initial two eight-octet fields in the header, called the "IKE SPIs", are used as a connection identifier at the beginning of IKE packets. (§2.6)
MUST 2.6
RFC7296-2.7-1The responder MUST accept a single proposal or reject them all and return an error. The error is given in a notification of type NO_PROPOSAL_CHOSEN. Each IPsec protocol proposal contains one or more transforms. Each transform contains a Transform Type. The accepted cryptographic suite MUST contain exactly one transform of each type included in the proposal. (§2.7)
MUST 2.7
RFC7296-3.3-1If an initiator wants to propose both combined- mode ciphers and normal ciphers, it must include two proposals: one will have all the combined-mode ciphers, and the other will have all the normal ciphers with the integrity algorithms. (§3.3)
MUST 3.3
RFC7296-3.3-2Combined-mode ciphers include both integrity and encryption in a single encryption algorithm, and MUST either offer no integrity algorithm or a single integrity algorithm of "NONE" (§3.3)
MUST 3.3
RFC7296-3.3.2-1An SA payload proposing the establishment of an SA has the following mandatory and optional Transform Types. A compliant implementation MUST understand all mandatory and optional types for each protocol it supports (though it need not accept proposals with unacceptable suites). A proposal MAY omit the optional types if the only value for them it will accept is NONE. Protocol Mandatory Types Optional Types --------------------------------------------------- IKE ENCR, PRF, INTEG*, D-H (§3.3.3)
MUST 3.3.3
RFC7296-1.3.3-1The KEi payload MUST be included. (§1.3.2)
MUST 1.3.2 - Rekeying the IKE SA
positiveunit/verifyTestRespondIKERekey
RFC7296-1.3.3-2The REKEY_SA notification MUST be included in a CREATE_CHILD_SA exchange if the purpose of the exchange is to replace an existing ESP or AH SA (§1.3.3)
MUST 1.3.3 - Rekeying a Child SA
RFC7296-1.3.3-3The initiator sends SA offer(s) in the SA payload, a nonce in the Ni payload, optionally a Diffie-Hellman value in the KEi payload, and the proposed Traffic Selectors for the proposed Child SA in the TSi and TSr payloads. (§1.3.3)
MUST 1.3.3 - Rekeying a Child SA
RFC7296-1.3.3-4The Traffic Selectors for traffic to be sent on that SA are specified in the TS payloads in the response, which may be a subset of what the initiator of the Child SA proposed. (§1.3.3)
MUST 1.3.3 - Rekeying a Child SA
RFC7296-2.9-1When the responder chooses a subset of the traffic proposed by the initiator, it narrows the Traffic Selectors to some subset of the initiator's proposal (provided the set does not become the null set). (§2.9)
MUST 2.9
RFC7296-2.9-2If the responder's policy allows it to accept the first selector of TSi and TSr, then the responder MUST narrow the Traffic Selectors to a subset that includes the initiator's first choices (§2.9)
MUST 2.9
RFC7296-2.9.2-1Thus, the new SA MUST NOT have narrower selectors than the original (§2.9.2)
MUST NOT 2.9.2
RFC7296-2.9.2-2The responder MUST NOT narrow down the Traffic Selectors narrower than the scope currently in use (§2.9.2)
MUST NOT 2.9.2
RFC7296-1.3.1-1If the request is accepted, the response MUST also include a notification of type USE_TRANSPORT_MODE (§1.3.1)
MUST 1.3.1 - Creating a new Child SA
RFC7296-1.3.1-2If the responder declines the request, the Child SA will be established in tunnel mode. If this is unacceptable to the initiator, the initiator MUST delete the SA (§1.3.1)
MUST 1.3.1 - Creating a new Child SA
RFC7296-2.23.1-1For transport mode, it MUST use exactly one IP address in the TSi and TSr payloads (§2.23.1)
MUST 2.23.1
RFC7296-2.23.1-2The TSi entries MUST have exactly one IP address, and that MUST match the source address of the IKE SA (§2.23.1)
MUST 2.23.1
RFC7296-2.23.1-3The TSr entries MUST have exactly one IP address, and that MUST match the destination address of the IKE SA (§2.23.1)
MUST 2.23.1
RFC7296-3.13.1-1For protocols for which port is undefined (including protocol 0), or if all ports are allowed, this field MUST be zero. (§3.13.1)
MUST 3.13.1
RFC7296-3.13.1-2For protocols for which port is undefined (including protocol 0), or if all ports are allowed, this field MUST be 65535. (§3.13.1)
MUST 3.13.1
RFC7296-3.13.1-3Systems working with [IPSECARCH] that wish to indicate "OPAQUE" ports, but not "ANY" ports, MUST set the start port to 65535 and the end port to 0. (§3.13.1)
MUST 3.13.1
RFC7296-2.23-1The IKE initiator MUST check the NAT_DETECTION_SOURCE_IP or NAT_DETECTION_DESTINATION_IP payloads if present (§2.23)
MUST 2.23
RFC7296-2.23-2However, if a NAT is detected, both devices MUST use UDP encapsulation for ESP. (§2.23)
MUST 2.23
positiveunit/verifyTestChildSANATTEncapPorts
negativeunit/verifyTestChildSANoNATNoEncap
RFC7296-2.23-3To tunnel IKE packets over UDP port 4500, the IKE header has four octets of zeros prepended and the result immediately follows the UDP header. (§2.23)
MUST 2.23
RFC7296-2.8-1If redundant SAs are created through such a collision, the SA created with the lowest of the four nonces used in the two exchanges SHOULD be closed by the endpoint that created it (§2.8, §2.8.1)
SHOULD 2.8
RFC7296-2.4-1To check whether the other side is alive, IKE specifies an empty INFORMATIONAL request that (like all IKE requests) requires an acknowledgement (§2.4)
MUST 2.4
RFC7296-1.4-1Normally, the response in the INFORMATIONAL exchange will contain Delete payloads for the paired SAs going in the other direction. (§1.4.1)
SHOULD 1.4.1 - Deleting an SA
RFC7296-2.8-2A difference between IKEv1 and IKEv2 is that in IKEv1 SA lifetimes were negotiated. In IKEv2, each end of the SA is responsible for enforcing its own lifetime policy on the SA and rekeying the SA when necessary. (§2.8)
MUST NOT 2.8
positiveunit/verifyTestSALifetimeTime
RFC7296-1-1In all cases, all IKE_SA_INIT exchanges MUST complete before any other exchange type, then all IKE_AUTH exchanges MUST complete, and following that, any number of CREATE_CHILD_SA and INFORMATIONAL exchanges may occur in any order (§1)
MUST 1
RFC7296-1.2-2If any CERT payloads are included, the first certificate provided MUST contain the public key used to verify the AUTH field (§1.2, §3.6)
MUST 1.2 - The initial exchanges
RFC7296-1.2-3Both parties in the IKE_AUTH exchange MUST verify that all signatures and Message Authentication Codes (MACs) are computed correctly (§1.2)
MUST 1.2 - The initial exchanges
RFC7296-1.2-4If either side uses a shared secret for authentication, the names in the ID payload MUST correspond to the key used to generate the AUTH payload (§1.2)
MUST 1.2 - The initial exchanges
RFC7296-1.2-5If the initiator guesses wrong, the responder will respond with a Notify payload of type INVALID_KE_PAYLOAD indicating the selected group. In this case, the initiator MUST retry the IKE_SA_INIT with the corrected Diffie-Hellman group (§1.2)
MUST 1.2 - The initial exchanges
RFC7296-1.2-6The initiator MUST again propose its full set of acceptable cryptographic suites because the rejection message was unauthenticated and otherwise an active attacker could trick the endpoints into negotiating a weaker suite than a stronger one that they both prefer (§1.2)
MUST 1.2 - The initial exchanges
RFC7296-2.4-11An endpoint MUST conclude that the other endpoint has failed only when repeated attempts to contact it have gone unanswered for a timeout period or when a cryptographically protected INITIAL_CONTACT notification is received on a different IKE SA to the same authenticated identity (§2.4)
MUST 2.4
RFC7296-2.4-12Implementations MUST limit the rate at which they take actions based on unprotected messages (§2.4)
MUST 2.4
RFC7296-2.4-13To be a good network citizen, retransmission times MUST increase exponentially to avoid flooding the network and making an existing congestion situation worse (§2.4)
MUST 2.4
RFC7296-2.7-2Each proposal contains one protocol. If a proposal is accepted, the SA response MUST contain the same protocol (§2.7)
MUST 2.7
RFC7296-2.10-4Nonces used in IKEv2 MUST be randomly chosen (§2.10)
MUST 2.10
RFC7296-2.11-1An implementation MUST accept incoming requests even if the source port is not 500 or 4500 (§2.11, §2.23)
MUST 2.11
RFC7296-2.11-2MUST respond to the address and port from which the request was received (§2.11)
MUST 2.11
RFC7296-2.11-3It MUST specify the address and port at which the request was received as the source address and port in the response (§2.11)
MUST 2.11
RFC7296-2.16-11these protocols are typically used to authenticate the initiator to the responder and MUST be used in conjunction with a public-key-signature-based authentication of the responder to the initiator. (§2.16)
MUST 2.16
RFC7296-2.16-6Extensible authentication is implemented in IKE as additional IKE_AUTH exchanges that MUST be completed in order to initialize the IKE SA (§2.16)
MUST 2.16
RFC7296-2.16-7This shared key generated during an IKE exchange MUST NOT be used for any other purpose (§2.16)
MUST NOT 2.16
RFC7296-2.23-7Both the IKE initiator and responder MUST include in their IKE_SA_INIT packets Notify payloads of type NAT_DETECTION_SOURCE_IP and NAT_DETECTION_DESTINATION_IP (§2.23)
MUST 2.23
RFC7296-2.23-8An IPsec endpoint that discovers a NAT between it and its correspondent (as described below) MUST send all subsequent traffic from port 4500 (§2.23)
MUST 2.23
RFC7296-2.23-9UDP encapsulation MUST NOT be done on port 500 (§2.23)
MUST NOT 2.23
negativeunit/verifyTestEncapPortsAreExpressible
RFC7296-2.23-10If Network Address Translation Traversal (NAT-T) is supported (that is, if NAT_DETECTION_*_IP payloads were exchanged during IKE_SA_INIT), all devices MUST be able to receive and process both UDP-encapsulated ESP and non-UDP-encapsulated ESP packets at any time. (§2.23)
MUST 2.23
RFC7296-2.23-11Implementations MUST process received UDP-encapsulated ESP packets even when no NAT was detected (§2.23)
MUST 2.23
RFC7296-2.23-12To tunnel ESP packets over UDP port 4500, the ESP header immediately follows the UDP header. Since the first four octets of the ESP header contain the SPI, and the SPI cannot validly be zero, it is always possible to distinguish ESP and IKE messages. (§2.23)
MUST 2.23
RFC7296-2.23-13When such a validated packet is found, a host that does not support other methods of recovery such as IKEv2 Mobility and Multihoming (MOBIKE) [MOBIKE], and that is not behind a NAT, SHOULD send all packets (including retransmission packets) to the IP address and port in the validated packet, and SHOULD store this as the new address and port combination for the SA (that is, they SHOULD dynamically update the address). (§2.23)
SHOULD 2.23
RFC7296-3.9-2Nonce values MUST NOT be reused (§3.9)
MUST NOT 3.9
RFC7296-1.3-2If the responder selects a proposal using a different Diffie-Hellman group (other than NONE), the responder MUST reject the request and indicate its preferred Diffie-Hellman group in the INVALID_KE_PAYLOAD Notify payload (§1.3, §3.4)
MUST 1.3 - The CREATE_CHILD_SA exchange
RFC7296-2.8.2-1The new IKE SA containing the lowest nonce SHOULD be deleted by the node that created it, and the other surviving new IKE SA MUST inherit all the Child SAs (§2.8.2)
MUST 2.8.2
RFC7296-3.3.6-3The initiator of an exchange MUST check that the accepted offer is consistent with one of its proposals, and if not MUST terminate the exchange (§3.3.6)
MUST 3.3.6
RFC7296-1.4-3Control messages that pertain to an IKE SA MUST be sent under that IKE SA. Control messages that pertain to Child SAs MUST be sent under the protection of the IKE SA that generated them (§1.4)
MUST 1.4 - The INFORMATIONAL exchange
RFC7296-1.4-4The recipient of an INFORMATIONAL exchange request MUST send some response; otherwise, the sender will assume the message was lost in the network and will retransmit it (§1.4, §4)
MUST 1.4 - The INFORMATIONAL exchange
RFC7296-1.4-5INFORMATIONAL exchanges MUST ONLY occur after the initial exchanges and are cryptographically protected with the negotiated keys (§1.4)
MUST 1.4 - The INFORMATIONAL exchange
positiveunit/verifyTestDpdProbeIsEncrypted
negativeunit/verifyTestDpdProbeIsEncrypted
RFC7296-1.4.1-6To delete an SA, an INFORMATIONAL exchange with one or more Delete payloads is sent listing the SPIs (as they would be expected in the headers of inbound packets) of the SAs to be deleted. The recipient MUST close the designated SAs (§1.4.1)
MUST 1.4.1 - Deleting an SA
RFC7296-1.4.1-7If a node receives a delete request for SAs for which it has already issued a delete request, it MUST delete the outgoing SAs while processing the request and the incoming SAs while processing the response (§1.4.1)
MUST 1.4.1 - Deleting an SA
RFC7296-1.5-1This message is not part of an INFORMATIONAL exchange, and the receiving node MUST NOT respond to it because doing so could cause a message loop (§1.5)
MUST NOT 1.5 - Informational messages outside an IKE SA
RFC7296-2.12-1Achieving perfect forward secrecy requires that when a connection is closed, each endpoint MUST forget not only the keys used by the connection but also any information that could be used to recompute those keys (§2.12)
MUST 2.12
RFC7296-2.24-1tunnel encapsulators and decapsulators for all tunnel mode SAs created by IKEv2 MUST support the ECN full-functionality option for tunnels specified in [ECN] (§2.24)
MUST 2.24
RFC7296-2.24-2MUST implement the tunnel encapsulation and decapsulation processing specified in [IPSECARCH] to prevent discarding of ECN congestion indications. (§2.24)
MUST 2.24
RFC7296-2.16-12For EAP methods that create a shared key as a side effect of authentication, that shared key MUST be used by both the initiator and responder to generate AUTH payloads in messages 7 and 8 using the syntax for shared secrets specified in Section 2.15 (§2.16)
MUST 2.16
RFC7296-2.16-13Following such an extended exchange, the EAP AUTH payloads MUST be included in the two messages following the one containing the EAP Success message (§2.16)
MUST 2.16
RFC7296-2.16-14Once the protocol exchange defined by the chosen EAP authentication method has successfully terminated, the responder MUST send an EAP payload containing the Success message (§2.16)
MUST 2.16
positiveunit/verifyTestEapResultSuccessIsSent
negativeunit/verifyTestEapResultFailureIsSent
RFC7296-2.16-15Similarly, if the authentication method has failed, the responder MUST send an EAP payload containing the Failure message (§2.16)
MUST 2.16
positiveunit/verifyTestEapResultFailureIsSent
RFC7296-3.1-13* I (Initiator) - This bit MUST be set in messages sent by the original initiator of the IKE SA and MUST be cleared in messages sent by the original responder. (§3.1)
MUST 3.1
RFC7296-3.5-5A fully-qualified domain name string. An example of an ID_FQDN is "example.com". The string MUST NOT contain any terminators (e.g., NULL, CR, etc.). (§3.5)
MUST NOT 3.5
positiveunit/verifyTestWp2IDTerminatorRefused
RFC7296-3.5-6A fully-qualified RFC 822 email address string. An example of a ID_RFC822_ADDR is "jsmith@example.com". The string MUST NOT contain any terminators. (§3.5)
MUST NOT 3.5
positiveunit/verifyTestWp2IDTerminatorRefused
RFC7296-1.4.1-1When an SA is closed, both members of the pair MUST be closed (that is, deleted). Each endpoint MUST close its incoming SAs and allow the other endpoint to close the other SA in each pair (§1.4.1)
MUST 1.4.1 - Deleting an SA
RFC7296-1.4.1-4In that case, the responses MUST NOT include Delete payloads for the deleted SAs, since that would result in duplicate deletion and could in theory delete the wrong SA. (§1.4.1)
MUST NOT 1.4.1 - Deleting an SA
RFC7296-1.4.1-5A node MAY refuse to accept incoming data on half-closed connections but MUST NOT unilaterally close them and reuse the SPIs (§1.4.1)
MUST NOT 1.4.1 - Deleting an SA
RFC7296-2.4-9If a system creates Child SAs that can fail independently from one another without the associated IKE SA being able to send a delete message, then the system MUST negotiate such Child SAs using separate IKE SAs (§2.4)
MUST 2.4
RFC7296-2.4-10If an IKE endpoint chooses to delete Child SAs, it MUST send Delete payloads to the other end notifying it of the deletion (§2.4)
MUST 2.4
RFC7296-2.16-5If EAP methods that do not generate a shared key are used, the AUTH payloads in messages 7 and 8 MUST be generated using SK_pi and SK_pr, respectively (§2.16)
MUST 2.16
RFC7296-2.16-16EAP methods that do not establish a shared key SHOULD NOT be used, as they are subject to a number of man-in-the-middle attacks [EAPMITM] if these EAP methods are used in other protocols that do not use a server-authenticated tunnel. (§2.16)
SHOULD NOT 2.16
RFC7296-3.4-1The length of the Diffie-Hellman public value for MODP groups MUST be equal to the length of the prime modulus over which the exponentiation was performed, prepending zero bits to the value if necessary (§3.4)
MUST 3.4
RFC7296-1.3-1If a CREATE_CHILD_SA exchange includes a KEi payload, at least one of the SA offers MUST include the Diffie-Hellman group of the KEi (§1.3)
MUST 1.3 - The CREATE_CHILD_SA exchange
RFC7296-2.1-3The responder MUST never retransmit a response unless it receives a retransmission of the request (§2.1)
MUST 2.1 - Retransmission timers
RFC7296-2.1-4In that event, the responder MUST ignore the retransmitted request except insofar as it causes a retransmission of the response (§2.1)
MUST 2.1 - Retransmission timers
RFC7296-2.1-5The initiator MUST remember each request until it receives the corresponding response. The responder MUST remember each response until it receives a request whose sequence number is larger than or equal to the sequence number in the response plus its window size (§2.1, §2.3)
MUST 2.1 - Retransmission timers
RFC7296-2.1-6If the responder receives a retransmitted request for which it has already forgotten the response, it MUST ignore the request (and not, for example, attempt constructing a new response) (§2.1)
MUST 2.1 - Retransmission timers
RFC7296-2.1-7IKE is a reliable protocol: the initiator MUST retransmit a request until it either receives a corresponding response or deems the IKE SA to have failed (§2.1)
MUST 2.1 - Retransmission timers
RFC7296-2.1-8A retransmission from the initiator MUST be bitwise identical to the original request (§2.1)
MUST 2.1 - Retransmission timers
RFC7296-2.2-1Retransmission of a message MUST use the same Message ID as the original message (§2.2)
MUST 2.2 - Message ID sequence numbers
RFC7296-2.2-2In the unlikely event that Message IDs grow too large to fit in 32 bits, the IKE SA MUST be closed or rekeyed (§2.2)
MUST 2.2 - Message ID sequence numbers
RFC7296-2.2-3Each endpoint in the IKE Security Association maintains two "current" Message IDs: the next one to be used for a request it initiates and the next one it expects to see in a request from the other end. (§2.2)
MUST 2.2 - Message ID sequence numbers
RFC7296-2.3-2An IKE endpoint MUST wait for a response to each of its messages before sending a subsequent message unless it has received a SET_WINDOW_SIZE Notify message from its peer (§2.3)
MUST 2.3 - Window size for overlapping requests
positiveunit/verifyTestWinOneRequestPerTick
positiveunit/verifyTestWinTeardownDoesNotHang
negativeunit/verifyTestWinOneRequestPerTick
negativeunit/verifyTestWinTeardownDoesNotHang
RFC7296-2.3-4An IKE endpoint MUST NOT exceed the peer's stated window size for transmitted IKE requests (§2.3)
MUST NOT 2.3 - Window size for overlapping requests
positiveunit/verifyTestWinResponseReleasesSlot
negativeunit/verifyTestWinResponseReleasesSlot
RFC7296-2.3-5This Notify message MUST NOT be sent in a response; the invalid request MUST NOT be acknowledged (§2.3)
MUST NOT 2.3 - Window size for overlapping requests
RFC7296-2.3-7The data associated with a SET_WINDOW_SIZE notification MUST be 4 octets long and contain the big endian representation of the number of messages the sender promises to keep (§2.3)
MUST 2.3 - Window size for overlapping requests
RFC7296-2.3-8An IKE endpoint MUST be prepared to accept and process a request while it has a request outstanding in order to avoid a deadlock in this situation (§2.3)
MUST 2.3 - Window size for overlapping requests
RFC7296-2.3-9Sending this notification is OPTIONAL, and notifications of this type MUST be rate limited (§2.3)
MUST 2.3 - Window size for overlapping requests
RFC7296-2.25-1When a peer receives a TEMPORARY_FAILURE notification, it MUST NOT immediately retry the operation; it MUST wait so that the sender may complete whatever operation caused the temporary condition (§2.25)
MUST NOT 2.25
RFC7296-2.8-5If an SA has expired or is about to expire and rekeying attempts using the mechanisms described here fail, an implementation MUST close the IKE SA and any associated Child SAs and then MAY start new ones (§2.8)
MUST 2.8
RFC7296-2.8-6After the new equivalent IKE SA is created, the initiator deletes the old IKE SA, and the Delete payload to delete itself MUST be the last request sent over the old IKE SA (§2.8)
MUST 2.8
RFC7296-2.8-7The responder to a CREATE_CHILD_SA MUST be prepared to accept messages on an SA before sending its response to the creation request, so there is no ambiguity for the initiator (§2.8)
MUST 2.8
RFC7296-2.8.1-1When there are two SAs eligible to receive packets, a node MUST accept incoming packets through either SA (§2.8.1)
MUST 2.8.1
RFC7296-2.18-2The new IKE SA MUST reset its message counters to 0 (§2.18)
MUST 2.18
RFC7296-2.18-3implementations MUST perform a new Diffie-Hellman exchange when rekeying the IKE SA. In other words, an initiator MUST NOT propose the value "NONE" for the Diffie-Hellman transform, and a responder MUST NOT accept such a proposal. (§2.18)
MUST NOT 2.18
RFC7296-3.16-1Identifier (1 octet) - Used in PPP to distinguish replayed messages from repeated ones. Since in IKE, EAP runs over a reliable protocol, the Identifier serves no function here. In a response message, this octet MUST be set to match the identifier in the corresponding request. (§3.16)
MUST 3.16 - The EAP payload and the EAP message format
RFC7296-3.16-2Length (2 octets, unsigned integer) - The length of the EAP message. MUST be four less than the Payload Length of the encapsulating payload. (§3.16)
MUST 3.16 - The EAP payload and the EAP message format
RFC7296-3.16-3For other codes, the EAP message length MUST be four octets and the Type and Type_Data fields MUST NOT be present. (§3.16)
MUST 3.16 - The EAP payload and the EAP message format
RFC7296-3.16-4In a Response (2) message, Type MUST either be Nak or match the type of the data requested (§3.16)
MUST 3.16 - The EAP payload and the EAP message format
RFC7296-1.7-2This document adds the restriction in Section 2.13 that all pseudorandom functions (PRFs) used with IKEv2 MUST take variable- sized keys. (§1.7)
MUST 1.7 - The change list against RFC 4306
RFC7296-2-1All IKEv2 implementations MUST be able to send, receive, and process IKE messages that are up to 1280 octets long (§2)
MUST 2 - IKE protocol details and variations
positiveunit/verifyTestMessageHandles1280Octets
negativeunit/verifyTestMessageHandles1280Octets
RFC7296-2.5-1The minor version number indicates new capabilities, and MUST be ignored by a node with a smaller minor version number, but used for informational purposes by the node with the larger minor version number (§2.5, §3.1)
MUST 2.5
RFC7296-2.5-2If an endpoint receives a message with a higher major version number, it MUST drop the message (§2.5, §3.1)
MUST 2.5
RFC7296-2.5-6Also, for forward compatibility, all fields marked RESERVED MUST be set to zero by an implementation running version 2.0 (§2.5, §3.2, §3.3.1, §3.3.2, §3.5, §3.8, §3.13, §3.15, §3.15.1)
MUST 2.5
RFC7296-2.5-7Also, for forward compatibility, all fields marked RESERVED MUST be set to zero by an implementation running version 2.0, and their content MUST be ignored by an implementation running version 2.0 (§2.5)
MUST 2.5
RFC7296-2.5-8Similarly, payload types that are not defined are reserved for future use; implementations of a version where they are undefined MUST skip over those payloads and ignore their contents. (§2.5)
MUST 2.5
RFC7296-2.5-9If the critical flag is set and the payload type is unrecognized, the message MUST be rejected (§2.5, §4)
MUST 2.5
RFC7296-2.5-11If the critical flag is not set and the payload type is unsupported, that payload MUST be ignored (§2.5)
MUST 2.5
RFC7296-2.5-13implementations MUST NOT reject as invalid a message with those payloads in any other order. (§2.5)
MUST NOT 2.5
RFC7296-2.5-14If an endpoint supports major version n, and major version m, it MUST support all versions between n and m (§2.5)
MUST 2.5
RFC7296-2.5-15If it receives a message with a major version that it supports, it MUST respond with that version number (§2.5)
MUST 2.5
RFC7296-2.5-16If they mistakenly (perhaps through an active attacker sending error messages) negotiate to version n, then both will notice that the other side can support a higher version number, and they MUST break the connection and reconnect using version n+1 (§2.5)
MUST 2.5
RFC7296-2.5-17Payloads sent in IKE response messages MUST NOT have the critical flag set (§2.5)
MUST NOT 2.5
RFC7296-2.5-18the response to the IKE request containing that payload MUST include a Notify payload UNSUPPORTED_CRITICAL_PAYLOAD, indicating an unsupported critical payload was included. In that Notify payload, the Notification Data contains the one-octet payload type. (§2.5)
MUST 2.5
RFC7296-2.21.2-1Note, however, that request messages that contain an unsupported critical payload, or where the whole message is malformed (rather than just bad payload contents), MUST be rejected in their entirety, and MUST only lead to an UNSUPPORTED_CRITICAL_PAYLOAD or INVALID_SYNTAX Notification sent as a response. (§2.21.2)
MUST 2.21.2
RFC7296-2.21.2-2Specifically, a responder may include all the payloads associated with authentication (IDr, CERT, and AUTH) while sending error notifications for the piggybacked exchanges (FAILED_CP_REQUIRED, NO_PROPOSAL_CHOSEN, and so on), and the initiator MUST NOT fail the authentication because of this. (§2.21.2)
MUST NOT 2.21.2
RFC7296-2.21.2-3Extension documents may define new error notifications with these semantics, but MUST NOT use them unless the peer has been shown to understand them, such as by using the Vendor ID payload (§2.21.2)
MUST NOT 2.21.2
RFC7296-2.21.3-1After the IKE SA is authenticated, all requests having errors MUST result in a response notifying the other end of the error (§2.21.3)
MUST 2.21.3
RFC7296-2.21.4-1If the message is marked as a response, the node can audit the suspicious event but MUST NOT respond (§2.21.4)
MUST NOT 2.21.4
positivefunctional/verifyipsec-error-notify-no-loop.ci
negativefunctional/verifyipsec-error-notify-no-loop.ci
RFC7296-2.21.4-2If a response is sent, the response MUST be sent to the IP address and port from where it came with the same IKE SPIs and the Message ID copied. (§2.21.4)
MUST 2.21.4
RFC7296-2.21.4-3The response MUST NOT be cryptographically protected (§2.21.4)
MUST NOT 2.21.4
RFC7296-2.21.4-4The response MUST NOT be cryptographically protected and MUST contain an INVALID_IKE_SPI Notify payload. (§2.21.4)
MUST 2.21.4
positivefunctional/verifyipsec-error-notify-no-loop.ci
negativefunctional/verifyipsec-error-notify-no-loop.ci
RFC7296-2.21.4-5A peer receiving such an unprotected Notify payload MUST NOT respond (§2.21.4)
MUST NOT 2.21.4
positiveunit/verifyTestNtfEmitterIsAFixedPoint
negativeunit/verifyTestNtfEmitterIsAFixedPoint
positivefunctional/verifyipsec-error-notify-no-loop.ci
negativefunctional/verifyipsec-error-notify-no-loop.ci
RFC7296-2.21.4-6A peer receiving such an unprotected Notify payload MUST NOT respond and MUST NOT change the state of any existing SAs. (§2.21.4)
MUST NOT 2.21.4
RFC7296-2.21.4-7The recipient MUST NOT change the state of any SAs as a result, but may wish to audit the event to aid in diagnosing malfunctions. (§2.21.4)
MUST NOT 2.21.4
RFC7296-2.21.4-8A node receiving a suspicious message from an IP address (and port, if NAT traversal is used) with which it has an IKE SA SHOULD send an IKE Notify payload in an IKE INFORMATIONAL exchange over that SA. (§2.21.4)
SHOULD 2.21.4
positiveno testno positive test
negativeno testno negative test

{gap}: Ze sends no protected Notify over an existing IKE SA when a suspicious message arrives from that peer's address. An unprotected message at a cached Message ID is dropped and counted (inbound.go, countErrorNotifySuppressed "unprotected-retransmit"), and an unprotected INVALID_IKE_SPI changes nothing, but neither path starts an INFORMATIONAL exchange over the SA

RFC7296-3.10.1-1Types in the range 0 - 16383 are intended for reporting errors. An implementation receiving a Notify payload with one of these types that it does not recognize in a response MUST assume that the corresponding request has failed entirely. (§3.10.1)
MUST 3.10.1
RFC7296-3.10.1-2Unrecognized error types in a request and status types in a request or response MUST be ignored, and they should be logged (§3.10.1)
MUST 3.10.1
RFC7296-3.10.1-3To avoid leaking information to someone probing a node, this status MUST be sent in response to any error not covered by one of the other status types. (§3.10.1)
MUST 3.10.1
RFC7296-3.10.1-4Notify payloads with status types MAY be added to any message and MUST be ignored if not recognized (§3.10.1)
MAY 3.10.1
positiveno testno positive test
negativeno testno negative test
RFC7296-2.6-2Each endpoint chooses one of the two SPIs and MUST choose them so as to be unique identifiers of an IKE SA (§2.6)
MUST 2.6
positiveunit/verifyTestSPIsAreUniqueIdentifiers
negativeunit/verifyTestSPIsAreUniqueIdentifiers
RFC7296-2.6-3The data associated with this notification MUST be between 1 and 64 octets in length (inclusive) (§2.6)
MUST 2.6
RFC7296-2.6-4If the IKE_SA_INIT response includes the COOKIE notification, the initiator MUST then retry the IKE_SA_INIT request, and include the COOKIE notification containing the received data as the first payload, and all other payloads unchanged (§2.6)
MUST 2.6
RFC7296-2.6-5When one party receives an IKE_SA_INIT request containing a cookie whose contents do not match the value expected, that party MUST ignore the cookie and process the message as if no cookie had been included; usually this means sending a response containing a new cookie (§2.6)
MUST 2.6
RFC7296-2.6.1-1Implementations SHOULD support this shorter exchange, but MUST NOT fail if other implementations do not support this shorter exchange (§2.6.1)
MUST NOT 2.6.1
RFC7296-2.10-2Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 bits in size (§2.10)
MUST 2.10
positiveunit/verifyTestNonceLengthBounds
negativeunit/verifyTestNonceLengthBounds
RFC7296-2.10-3Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 bits in size, and MUST be at least half the key size of the negotiated pseudorandom function (PRF). (§2.10)
MUST 2.10
RFC7296-2.13-1For algorithms that accept a variable-length key, a fixed key size MUST be specified as part of the cryptographic transform negotiated (§2.13)
MUST 2.13
RFC7296-2.13-3The preferred key size MUST be used as the length of SK_d, SK_pi, and SK_pr (§2.13, §2.14)
MUST 2.13
RFC7296-2.13-4Other types of PRFs MUST specify their preferred key size (§2.13)
MUST 2.13
RFC7296-2.15-1The management interface by which the shared secret is provided MUST accept ASCII strings of at least 64 octets (§2.15)
MUST 2.15
RFC7296-2.15-2MUST NOT add a null terminator before using them as shared secrets (§2.15)
MUST NOT 2.15
RFC7296-2.17-1keying material for each Child SA MUST be taken from the expanded KEYMAT using the following rules: o All keys for SAs carrying data from the initiator to the responder are taken before SAs going from the responder to the initiator. (§2.17)
MUST 2.17
positiveunit/verifyTestChildSAKeymatOrder
negativeunit/verifyTestChildSAKeymatOrder
RFC7296-2.17-2For ESP and AH, [IPSECARCH] defines the order, namely: the encryption key (if any) MUST be taken from the first bits and the integrity key (if any) MUST be taken from the remaining bits. (§2.17)
MUST 2.17
positiveunit/verifyTestChildSAKeymatOrder
negativeunit/verifyTestChildSAKeymatOrder
RFC7296-3.1-1An Encrypted payload MUST be the last payload in a packet (§3.1, §3.14)
MUST 3.1
positiveunit/verifyTestSKIsLastAndNeverNested
negativeunit/verifyTestSKIsLastAndNeverNested
RFC7296-3.1-2an Encrypted payload MUST NOT contain another Encrypted payload (§3.1)
MUST NOT 3.1
positiveunit/verifyTestSKIsLastAndNeverNested
negativeunit/verifyTestSKIsLastAndNeverNested
RFC7296-3.1-3Initiator's SPI (8 octets) - A value chosen by the initiator to identify a unique IKE Security Association. This value MUST NOT be zero. (§3.1)
MUST NOT 3.1
RFC7296-3.1-4Responder's SPI (8 octets) - A value chosen by the responder to identify a unique IKE Security Association. This value MUST be zero in the first message of an IKE initial exchange (including repeats of that message including a cookie). (§3.1)
MUST 3.1
RFC7296-3.1-5Implementations based on this version of IKE MUST set the major version to 2 (§3.1)
MUST 3.1
RFC7296-3.1-6Implementations based on this version of IKE MUST set the minor version to 0 (§3.1)
MUST 3.1
RFC7296-3.1-7'X' bits MUST be cleared when sending (§3.1)
MUST 3.1
RFC7296-3.1-8'X' bits MUST be cleared when sending and MUST be ignored on receipt. (§3.1)
MUST 3.1
positiveunit/verifyTestXBitsIgnoredOnReceipt
negativeunit/verifyTestXBitsIgnoredOnReceipt
RFC7296-3.1-9R (Response) - This bit indicates that this message is a response to a message containing the same Message ID. This bit MUST be cleared in all request messages and MUST be set in all responses. (§3.1)
MUST 3.1
RFC7296-3.1-11V (Version) - This bit indicates that the transmitter is capable of speaking a higher major version number of the protocol than the one indicated in the major version number field. Implementations of IKEv2 MUST clear this bit when sending and MUST ignore it in incoming messages. (§3.1)
MUST 3.1
negativeunit/verifyTestXBitsIgnoredOnReceipt
RFC7296-3.1-12An IKE endpoint MUST NOT generate a response to a message that is marked as being a response (with one exception; see Section 2.21.2) (§3.1)
MUST NOT 3.1
RFC7296-3.2-2Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type. MUST be ignored by the recipient if the recipient understands the payload type code. (§3.2)
MUST 3.2
RFC7296-3.2-3all implementations MUST understand all payload types defined in this document (§3.2)
MUST 3.2
RFC7296-3.2-4Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type. MUST be ignored by the recipient if the recipient understands the payload type code. MUST be set to zero for payload types defined in this document. (§3.2)
MUST 3.2
RFC7296-3.2-5o Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. (§3.2)
MUST 3.2
RFC7296-3.2-6Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type. (§3.2)
MUST 3.2
RFC7296-3.3-3An SA payload MAY contain multiple proposals. If there is more than one, they MUST be ordered from most preferred to least preferred (§3.3)
MUST 3.3
positiveunit/verifyTestProposalOrderPreserved
negativeunit/verifyTestProposalOrderPreserved
RFC7296-3.3-4When parsing an SA, an implementation MUST check that the total Payload Length is consistent with the payload's internal lengths and counts (§3.3)
MUST 3.3
RFC7296-3.3-5Each structure MUST have a proposal number one (1) greater than the previous structure. The first Proposal in the initiator's SA payload MUST have a Proposal Num of one (1) (§3.3, §3.3.1)
MUST 3.3
positiveunit/verifyTestPropProposalNumbering
negativeunit/verifyTestPropProposalNumbering
RFC7296-3.3-6A transform MUST NOT have multiple attributes of the same type (§3.3)
MUST NOT 3.3
RFC7296-3.3-7To propose alternate values for an attribute (for example, multiple key sizes for the AES encryption algorithm), an implementation MUST include multiple transforms with the same Transform Type each with a single Attribute. (§3.3)
MUST 3.3
RFC7296-3.3.1-1When a proposal is accepted, the proposal number in the SA payload MUST match the number on the proposal sent that was accepted (§3.3.1)
MUST 3.3.1
RFC7296-3.3.1-2o SPI Size (1 octet) - For an initial IKE SA negotiation, this field MUST be zero; the SPI is obtained from the outer header. (§3.3.1)
MUST 3.3.1
RFC7296-3.3.3-1A compliant implementation MUST understand all mandatory and optional types for each protocol it supports (§3.3.3)
MUST 3.3.3
RFC7296-3.3.4-2Upon receipt of a payload with a set of Transform IDs, the implementation MUST compare the transmitted Transform IDs against those locally configured via the management controls, to verify that the proposed suite is acceptable based on local policy (§3.3.4)
MUST 3.3.4
RFC7296-3.3.4-3The implementation MUST reject SA proposals that are not authorized by these IKE suite controls (§3.3.4)
MUST 3.3.4
RFC7296-3.3.5-1Attributes described as fixed length MUST NOT be encoded using the variable-length encoding unless that length exceeds two bytes (§3.3.5)
MUST NOT 3.3.5
RFC7296-3.3.5-2Variable-length attributes MUST NOT be encoded as fixed-length even if their value can fit into two octets (§3.3.5)
MUST NOT 3.3.5
RFC7296-3.3.5-3The Key Length attribute specifies the key length in bits (MUST use network byte order) (§3.3.5)
MUST 3.3.5
RFC7296-3.3.5-4The Key Length attribute MUST NOT be used with transforms that use a fixed-length key (§3.3.5)
MUST NOT 3.3.5
RFC7296-3.3.5-5o Some transforms specify that the Key Length attribute MUST be always included (omitting the attribute is not allowed, and proposals not containing it MUST be rejected). (§3.3.5)
MUST 3.3.5
RFC7296-3.3.6-4If the responder receives a proposal that contains a Transform Type it does not understand, or a proposal that is missing a mandatory Transform Type, it MUST consider this proposal unacceptable; however, other proposals in the same SA payload are processed as usual (§3.3.6)
MUST 3.3.6
RFC7296-3.3.6-5Similarly, if the responder receives a transform that it does not understand, or one that contains a Transform Attribute it does not understand, it MUST consider this transform unacceptable; other transforms with the same Transform Type are processed as usual. (§3.3.6)
MUST 3.3.6
RFC7296-3.3.6-7Any attributes of a selected transform MUST be returned unmodified (§3.3.6)
MUST 3.3.6
RFC7296-3.9-1The size of the Nonce Data MUST be between 16 and 256 octets, inclusive (§3.9)
MUST 3.9
positiveunit/verifyTestNonceLengthBounds
negativeunit/verifyTestNonceLengthBounds
RFC7296-3.10-3For a notification concerning the IKE SA, the SPI Size MUST be zero and the field must be empty. (§3.10)
MUST 3.10
RFC7296-3.10-4For notifications concerning Child SAs, this field MUST contain either (2) to indicate AH or (3) to indicate ESP. (§3.10)
MUST 3.10
RFC7296-3.10-5If the SPI field is empty, this field MUST be sent as zero and MUST be ignored on receipt. (§3.10)
MUST 3.10
RFC7296-3.11-1each SPI MUST be for the same protocol. Mixing of protocol identifiers MUST NOT be performed in the Delete payload. (§3.11)
MUST NOT 3.11
RFC7296-3.11-2SPI Size (1 octet) - Length in octets of the SPI as defined by the protocol ID. It MUST be zero for IKE (SPI is in message header) or four for AH and ESP. (§3.11)
MUST 3.11
RFC7296-3.12-2Unfamiliar Vendor IDs MUST be ignored (§3.12)
MUST 3.12
RFC7296-3.12-3Writers of documents who wish to extend this protocol MUST define a Vendor ID payload to announce the ability to implement the extension in the document (§3.12)
MUST 3.12
RFC7296-3.12-4A Vendor ID payload MUST NOT change the interpretation of any information defined in this specification (i.e., the critical bit MUST be set to 0) (§3.12)
MUST NOT 3.12
RFC7296-3.14-2Senders MUST select a new unpredictable IV for every message (§3.14)
MUST 3.14
RFC7296-3.14-3Initialization Vector - For CBC mode ciphers, the length of the initialization vector (IV) is equal to the block length of the underlying encryption algorithm. Senders MUST select a new unpredictable IV for every message; recipients MUST accept any value. (§3.14)
MUST 3.14
RFC7296-3.14-4Padding MAY contain any value chosen by the sender, and MUST have a length that makes the combination of the payloads, the Padding, and the Pad Length to be a multiple of the encryption block size (§3.14)
MUST 3.14
RFC7296-3.14-5the recipient MUST accept any length that results in proper alignment (§3.14)
MUST 3.14
RFC7296-3.14-6The checksum MUST be computed over the encrypted message (§3.14)
MUST 3.14
RFC7296-3.14-7Peers MUST NOT negotiate transforms for which no such specification exists (§3.14)
MUST NOT 3.14
RFC7296-5-2Though the security of negotiated Child SAs does not depend on the strength of the encryption and integrity protection negotiated in the IKE SA, implementations MUST NOT negotiate NONE as the IKE integrity protection algorithm or ENCR_NULL as the IKE encryption algorithm. (§5)
MUST NOT 5 - Security considerations
RFC7296-5-3For this reason, a PRF whose output is less than 128 bits (e.g., 3DES-CBC) MUST NOT be used with this protocol. (§5)
MUST NOT 5 - Security considerations
RFC7296-2.19-1Since the IKE_AUTH exchange creates an IKE SA and a Child SA, the IRAC MUST request the IRAS-controlled address (and optionally other information concerning the protected network) in the IKE_AUTH exchange (§2.19, §4)
MUST 2.19
RFC7296-2.19-4CP(CFG_REQUEST) MUST contain at least an INTERNAL_ADDRESS attribute (either IPv4 or IPv6) but MAY contain any number of additional attributes the initiator wants returned in the response (§2.19)
MUST 2.19
RFC7296-2.20-1An IKE implementation MAY decline to give out version information prior to authentication or even after authentication in case some implementation is known to have some security weakness. In that case, it MUST either return an empty string or no CP payload if CP is not supported. (§2.20)
MUST 2.20
RFC7296-3.15.1-2An empty INTERNAL_IP4_NETMASK attribute can be included in a CFG_REQUEST to request this information (although the gateway can send the information even when not requested). Non-empty values for this attribute in a CFG_REQUEST do not make sense and thus MUST NOT be included. (§3.15.1)
MUST NOT 3.15.1
RFC7296-3.15.1-5The responder MUST return a Configuration payload if it accepted any of the configuration data, and the Configuration payload MUST contain the attributes that the responder accepted with zero-length data (§3.15.1)
MUST 3.15.1
RFC7296-3.15.1-6Those attributes that it did not accept MUST NOT be in the CFG_ACK Configuration payload (§3.15.1)
MUST NOT 3.15.1
RFC7296-3.15.1-7If no attributes were accepted, the responder MUST return either an empty CFG_ACK payload or a response message without a CFG_ACK payload (§3.15.1)
MUST 3.15.1
RFC7296-2.1-2they SHOULD be able to send, receive, and process messages that are up to 3000 octets long. (§2)
SHOULD 2 - IKE protocol details and variations
positiveno testno positive test
negativeno testno negative test
RFC7296-2.4-2If there has only been outgoing traffic on all of the SAs associated with an IKE SA, it is essential to confirm liveness of the other endpoint to avoid black holes. If no cryptographically protected messages have been received on an IKE SA or any of its Child SAs recently, the system needs to perform a liveness check in order to prevent sending messages to a dead peer. (§2.4)
SHOULD 2.4
RFC7296-2.4-3Since IKE is designed to operate in spite of DoS attacks from the network, an endpoint MUST NOT conclude that the other endpoint has failed based on any routing information (e.g., ICMP messages) or IKE messages that arrive without cryptographic protection (e.g., Notify messages complaining about unknown SPIs). (§2.4)
MUST NOT 2.4
RFC7296-2.4-4The INITIAL_CONTACT notification, if sent, MUST be in the first IKE_AUTH request or response, not as a separate exchange afterwards (§2.4)
MUST 2.4
RFC7296-2.8-3To reduce the probability of this happening, the timing of rekeying requests SHOULD be jittered (delayed by a random amount of time after the need for rekeying is noticed). (§2.8.1)
SHOULD 2.8.1
positiveno testno positive test
negativeno testno negative test
RFC7296-3.4-2This Diffie-Hellman Group Num MUST match a Diffie-Hellman group specified in a proposal in the SA payload that is sent in the same message (§3.4)
MUST 3.4
RFC7296-3.4-3If none of the proposals in that SA payload specifies a Diffie-Hellman group, the KE payload MUST NOT be present (§3.4)
MUST NOT 3.4
RFC7296-3.3.6-8If one of the proposals offered is for the Diffie-Hellman group of NONE, and the responder selects that Diffie-Hellman group, then it MUST ignore the initiator's KE payload and omit the KE payload from the response (§3.3.6)
MUST 3.3.6
RFC7296-2.4-14This notification MUST NOT be sent by an entity that may be replicated (§2.4)
MUST NOT 2.4
RFC7296-2.8-8When the lifetime of a Security Association expires, the Security Association MUST NOT be used (§2.8)
MUST NOT 2.8
positiveunit/verifyTestResUnexpiredSAIsUsed
negativeunit/verifyTestResExpiredSAIsNotUsed
RFC7296-4-1If the responder rejects the CREATE_CHILD_SA request with a NO_ADDITIONAL_SAS notification, the implementation MUST be capable of instead deleting the old SA and creating a new one (§4)
MUST 4 - Conformance requirements
RFC7296-2.15-3It MUST also accept a hex encoding of the shared secret (§2.15)
MUST 2.15
RFC7296-3.3.4-4All implementations of IKEv2 MUST include a management facility that enables a user or system administrator to specify the suites that are acceptable for use with IKE (§3.3.4)
MUST 3.3.4
RFC7296-3.5-2To assure maximum interoperability, implementations MUST be configurable to send at least one of ID_IPV4_ADDR, ID_FQDN, ID_RFC822_ADDR, or ID_KEY_ID (§3.5)
MUST 3.5
RFC7296-3.5-3To assure maximum interoperability, implementations MUST be configurable to send at least one of ID_IPV4_ADDR, ID_FQDN, ID_RFC822_ADDR, or ID_KEY_ID, and MUST be configurable to accept all of these four types. (§3.5)
MUST 3.5
RFC7296-3.5-4IPv6-capable implementations MUST additionally be configurable to accept ID_IPV6_ADDR (§3.5)
MUST 3.5
RFC7296-3.6-1Implementations MUST be capable of being configured to send and accept up to four X.509 certificates in support of authentication (§3.6)
MUST 3.6
RFC7296-3.6-2and also MUST be capable of being configured to send and accept the two Hash and URL formats (with HTTP URLs). (§3.6)
MUST 3.6
RFC7296-3.6-3Implementations MUST support the "http:" scheme for hash-and-URL lookup (§3.6, §1.7)
MUST 3.6
RFC7296-4-4For an implementation to be called conforming to this specification, it MUST be possible to configure it to accept the following: o Public Key Infrastructure using X.509 (PKIX) Certificates containing and signed by RSA keys of size 1024 or 2048 bits, where the ID passed is any of ID_KEY_ID, ID_FQDN, ID_RFC822_ADDR, or ID_DER_ASN1_DN. o Shared key authentication where the ID passed is any of ID_KEY_ID, ID_FQDN, or ID_RFC822_ADDR. (§4)
MUST 4 - Conformance requirements
RFC7296-4-5Every implementation MUST be capable of doing four-message IKE_SA_INIT and IKE_AUTH exchanges establishing two SAs (one for IKE, one for ESP or AH) (§4)
MUST 4 - Conformance requirements

Gaps and untested MUSTs

RequirementStateReason
RFC7296-2.21.4-8 A node receiving a suspicious message from an IP address (and port, if NAT traversal is used) with which it has an IKE SA SHOULD send an IKE Notify payload in an IKE INFORMATIONAL exchange over that SA. (§2.21.4) {gap} Ze sends no protected Notify over an existing IKE SA when a suspicious message arrives from that peer's address. An unprotected message at a cached Message ID is dropped and counted (inbound.go, countErrorNotifySuppressed "unprotected-retransmit"), and an unprotected INVALID_IKE_SPI changes nothing, but neither path starts an INFORMATIONAL exchange over the SA

Proof state

A tagged unit reads unproven where no discrimination record exists for it: nothing in this tree has been observed to break it, so the claim its tag makes is unproven.

RFC7296-1.2-1

The first pair of messages (IKE_SA_INIT) negotiate cryptographic algorithms, exchange nonces, and do a Diffie-Hellman exchange [DH]. The second pair of messages (IKE_AUTH) authenticate the previous messages, exchange identities and certificates, and establish the first Child SA. Parts of these messages are encrypted and integrity protected with keys established through the IKE_SA_INIT exchange, so the identities are hidden from eavesdroppers and all fields in all the messages are authenticated. (§1.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30. Descriptive row kept MUST under D-3. Positive TestRFC7296InitialExchangesCarryWhatSection12Names runs production handleSAInitRequest/handleAuthRequest/handleAuthResponse in X.509 mode over all four captured messages: IKE_SA_INIT req/resp carry SA+KE+Nonce, the single accepted proposal is one offered and both SAs hold it; Ni/Nr held crosswise and distinct; both KE name the negotiated group, each side holds the other's public value, equal SK_d; IKE_AUTH req IDi+CERT+AUTH+ESP SA+TSi+TSr, resp IDr+CERT+AUTH+one ESP proposal+TSi+TSr; identities recorded, both Established, initiator holds negotiated TS. Negative TestRFC7296TamperedIKESAInitFailsIKEAuth ('authenticate the previous messages'): one flipped octet in the stored IKE_SA_INIT copy on either side (PSK and X.509) keeps that side off Established while an untouched control establishes; genuine, it fails if AUTH stopped covering the IKE_SA_INIT octets. Encryption clause: TestInitialExchangeEncryptionBoundary +/-. The negotiation, nonce and DH clauses are positive-only here; their refusals are held by their own rows (3.3.6, 2.10, 1.2 KE/3.4). Records: handleSAInitRequest +, verifyRemoteAuth -, observed red.

PolarityTestKind and tierProof state
negative TestRFC7296TamperedIKESAInitFailsIKEAuth unit/verify revert, verified
negative TestInitialExchangeEncryptionBoundary unit/verify revert, verified
positive TestRFC7296InitialExchangesCarryWhatSection12Names unit/verify revert, verified
positive TestInitialExchangeEncryptionBoundary unit/verify revert, verified

RFC7296-2.6-1

The initial two eight-octet fields in the header, called the "IKE SPIs", are used as a connection identifier at the beginning of IKE packets. (§2.6)

Audit verdict: enforced (the tests do what the requirement demands), fresh. The earlier residual is closed. New TestRFC7296MismatchedResponderSPIReachesNoSAThroughTheReceiveLoops runs the real receive loops over loopback UDP, dispatchInbound (port 500) and dispatchNATTInbound (non-ESP marker): a datagram with the established SA's initiator SPI and a different non-zero responder SPI, sent first, is never delivered to the SA's session (the first delivered datagram must carry the SA's own responder SPI, and no second one arrives); the datagram with the full pair is delivered. Ordering on loopback and the single dispatch goroutine make 'not delivered' distinguishable from 'delayed'. Kept: lookupInbound units TestRFC7296IKESPIPairIdentifiesTheIKESA / TestRFC7296UnknownIKESPIPairMapsToNoSA (full-pair map, zero-rSPI exceptions) and wire header round-trip/short-header tags. Records: dispatchInbound, dispatchNATTInbound, lookupInbound reverts observed red.

PolarityTestKind and tierProof state
negative TestRFC7296MismatchedResponderSPIReachesNoSAThroughTheReceiveLoops unit/verify revert, verified
negative TestRFC7296UnknownIKESPIPairMapsToNoSA unit/verify revert, verified
negative TestDecodeTruncatedHeader unit/verify revert, verified
positive TestRFC7296MismatchedResponderSPIReachesNoSAThroughTheReceiveLoops unit/verify revert, verified
positive TestRFC7296IKESPIPairIdentifiesTheIKESA unit/verify revert, verified
positive TestHeaderRoundtrip unit/verify revert, verified

RFC7296-2.7-1

The responder MUST accept a single proposal or reject them all and return an error. The error is given in a notification of type NO_PROPOSAL_CHOSEN. Each IPsec protocol proposal contains one or more transforms. Each transform contains a Transform Type. The accepted cryptographic suite MUST contain exactly one transform of each type included in the proposal. (§2.7)

Audit verdict: enforced (the tests do what the requirement demands), fresh. RFC 7296 Section 2.7 (rfc/full/rfc7296.txt): "The responder MUST accept a single proposal or reject them all and return an error. The error is given in a notification of type NO_PROPOSAL_CHOSEN." and "The accepted cryptographic suite MUST contain exactly one transform of each type included in the proposal." NegotiateIKE picks one proposal or returns ErrNoProposalChosen (TestProposalNegotiationFirstMatch/NoMatch); TestEsnResponderAnswersOnlyAValueTheOfferCarried asserts SAr2 carries one proposal with exactly one ESN transform of a value the offer carried and maps refusal to NO_PROPOSAL_CHOSEN. Interop: checkESNExtendedOnlyRefused isolates the ESN type (aes256gcm16-esn alone) and asserts ze reached NO_PROPOSAL_CHOSEN (logged by buildChildlessAuthResponse as it builds the refusal notify) with no CHILD_SA on strongSwan and zero XFRM states on both ends, recorded red with the espProposalMatches ESN comparison reverted; checkESNBothOffered asserts both ends keyed, strongSwan's state carries no esn, and traffic crosses, so both ends selected the same single ESN value. Limitation, not a defect: the interop negative reads ze's log, not strongSwan's receipt of the notify; the wire mapping is held by the engine unit test. Re-judged 2026-10-10 (independent judge, mode rejudge): every tagged unit, and the helpers they call (waitLog, listSAs, checkXFRMCount, establish, waitXFRM, xfrmState, verifyTunnelTraffic), is byte-identical between 35c3b0b699 and HEAD; the diff touches the scenarioCheckers registry shape (both ESN scenarios still map to these checkers) and the childless-IKE-SA checkers, and the producer change adds only a fix field to the refusal log line, so the verdict stands.

PolarityTestKind and tierProof state
negative TestProposalNegotiationNoMatch unit/verify unproven
negative TestEsnResponderAnswersOnlyAValueTheOfferCarried unit/verify unproven
negative checkESNExtendedOnlyRefused interop/nightly unproven
positive TestProposalNegotiationFirstMatch unit/verify unproven
positive TestEsnResponderAnswersOnlyAValueTheOfferCarried unit/verify unproven
positive checkESNBothOffered interop/nightly unproven

RFC7296-3.3-1

If an initiator wants to propose both combined- mode ciphers and normal ciphers, it must include two proposals: one will have all the combined-mode ciphers, and the other will have all the normal ciphers with the integrity algorithms. (§3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30 after R30 D-8 (lookups return errors). The sentence (Section 3.3, rfc/full/rfc7296.txt:4308) obliges an initiator offering both classes to use two proposals. Send side: TestESPProposalsNeverMixAEADClass builds a group holding an AEAD and a non-AEAD proposal through the offer builder (now wireESPOffer via the test-only one-value wrapper) and asserts two proposals, AEAD with one ENCR and no INTEG, non-AEAD with one ENCR and one INTEG; a merge or an INTEG beside the AEAD cipher goes red. ipsec.ESPProposal holds one cipher, so the send-side negative is inexpressible (single-polarity positive on that side). Receive side: TestAeadMixInOneProposalIsRefused (negative) feeds espProposalMatches one proposal with the AEAD cipher plus a real INTEG and asserts refusal; TestAeadAloneInItsOwnProposalIsAccepted (positive, absent INTEG and explicit NONE) rules out a comparison that refuses every AEAD proposal. The edit to the negative is mechanical: lookupIntegrity now returns (T, error) and the test fails on the error; assertions and fixture unchanged. Records: negative revert on responder.go::espProposalMatches, observed red. The two positives carry no record (tags predate the record ratchet).

PolarityTestKind and tierProof state
negative TestAeadMixInOneProposalIsRefused unit/verify revert, verified
positive TestAeadAloneInItsOwnProposalIsAccepted unit/verify unproven
positive TestESPProposalsNeverMixAEADClass unit/verify unproven

RFC7296-3.3-2

Combined-mode ciphers include both integrity and encryption in a single encryption algorithm, and MUST either offer no integrity algorithm or a single integrity algorithm of "NONE" (§3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. AEAD ESP proposal built with no INTEG transform, non-AEAD keeps it (TestESPWireProposalAEADIntegNone)

PolarityTestKind and tierProof state
negative TestESPWireProposalAEADIntegNone unit/verify unproven
positive TestESPWireProposalAEADIntegNone unit/verify unproven

RFC7296-3.3.2-1

An SA payload proposing the establishment of an SA has the following mandatory and optional Transform Types. A compliant implementation MUST understand all mandatory and optional types for each protocol it supports (though it need not accept proposals with unacceptable suites). A proposal MAY omit the optional types if the only value for them it will accept is NONE. Protocol Mandatory Types Optional Types --------------------------------------------------- IKE ENCR, PRF, INTEG*, D-H (§3.3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Row quotes the Section 3.3.3 span: the understand-all-types sentence and the IKE line (ENCR, PRF, INTEG*, D-H). IKE line through the responder's selection (wireProposalsToIKE + crypto.NegotiateIKE): a complete proposal is chosen and an AES-GCM proposal without INTEG is chosen with integrity NONE (TestRFC7296PeerIKEProposalWithTheMandatoryTypesIsAccepted); proposals missing ENCR or INTEG draw ErrProposalIncomplete and one missing D-H draws ErrDHGroupNone (TestRFC7296PeerIKEProposalMissingAMandatoryTypeIsRefused); missing PRF draws ErrNoProposalChosen (TestIKEWireProposalHasAllTransforms). TestResponderRequiresKEForDH proves the KE payload, a neighbour. Re-judged 2026-09-30 (leftovers): the weak finding (understand-every-type clause unproven under this id) is closed by tagging TestTftUnknownTransformTypeMakesProposalUnacceptable: positive, a wire IKE proposal of ENCR, PRF, INTEG and D-H is converted and accepted, so every IKE-line type is understood (an ununderstood one would mark the proposal unacceptable); negative, the same proposal plus an unassigned type 6 or an ESN transform is refused with ErrNoProposalChosen, which shows the understood predicate is what admits the four. The negative is the table-bound side (shared with RFC7296-3.3.3-1 and 3.3.6-4); the missing-type negatives above remain this row's direct violations. Records: TransformTypeUnderstoodIKE panic revert observed red both polarities. Judge ran the unit: PASS.

PolarityTestKind and tierProof state
negative TestRFC7296PeerIKEProposalMissingAMandatoryTypeIsRefused unit/verify revert, verified
negative TestIKEWireProposalHasAllTransforms unit/verify revert, verified
negative TestResponderRequiresKEForDH unit/verify revert, verified
negative TestTftUnknownTransformTypeMakesProposalUnacceptable unit/verify revert, verified
positive TestRFC7296PeerIKEProposalWithTheMandatoryTypesIsAccepted unit/verify revert, verified
positive TestIKEWireProposalHasAllTransforms unit/verify revert, verified
positive TestResponderRequiresKEForDH unit/verify revert, verified
positive TestTftUnknownTransformTypeMakesProposalUnacceptable unit/verify revert, verified

RFC7296-1.3.3-1

The KEi payload MUST be included. (§1.3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-12 (independent auditor). SHIFTED by 6e063fb498 (tests: give ten assert-nothing tests a real assertion), whose hunks sit in untagged sibling tests and the import block. The tagged unit is byte-identical (gate-verified) and no helper it calls changed. Verdict stands. initiateIKERekey emits KEi (TestRespondIKERekey) and respondIKERekey refuses a rekey without KE naming KEi; test comment still cites Section 1.3.3 where the sentence is 1.3.2

PolarityTestKind and tierProof state
negative TestRespondIKERekeyRejectsMissingKE unit/verify unproven
positive TestRespondIKERekey unit/verify unproven

RFC7296-1.3.3-2

The REKEY_SA notification MUST be included in a CREATE_CHILD_SA exchange if the purpose of the exchange is to replace an existing ESP or AH SA (§1.3.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRksaChildRekeyCarriesTheRekeySANotify unit/verify unproven
positive TestRksaChildRekeyCarriesTheRekeySANotify unit/verify unproven

RFC7296-1.3.3-3

The initiator sends SA offer(s) in the SA payload, a nonce in the Ni payload, optionally a Diffie-Hellman value in the KEi payload, and the proposed Traffic Selectors for the proposed Child SA in the TSi and TSr payloads. (§1.3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Positive: TestRFC7296ChildRekeyRequestCarriesTheOfferNonceAndSelectors decrypts ze's initiateChildRekey request at the peer: exactly one SA, one Ni, one TSi and one TSr with selectors, KEi present with pfs enable and absent with pfs disable (the optional clause both ways). Negative (receive side): TestRFC7296ChildRekeyRequestMissingAPayloadIsRefused removes SA, Ni, TSi or TSr one at a time from a peer request: each refused with errMalformedRequest and INVALID_SYNTAX, nothing installed; the complete request is answered. TestRekeyWithoutTrafficSelectorsIsRefused (moved from 2.9-1) adds the no-TS request refusal and its answered twin.

PolarityTestKind and tierProof state
negative TestRekeyWithoutTrafficSelectorsIsRefused unit/verify revert, verified
negative TestRFC7296ChildRekeyRequestMissingAPayloadIsRefused unit/verify revert, verified
positive TestRekeyWithoutTrafficSelectorsIsRefused unit/verify revert, verified
positive TestRFC7296ChildRekeyRequestCarriesTheOfferNonceAndSelectors unit/verify revert, verified

RFC7296-1.3.3-4

The Traffic Selectors for traffic to be sent on that SA are specified in the TS payloads in the response, which may be a subset of what the initiator of the Child SA proposed. (§1.3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. TestRFC7296ChildRekeyResponseCarriesTheSelectorsAndMayNarrow: ze's respondChildRekey response announces TSi/TSr equal to the installed scope, and ze as rekey initiator installs an answer narrowed to 10.1.0.0/25 from a /24 proposal (the may-be-a-subset clause). TestChildRekeyAnswerWithoutTrafficSelectorsIsRefused (moved from 2.9-1): a response without TS payloads is refused and installs nothing, the same fixture with both payloads installs their scope.

PolarityTestKind and tierProof state
negative TestChildRekeyAnswerWithoutTrafficSelectorsIsRefused unit/verify revert, verified
positive TestChildRekeyAnswerWithoutTrafficSelectorsIsRefused unit/verify revert, verified
positive TestRFC7296ChildRekeyResponseCarriesTheSelectorsAndMayNarrow unit/verify revert, verified

RFC7296-2.9-1

When the responder chooses a subset of the traffic proposed by the initiator, it narrows the Traffic Selectors to some subset of the initiator's proposal (provided the set does not become the null set). (§2.9)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-10 (independent judge) against RFC 7296 Section 2.9: "When the responder chooses a subset of the traffic proposed by the initiator, it narrows the Traffic Selectors to some subset of the initiator's proposal (provided the set does not become the null set)." The upgrade path named in the earlier weak verdict is now met by TestResponderNarrowsBothSelectorsToPolicy, which drives narrowChildSelectors, the producer every responder path calls (responder.go buildAuthResponse, responder_eap.go, create_child.go, rekey.go). Positive: a 10.0.0.0/8 proposal on BOTH TSi and TSr against policy 10.10.0.0/16 (initiator side) and 10.20.0.0/16 (responder side) must yield NegotiatedTSi 10.10.0.0/16 and NegotiatedTSr 10.20.0.0/16 exactly, and the IKE_AUTH response payloads from buildChildSAResponsePayloads must carry exactly one selector each spanning those prefixes. Negative (control, a responder MUST has no violating input): a proposal already inside policy (10.10.1.0/24, 10.20.2.0/24) must come back unchanged on both halves. Mutants judged: echoing the proposal, taking the wider prefix in intersectNet, or narrowing one side only reds the positive; answering with the policy prefixes reds the negative on both halves, so the earlier hole (intersectPair answering policy on TSr) is closed. The null-set proviso stays with TestTSUnacceptableIsSentWhenNothingIsAcceptable (disjoint proposal draws TS_UNACCEPTABLE, no pairs recorded). TestChildRekeyInitiatorInstallsTheAnsweredSelectors remains tagged but is Ze as initiator refusing a widened answer, supporting evidence only. Isolation: no floor, tunnel mode, no NAT state, so neither the Section 2.9.2 floor check nor transport single-address narrowing nor NAT substitution can decide the result. Limit: the unit drives the producer, not a whole IKE_AUTH exchange; the recorded discrimination breaks (panic in intersectPair / intersectNet) prove the path is reached, not the narrowing, which the exact-value assertions above carry.

PolarityTestKind and tierProof state
negative TestChildRekeyInitiatorInstallsTheAnsweredSelectors unit/verify unproven
negative TestResponderNarrowsBothSelectorsToPolicy unit/verify revert, verified
negative TestTSUnacceptableIsSentWhenNothingIsAcceptable unit/verify unproven
positive TestChildRekeyInitiatorInstallsTheAnsweredSelectors unit/verify unproven
positive TestResponderNarrowsBothSelectorsToPolicy unit/verify revert, verified
positive TestTSUnacceptableIsSentWhenNothingIsAcceptable unit/verify unproven

RFC7296-2.9-2

If the responder's policy allows it to accept the first selector of TSi and TSr, then the responder MUST narrow the Traffic Selectors to a subset that includes the initiator's first choices (§2.9)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNarrowingIncludesFirstChoice unit/verify unproven
positive TestPeerInitiatedRekeyIsNarrowedInTheExchangeOrientation unit/verify unproven
positive TestAuthResponsePayloadsCarryTheNarrowedSelectors unit/verify unproven
positive TestNarrowingIncludesFirstChoice unit/verify unproven

RFC7296-2.9.2-1

Thus, the new SA MUST NOT have narrower selectors than the original (§2.9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestChildRekeyAnswerBelowTheScopeInUseIsRefused unit/verify unproven
negative TestRekeyFloorIsNotNarrowed unit/verify unproven
positive TestChildRekeyAnswerBelowTheScopeInUseIsRefused unit/verify unproven
positive TestRekeyAnswerMatchesTheInstalledSelectors unit/verify unproven
positive TestRekeyFloorIsNotNarrowed unit/verify unproven

RFC7296-2.9.2-2

The responder MUST NOT narrow down the Traffic Selectors narrower than the scope currently in use (§2.9.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestChildRekeyAnswerBelowTheScopeInUseIsRefused unit/verify unproven
negative TestRekeyProposalBelowTheFloorIsRefused unit/verify unproven
negative TestRekeyFloorIsNotNarrowed unit/verify unproven
positive TestChildRekeyAnswerBelowTheScopeInUseIsRefused unit/verify unproven
positive TestRekeyProposalBelowTheFloorIsRefused unit/verify unproven
positive TestRekeyFloorIsNotNarrowed unit/verify unproven

RFC7296-1.3.1-1

If the request is accepted, the response MUST also include a notification of type USE_TRANSPORT_MODE (§1.3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestUseTransportModeNotifyIsEchoedOnlyWhenAccepted unit/verify unproven
positive TestUseTransportModeNotifyIsEchoedOnlyWhenAccepted unit/verify unproven

RFC7296-1.3.1-2

If the responder declines the request, the Child SA will be established in tunnel mode. If this is unacceptable to the initiator, the initiator MUST delete the SA (§1.3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestTransportRequiredDeletesTheSAOnDecline unit/verify unproven
positive TestChildlessInitiatorDeletesDeclinedTransportChildSA unit/verify revert, verified
positive TestTransportRequiredDeletesTheSAOnDecline unit/verify unproven

RFC7296-2.23.1-1

For transport mode, it MUST use exactly one IP address in the TSi and TSr payloads (§2.23.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResponderAnswersTheIKESAAddressesBehindANAT unit/verify revert, verified
negative TestTransportModeUsesExactlyOneAddress unit/verify unproven
positive TestResponderAnswersTheIKESAAddressesBehindANAT unit/verify revert, verified
positive TestTransportModeUsesExactlyOneAddress unit/verify unproven

RFC7296-2.23.1-2

The TSi entries MUST have exactly one IP address, and that MUST match the source address of the IKE SA (§2.23.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestTransportSelectorsMatchTheIKESAAddressesBehindANAT unit/verify revert, verified
negative TestTransportModeUsesExactlyOneAddress unit/verify unproven
positive TestTransportSelectorsMatchTheIKESAAddressesBehindANAT unit/verify revert, verified
positive TestTransportModeUsesExactlyOneAddress unit/verify unproven

RFC7296-2.23.1-3

The TSr entries MUST have exactly one IP address, and that MUST match the destination address of the IKE SA (§2.23.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestTransportSelectorsMatchTheIKESAAddressesBehindANAT unit/verify revert, verified
negative TestTransportModeUsesExactlyOneAddress unit/verify unproven
positive TestTransportSelectorsMatchTheIKESAAddressesBehindANAT unit/verify revert, verified
positive TestTransportModeUsesExactlyOneAddress unit/verify unproven

RFC7296-3.13.1-1

For protocols for which port is undefined (including protocol 0), or if all ports are allowed, this field MUST be zero. (§3.13.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. selectorsToWire encodes protocol-0 all-ports Start Port 0; single-port selector proves the encoder can emit non-zero

PolarityTestKind and tierProof state
negative TestPortEncodingFollowsSection3131 unit/verify unproven
positive TestPortEncodingFollowsSection3131 unit/verify unproven

RFC7296-3.13.1-2

For protocols for which port is undefined (including protocol 0), or if all ports are allowed, this field MUST be 65535. (§3.13.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. all-ports End Port 65535; single-port 443 discriminator

PolarityTestKind and tierProof state
negative TestPortEncodingFollowsSection3131 unit/verify unproven
positive TestPortEncodingFollowsSection3131 unit/verify unproven

RFC7296-3.13.1-3

Systems working with [IPSECARCH] that wish to indicate "OPAQUE" ports, but not "ANY" ports, MUST set the start port to 65535 and the end port to 0. (§3.13.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. PortOpaque encodes 65535/0 and ANY is not emitted in that form

PolarityTestKind and tierProof state
negative TestPortEncodingFollowsSection3131 unit/verify unproven
positive TestPortEncodingFollowsSection3131 unit/verify unproven

RFC7296-2.23-1

The IKE initiator MUST check the NAT_DETECTION_SOURCE_IP or NAT_DETECTION_DESTINATION_IP payloads if present (§2.23)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Rejudged 2026-09-30 (ike-eap judge). TestRFC7296InitiatorChecksEachNATDetectionPayload drives handleSAInitResponse over a real encoded IKE_SA_INIT response: a SOURCE_IP mismatch alone sets NATDetected+PeerBehindNAT and floats to 4500, a DESTINATION_IP mismatch alone sets NATDetected+BehindNAT and floats, so ignoring either payload goes red. TestRFC7296InitiatorCheckFindsNoNATOnMatchingPayloads (both present, both matching: no NAT, not floated) goes red if presence alone were taken as a NAT, i.e. if the payloads were not checked. Both carry observed-red records on fsm.go handleSAInitResponse. HEAD tags on transport TestNATDetectionPresent/Absent (DetectNAT in isolation) are supplementary and hold no record.

PolarityTestKind and tierProof state
negative TestRFC7296InitiatorCheckFindsNoNATOnMatchingPayloads unit/verify revert, verified
negative TestNATDetectionAbsent unit/verify revert, verified
positive TestRFC7296InitiatorChecksEachNATDetectionPayload unit/verify revert, verified
positive TestNATDetectionPresent unit/verify revert, verified

RFC7296-2.23-2

However, if a NAT is detected, both devices MUST use UDP encapsulation for ESP. (§2.23)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-15 after b457ba88cf rewrote TestChildSANATTEncapPorts. RFC 7296 Section 2.23: 'However, if a NAT is detected, both devices MUST use UDP encapsulation for ESP.' With NATDetected and the IKE SA floated to its NAT-T socket, the test runs createFirstChildSA and requires exactly two installed states, inbound and outbound, each with UDPEncap true, so a NAT-detected Child SA installed without UDP encapsulation on either direction fails. The rewrite added port assertions (the IKE SA's ports, both fixtures off 4500) that serve RFC 3948 Section 2.1 and do not weaken the UDPEncap assertion. No receive-side refusal is legitimate (RFC7296-2.23-10 requires plain ESP to stay accepted), so TestChildSANoNATNoEncap stays a supplementary no-NAT guard. Rekey still carries NATDetected and UDPEncap from the old child (rekey.go newRekeyedChild), asserted by the untagged TestRekeyKeepsBothESPFormAcceptance outside this fingerprint.

PolarityTestKind and tierProof state
negative TestChildSANoNATNoEncap unit/verify revert, verified
positive TestChildSANATTEncapPorts unit/verify revert, verified

RFC7296-2.23-3

To tunnel IKE packets over UDP port 4500, the IKE header has four octets of zeros prepended and the result immediately follows the UDP header. (§2.23)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Rejudged 2026-09-30 (ike-eap judge). TestRFC7296IKEOnPort4500CarriesTheZeroMarker sends through sendRaw (the shared post-establishment send path) on an SA floated to 4500 and reads the raw UDP payload at the peer: exactly 00000000 followed by the IKE message byte for byte, so a missing marker or anything between the UDP header and the marker goes red. TestRFC7296IKEOnPort500CarriesNoMarker shows the same send on port 500 carries the message unchanged, so the zeros are conditional on 4500. Both carry observed-red records on established.go sendRaw. HEAD tags on transport TestNonESPMarker/TestNonESPMarkerESPPacket (helpers in isolation) are supplementary and hold no record.

PolarityTestKind and tierProof state
negative TestRFC7296IKEOnPort500CarriesNoMarker unit/verify revert, verified
negative TestNonESPMarkerESPPacket unit/verify revert, verified
positive TestRFC7296IKEOnPort4500CarriesTheZeroMarker unit/verify revert, verified
positive TestNonESPMarker unit/verify revert, verified

RFC7296-2.8-1

If redundant SAs are created through such a collision, the SA created with the lowest of the four nonces used in the two exchanges SHOULD be closed by the endpoint that created it (§2.8, §2.8.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRekeyCollision unit/verify unproven
negative TestRekeyCollisionIKEBranchLowestNonceAbandons unit/verify unproven
negative TestRekeyCollisionLowestNonceAbandons unit/verify unproven
positive TestRekeyCollision unit/verify unproven
positive TestRekeyCollisionIKEBranchLowestNonceAbandons unit/verify unproven
positive TestRekeyCollisionLowestNonceAbandons unit/verify unproven

RFC7296-2.4-1

To check whether the other side is alive, IKE specifies an empty INFORMATIONAL request that (like all IKE requests) requires an acknowledgement (§2.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. empty INFORMATIONAL request answered by an encrypted INFORMATIONAL response with zero inner payloads echoing the message ID; a response is not answered

PolarityTestKind and tierProof state
negative TestDPDEmptyInformationalGetsEmptyResponse unit/verify unproven
positive TestDPDEmptyInformationalGetsEmptyResponse unit/verify unproven

RFC7296-1.4-1

Normally, the response in the INFORMATIONAL exchange will contain Delete payloads for the paired SAs going in the other direction. (§1.4.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after the owner moved the level from MUST to SHOULD (970ea021d8); quote unchanged. RFC 7296 1.4.1: 'Normally, the response in the INFORMATIONAL exchange will contain Delete payloads for the paired SAs going in the other direction.' TestDelResponseCarriesThePairedDelete sends a Child SA Delete naming ze's outbound SPI and requires the response to carry one ESP Delete naming the paired inbound SPI and not the deleted one, so an empty or echoing response fails; that is the recommended behavior at either level. TestDelIKEDeleteDrawsAnEmptyResponse (IKE SA Delete draws an empty response, per the same paragraph) is a scoping control rather than a violating input, and the crossing-Delete exception is proven under RFC7296-1.4.1-4 and -7. The lower level asks less, so the proof still covers it. No discrimination record.

PolarityTestKind and tierProof state
negative TestDelIKEDeleteDrawsAnEmptyResponse unit/verify unproven
positive TestDelResponseCarriesThePairedDelete unit/verify unproven

RFC7296-2.8-2

A difference between IKEv1 and IKEv2 is that in IKEv1 SA lifetimes were negotiated. In IKEv2, each end of the SA is responsible for enforcing its own lifetime policy on the SA and rekeying the SA when necessary. (§2.8)

Audit verdict: enforced (the tests do what the requirement demands), fresh. no lifetime transform or attribute reaches the wire (TestLifetimesNotNegotiatedOnWire); lifetime state derives from the local value (TestSALifetimeTime)

PolarityTestKind and tierProof state
negative TestLifetimesNotNegotiatedOnWire unit/verify unproven
positive TestSALifetimeTime unit/verify unproven

RFC7296-1-1

In all cases, all IKE_SA_INIT exchanges MUST complete before any other exchange type, then all IKE_AUTH exchanges MUST complete, and following that, any number of CREATE_CHILD_SA and INFORMATIONAL exchanges may occur in any order (§1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestAutExchangesRunInRFCOrder unit/verify unproven
positive TestAutExchangesRunInRFCOrder unit/verify unproven

RFC7296-1.2-2

If any CERT payloads are included, the first certificate provided MUST contain the public key used to verify the AUTH field (§1.2, §3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestAutFirstCertificateCarriesTheAuthKey unit/verify unproven
negative TestRccTwoLevelChainAuthenticates unit/verify unproven
positive TestAutFirstCertificateCarriesTheAuthKey unit/verify unproven
positive TestRccTwoLevelChainAuthenticates unit/verify unproven

RFC7296-1.2-3

Both parties in the IKE_AUTH exchange MUST verify that all signatures and Message Authentication Codes (MACs) are computed correctly (§1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestAutIKEAuthVerifiesEveryMAC unit/verify unproven
negative TestAutIKEAuthVerifiesSignatures unit/verify unproven
positive TestAutIKEAuthVerifiesEveryMAC unit/verify unproven
positive TestAutIKEAuthVerifiesSignatures unit/verify unproven

RFC7296-1.2-4

If either side uses a shared secret for authentication, the names in the ID payload MUST correspond to the key used to generate the AUTH payload (§1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestAutSharedSecretAuthBindsTheIDName unit/verify unproven
positive TestAutSharedSecretAuthBindsTheIDName unit/verify unproven

RFC7296-1.2-5

If the initiator guesses wrong, the responder will respond with a Notify payload of type INVALID_KE_PAYLOAD indicating the selected group. In this case, the initiator MUST retry the IKE_SA_INIT with the corrected Diffie-Hellman group (§1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestKegInitiatorRefusesUnofferedGroup unit/verify unproven
positive TestKegInitiatorRetriesOnInvalidKEPayload unit/verify unproven

RFC7296-1.2-6

The initiator MUST again propose its full set of acceptable cryptographic suites because the rejection message was unauthenticated and otherwise an active attacker could trick the endpoints into negotiating a weaker suite than a stronger one that they both prefer (§1.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestKegRetryOfferIsNotNarrowedByTheNotify unit/verify unproven
positive TestKegRetryReproposesEveryConfiguredSuite unit/verify unproven

RFC7296-2.4-11

An endpoint MUST conclude that the other endpoint has failed only when repeated attempts to contact it have gone unanswered for a timeout period or when a cryptographically protected INITIAL_CONTACT notification is received on a different IKE SA to the same authenticated identity (§2.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDPDNoTransportTakesNoWindow unit/verify unproven
negative TestDPDVerdictNeedsARepeatedAttempt unit/verify unproven
negative TestSesPeerFailedOnlyAfterRepeatedSilence unit/verify unproven
positive TestDPDVerdictEndsAProbeThatCannotBeRepeated unit/verify unproven
positive TestDPDVerdictNeedsARepeatedAttempt unit/verify unproven
positive TestSesPeerFailedOnlyAfterRepeatedSilence unit/verify unproven

RFC7296-2.4-12

Implementations MUST limit the rate at which they take actions based on unprotected messages (§2.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestErrResponderWindowDoesNotReflectToObservedSource unit/verify unproven
negative TestErrUnprotectedMessageDrawsNoCachedResponse unit/verify unproven
negative TestSesLimitsWorkOnUnprotectedMessages unit/verify unproven
positive TestErrResponderWindowDoesNotReflectToObservedSource unit/verify unproven
positive TestErrUnprotectedMessageDrawsNoCachedResponse unit/verify unproven
positive TestSesLimitsWorkOnUnprotectedMessages unit/verify unproven

RFC7296-2.4-13

To be a good network citizen, retransmission times MUST increase exponentially to avoid flooding the network and making an existing congestion situation worse (§2.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSesRetransmitWaitIncreasesExponentially unit/verify unproven
positive TestSesRetransmitWaitIncreasesExponentially unit/verify unproven

RFC7296-2.7-2

Each proposal contains one protocol. If a proposal is accepted, the SA response MUST contain the same protocol (§2.7)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSesAcceptedProposalKeepsItsProtocol unit/verify unproven
positive TestSesAcceptedProposalKeepsItsProtocol unit/verify unproven

RFC7296-2.10-4

Nonces used in IKEv2 MUST be randomly chosen (§2.10)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSesNoncesAreRandomlyChosenAndNeverReused unit/verify unproven
positive TestSesNoncesAreRandomlyChosenAndNeverReused unit/verify unproven

RFC7296-2.11-1

An implementation MUST accept incoming requests even if the source port is not 500 or 4500 (§2.11, §2.23)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSesAcceptsRequestFromAnySourcePort unit/verify unproven
negative TestPrtAcceptsDatagramFromAnySourcePort unit/verify unproven
positive TestSesAcceptsRequestFromAnySourcePort unit/verify unproven
positive TestPrtAcceptsDatagramFromAnySourcePort unit/verify unproven

RFC7296-2.11-2

MUST respond to the address and port from which the request was received (§2.11)

Audit verdict: enforced (the tests do what the requirement demands), fresh. TestRFC7296ReplyLandsOnTheRequestSourcePort reads the reply datagram on the socket bound to the request's odd source port (response flag, request Message ID, decrypts under the IKE SA). The negative is now TestRFC7296ReplyDoesNotGoToTheConfiguredEndpoint alone: the configured remote, the violating destination, receives nothing. The NAT-T unauthenticated-packet unit moved to RFC7296-2.23-13, the row it proves. The older natt positive asserts only the stored endpoint and is supplementary.

PolarityTestKind and tierProof state
negative TestRFC7296ReplyDoesNotGoToTheConfiguredEndpoint unit/verify revert, verified
positive TestNattRepliesToTheObservedSourcePort unit/verify revert, verified
positive TestRFC7296ReplyLandsOnTheRequestSourcePort unit/verify revert, verified

RFC7296-2.11-3

It MUST specify the address and port at which the request was received as the source address and port in the response (§2.11)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNattReplyRefusesWithoutADestination unit/verify unproven
positive TestNattReplyLeavesFromTheArrivalSocket unit/verify unproven

RFC7296-2.16-11

these protocols are typically used to authenticate the initiator to the responder and MUST be used in conjunction with a public-key-signature-based authentication of the responder to the initiator. (§2.16)

Audit verdict: enforced (the tests do what the requirement demands), fresh. EAP responder AUTH is an RFC 7427 signature verified under the cert key; no-cert EAP refused at setup and config; initiator refuses PSK AUTH from EAP responder; PSK peers unaffected

PolarityTestKind and tierProof state
negative TestEapAuthConfigRejectsEAPWithoutCertificate unit/verify unproven
negative TestEapAuthInitiatorRefusesPreSharedKeyResponder unit/verify unproven
negative TestEapAuthResponderRefusesWithoutCertificate unit/verify unproven
positive TestEapAuthConfigAcceptsPreSharedKeyPeer unit/verify unproven
positive TestEapAuthNonEAPPreSharedKeyStillAuthenticates unit/verify unproven
positive TestEapAuthResponderSignsWithPublicKey unit/verify unproven

RFC7296-2.16-6

Extensible authentication is implemented in IKE as additional IKE_AUTH exchanges that MUST be completed in order to initialize the IKE SA (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestAutEAPRunsAsExtraIKEAuthExchanges unit/verify unproven
positive TestAutEAPRunsAsExtraIKEAuthExchanges unit/verify unproven

RFC7296-2.16-7

This shared key generated during an IKE exchange MUST NOT be used for any other purpose (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestAutEAPSharedKeyServesAuthAlone unit/verify unproven
positive TestAutEAPSharedKeyServesAuthAlone unit/verify unproven

RFC7296-2.23-7

Both the IKE initiator and responder MUST include in their IKE_SA_INIT packets Notify payloads of type NAT_DETECTION_SOURCE_IP and NAT_DETECTION_DESTINATION_IP (§2.23)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSesBothEndsSendNATDetectionNotifies unit/verify unproven
positive TestSesBothEndsSendNATDetectionNotifies unit/verify unproven

RFC7296-2.23-8

An IPsec endpoint that discovers a NAT between it and its correspondent (as described below) MUST send all subsequent traffic from port 4500 (§2.23)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNattFloatedSAWithoutNATTSocketSendsNothing unit/verify revert, verified
negative TestNattNoFloatWithoutNAT unit/verify revert, verified
positive TestNattFloatsEverySenderToPort4500 unit/verify revert, verified
positive TestNattRekeyedChildKeepsUDPEncap unit/verify unproven

RFC7296-2.23-9

UDP encapsulation MUST NOT be done on port 500 (§2.23)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEncapPortsAreExpressible unit/verify unproven
positive TestEncapNeverRequestedOnPort500 unit/verify revert, verified

RFC7296-2.23-10

If Network Address Translation Traversal (NAT-T) is supported (that is, if NAT_DETECTION_*_IP payloads were exchanged during IKE_SA_INIT), all devices MUST be able to receive and process both UDP-encapsulated ESP and non-UDP-encapsulated ESP packets at any time. (§2.23)

Audit verdict: enforced (the tests do what the requirement demands), fresh. every Child SA accepts both ESP forms inbound (AcceptBothESPForms) and both forms are programmable; kernel behavior measured by the cited QEMU tests

PolarityTestKind and tierProof state
negative TestBfmBothESPFormsReceivedOnOneChildSA unit/verify unproven
positive TestBfmBothESPFormsAreReachable unit/verify unproven

RFC7296-2.23-11

Implementations MUST process received UDP-encapsulated ESP packets even when no NAT was detected (§2.23)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestBfmBareESPKeptForUnfloatedSA unit/verify unproven
positive TestBfmEncapsulatedESPAcceptedWithoutNAT unit/verify revert, verified
positive TestBfmEncapsulatedESPSentWhenNATDetected unit/verify revert, verified

RFC7296-2.23-12

To tunnel ESP packets over UDP port 4500, the ESP header immediately follows the UDP header. Since the first four octets of the ESP header contain the SPI, and the SPI cannot validly be zero, it is always possible to distinguish ESP and IKE messages. (§2.23)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Rejudged 2026-09-30 (ike-eap judge). Sentence 1: Linux performs ESP-in-UDP, so the proof is the state Ze installs: TestRFC7296ESPInUDPStateHasESPRightAfterUDP asserts xfrmStateFromParams builds an encapsulated 4500/4500 SA with Encap.Type XFRM_ENCAP_ESPINUDP (the RFC 3948 form, ESP header right after UDP, not ESPINUDP_NON_IKE) and the SA's SPI. Sentence 2: TestRFC7296ESPInUDPStateRefusesSPIZero forces SPI 0 on an encapsulated SA and requires a refusal with no state; judge mutation (SPI==0 check disabled in xfrmStateFromParams) turned it red, so it is not vacuous. Both carry records. Receive-side distinction stays on transport TestNonESPMarker/TestNonESPMarkerESPPacket (recorded). No netns wire capture (needs root); the template Ze installs is the boundary Ze owns.

PolarityTestKind and tierProof state
negative TestRFC7296ESPInUDPStateRefusesSPIZero unit/verify revert, verified
negative TestNonESPMarkerESPPacket unit/verify revert, verified
positive TestRFC7296ESPInUDPStateHasESPRightAfterUDP unit/verify revert, verified
positive TestNonESPMarker unit/verify revert, verified

RFC7296-2.23-13

When such a validated packet is found, a host that does not support other methods of recovery such as IKEv2 Mobility and Multihoming (MOBIKE) [MOBIKE], and that is not behind a NAT, SHOULD send all packets (including retransmission packets) to the IP address and port in the validated packet, and SHOULD store this as the new address and port combination for the SA (that is, they SHOULD dynamically update the address). (§2.23)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Row is verbatim §2.23. Positive TestRFC7296ValidatedPacketFromANewEndpointMovesTheSA: responder not behind a NAT and without MOBIKE; a second validated request from a new port moves peerEndpoint and remoteUDPAddr (what every send and retransmission reads), and the response is read on the new socket. Negatives each violate one bound of the sentence against adoptAuthenticatedEndpoint: behind a NAT (§2.23 'A host behind a NAT SHOULD NOT do this type of dynamic address update') and MOBIKE keep the stored endpoint (TestRFC7296ValidatedPacketDoesNotMoveTheSAOutsideTheRow); a packet with an in-window Message ID whose integrity check fails, from a new endpoint, moves nothing (TestNattUnauthenticatedPacketDoesNotMoveTheEndpoint). Each guard in the producer has a case that reddens without it. The 'new packet' replay bound is a separate lowercase-should sentence, not this row.

PolarityTestKind and tierProof state
negative TestRFC7296ValidatedPacketDoesNotMoveTheSAOutsideTheRow unit/verify revert, verified
negative TestNattUnauthenticatedPacketDoesNotMoveTheEndpoint unit/verify revert, verified
positive TestRFC7296ValidatedPacketFromANewEndpointMovesTheSA unit/verify revert, verified

RFC7296-3.9-2

Nonce values MUST NOT be reused (§3.9)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSesNoncesAreRandomlyChosenAndNeverReused unit/verify unproven
negative TestSesRekeyDrawsFreshNoncesOnBothSides unit/verify unproven
positive TestSesNoncesAreRandomlyChosenAndNeverReused unit/verify unproven
positive TestSesRekeyDrawsFreshNoncesOnBothSides unit/verify unproven

RFC7296-1.3-2

If the responder selects a proposal using a different Diffie-Hellman group (other than NONE), the responder MUST reject the request and indicate its preferred Diffie-Hellman group in the INVALID_KE_PAYLOAD Notify payload (§1.3, §3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNegRekeyRejectsMismatchedKEGroup unit/verify unproven
positive TestNegRekeyRejectsMismatchedKEGroup unit/verify unproven

RFC7296-2.8.2-1

The new IKE SA containing the lowest nonce SHOULD be deleted by the node that created it, and the other surviving new IKE SA MUST inherit all the Child SAs (§2.8.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNegIKERekeyCollisionResolves unit/verify unproven
negative TestNegSurvivingSAInheritsChildren unit/verify unproven
positive TestNegIKERekeyCollisionResolves unit/verify unproven
positive TestNegSurvivingSAInheritsChildren unit/verify unproven

RFC7296-3.3.6-3

The initiator of an exchange MUST check that the accepted offer is consistent with one of its proposals, and if not MUST terminate the exchange (§3.3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestVerInitiatorRefusesUnsentESPKeyLength unit/verify unproven
negative TestVerInitiatorRefusesUnsentIKEKeyLength unit/verify unproven
negative TestEsnInitiatorRefusesAnESNValueItNeverOffered unit/verify unproven
negative TestKlnInitiatorRefusesLongerAcceptedKey unit/verify unproven
negative TestNegInitiatorRejectsUnproposedOffer unit/verify unproven
positive TestVerInitiatorRefusesUnsentESPKeyLength unit/verify unproven
positive TestVerInitiatorRefusesUnsentIKEKeyLength unit/verify unproven
positive TestEsnInitiatorRefusesAnESNValueItNeverOffered unit/verify unproven
positive TestKlnInitiatorRefusesLongerAcceptedKey unit/verify unproven
positive TestNegInitiatorRejectsUnproposedOffer unit/verify unproven

RFC7296-1.4-3

Control messages that pertain to an IKE SA MUST be sent under that IKE SA. Control messages that pertain to Child SAs MUST be sent under the protection of the IKE SA that generated them (§1.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLcyControlMessagesRideTheirOwnIKESA unit/verify unproven
positive TestLcyControlMessagesRideTheirOwnIKESA unit/verify unproven

RFC7296-1.4-4

The recipient of an INFORMATIONAL exchange request MUST send some response; otherwise, the sender will assume the message was lost in the network and will retransmit it (§1.4, §4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLcyEveryInformationalRequestDrawsAResponse unit/verify unproven
positive TestLcyEveryInformationalRequestDrawsAResponse unit/verify unproven

RFC7296-1.4-5

INFORMATIONAL exchanges MUST ONLY occur after the initial exchanges and are cryptographically protected with the negotiated keys (§1.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDpdProbeIsEncrypted unit/verify unproven
positive TestDpdProbeIsEncrypted unit/verify unproven

RFC7296-1.4.1-6

To delete an SA, an INFORMATIONAL exchange with one or more Delete payloads is sent listing the SPIs (as they would be expected in the headers of inbound packets) of the SAs to be deleted. The recipient MUST close the designated SAs (§1.4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDelUnknownSPIClosesNothing unit/verify unproven
positive TestDelPeerDeleteClosesTheDesignatedChildSA unit/verify unproven

RFC7296-1.4.1-7

If a node receives a delete request for SAs for which it has already issued a delete request, it MUST delete the outgoing SAs while processing the request and the incoming SAs while processing the response (§1.4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDelWithoutOwnDeleteTheSameRequestIsPaired unit/verify unproven
positive TestDelCrossingDeleteAnswersWithoutAPairedDelete unit/verify unproven

RFC7296-1.5-1

This message is not part of an INFORMATIONAL exchange, and the receiving node MUST NOT respond to it because doing so could cause a message loop (§1.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestWp2OutOfSAAnswersARequest unit/verify unproven
positive TestWp2OutOfSAEmitterIsAFixedPoint unit/verify unproven

RFC7296-2.12-1

Achieving perfect forward secrecy requires that when a connection is closed, each endpoint MUST forget not only the keys used by the connection but also any information that could be used to recompute those keys (§2.12)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestWp2OpenSAKeepsItsKeys unit/verify unproven
positive TestRunEstablishedClearsPendingIKESwapOnExit unit/verify unproven
positive TestWp2ForgetKeysErasesEverySecret unit/verify unproven

RFC7296-2.24-1

tunnel encapsulators and decapsulators for all tunnel mode SAs created by IKEv2 MUST support the ECN full-functionality option for tunnels specified in [ECN] (§2.24)

Audit verdict: enforced (the tests do what the requirement demands), fresh. installed Child SAs are tunnel mode with no ECN-disabling field (engine and XFRM scans); VPP InstallSA sets ENCAP/DECAP_COPY_ECN. Negatives are non-vacuity checks rather than violating inputs

PolarityTestKind and tierProof state
negative TestEcnTheScannedStateIsTheOneZeInstalls unit/verify unproven
negative TestVPPInstallSAECNIsOnTheSAZeInstalls unit/verify unproven
negative TestEcnTheInstalledSAsAreRealAndDirectional unit/verify unproven
positive TestEcnInstalledStateDisablesNothing unit/verify unproven
positive TestVPPInstallSACopiesECN unit/verify unproven
positive TestEcnInstalledChildSAAsksForNoECNChange unit/verify unproven

RFC7296-2.24-2

MUST implement the tunnel encapsulation and decapsulation processing specified in [IPSECARCH] to prevent discarding of ECN congestion indications. (§2.24)

Audit verdict: enforced (the tests do what the requirement demands), fresh. same units: XFRM state carries no NOECN path, VPP sets DECAP_COPY_ECN; transport mode refused by VPP backend

PolarityTestKind and tierProof state
negative TestEcnTheScannedStateIsTheOneZeInstalls unit/verify unproven
negative TestVPPInstallSAECNIsOnTheSAZeInstalls unit/verify unproven
negative TestEcnTheInstalledSAsAreRealAndDirectional unit/verify unproven
positive TestEcnInstalledStateDisablesNothing unit/verify unproven
positive TestVPPInstallSACopiesECN unit/verify unproven
positive TestEcnInstalledChildSAAsksForNoECNChange unit/verify unproven

RFC7296-2.16-12

For EAP methods that create a shared key as a side effect of authentication, that shared key MUST be used by both the initiator and responder to generate AUTH payloads in messages 7 and 8 using the syntax for shared secrets specified in Section 2.15 (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapAuthProducerOutputIsRefusedUnderAnotherKey unit/verify unproven
positive TestEapAuthProducerIsKeyedByTheNegotiatedMSK unit/verify unproven

RFC7296-2.16-13

Following such an extended exchange, the EAP AUTH payloads MUST be included in the two messages following the one containing the EAP Success message (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapAuthFollowsTheSuccessMessage unit/verify unproven
positive TestEapAuthFollowsTheSuccessMessage unit/verify unproven

RFC7296-2.16-14

Once the protocol exchange defined by the chosen EAP authentication method has successfully terminated, the responder MUST send an EAP payload containing the Success message (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapResultFailureIsSent unit/verify unproven
positive TestEapResultSuccessIsSent unit/verify unproven

RFC7296-2.16-15

Similarly, if the authentication method has failed, the responder MUST send an EAP payload containing the Failure message (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapResultSuccessIsNotFailure unit/verify unproven
positive TestEapResultFailureIsSent unit/verify unproven

RFC7296-3.1-13

* I (Initiator) - This bit MUST be set in messages sent by the original initiator of the IKE SA and MUST be cleared in messages sent by the original responder. (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Every call site of initiatorFlag is now product-driven for both original roles: IKE_SA_INIT/IKE_AUTH request and response, INFORMATIONAL responses, IKE rekey request, DPD probes (earlier units), and TestRFC7296InitiatorBitAtEveryRemainingCallSite: writeDelete and sendIKESATeardown Delete requests and startMobikeRequest read off the peer socket, respondMobikeError, buildErrorNotifyResponse, initiateChildRekey, respondChildRekey accepted and INVALID_KE, respondIKERekey accepted and INVALID_KE. Each check asserts I == original-initiator and the R flag, so a site deriving I from direction goes red on a response or on the original responder's request, and a hard-coded value goes red for one role. The older unit's test-built Delete remains but no longer carries the Delete claim alone.

PolarityTestKind and tierProof state
negative TestWp2DPDProbeIBitDiffersByRole unit/verify revert, verified
positive TestRFC7296InitiatorBitAtEveryRemainingCallSite unit/verify revert, verified
positive TestRFC7296InitiatorBitFollowsTheOriginalRole unit/verify revert, verified
positive TestWp2DPDProbeIBitFollowsRole unit/verify revert, verified

RFC7296-3.5-5

A fully-qualified domain name string. An example of an ID_FQDN is "example.com". The string MUST NOT contain any terminators (e.g., NULL, CR, etc.). (§3.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Row now quotes the ID_FQDN entry through its ban (verbatim §3.5; the keyword-free ASCII/IDNA sentence the old weak verdict turned on is out of the span). TestWp2IDTerminatorRefused: a peer ID_FQDN holding NUL, CR or LF is refused by refuseIDTerminators, and ze's own local-id/remote-id holding one is refused by ValidateIdentities (config.go:158), the only path to the ID_FQDN ze sends (encodeIKEID). TestWp2IDWithoutTerminatorAccepted: clean FQDN accepted on both paths, NUL ID_KEY_ID left alone, so neither check refuses everything. Both halves call the validators directly; the call sites remote_id.go:393 and config.go:158 are unasserted. Producer comments at remote_id.go:352 and ipsec/validate.go:181 still quote the invented sentence the row dropped.

PolarityTestKind and tierProof state
negative TestWp2IDWithoutTerminatorAccepted unit/verify revert, verified
positive TestWp2IDTerminatorRefused unit/verify revert, verified

RFC7296-3.5-6

A fully-qualified RFC 822 email address string. An example of a ID_RFC822_ADDR is "jsmith@example.com". The string MUST NOT contain any terminators. (§3.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-01 under owner ruling 5 (ruling 2 reading). Ze never sends an ID_RFC822_ADDR: encodeIKEID (auth.go) emits only ID_IPV4_ADDR, ID_IPV6_ADDR or ID_FQDN, and the config path refuses a local-id/remote-id holding a terminator before it can be sent. The handling of the peer's violation is the refusal: TestWp2IDTerminatorRefused feeds refuseIDTerminators an ID_RFC822_ADDR holding a NUL and asserts refusal; TestWp2IDWithoutTerminatorAccepted is the control, a clean mail address accepted, so a check refusing every identity goes red. Tag labels are inverted relative to ruling 2 (refusal tagged positive, acceptance negative) but the pair is complete and isolated (one NUL octet is the only difference). Both units hold observed-red revert records.

PolarityTestKind and tierProof state
negative TestWp2IDWithoutTerminatorAccepted unit/verify revert, verified
positive TestWp2IDTerminatorRefused unit/verify revert, verified

RFC7296-1.4.1-1

When an SA is closed, both members of the pair MUST be closed (that is, deleted). Each endpoint MUST close its incoming SAs and allow the other endpoint to close the other SA in each pair (§1.4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLcyClosingAChildSAClosesBothHalvesAndDeletesOurInbound unit/verify unproven
positive TestLcyClosingAChildSAClosesBothHalvesAndDeletesOurInbound unit/verify unproven

RFC7296-1.4.1-4

In that case, the responses MUST NOT include Delete payloads for the deleted SAs, since that would result in duplicate deletion and could in theory delete the wrong SA. (§1.4.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. TestDelCrossingDeleteAnswersWithoutAPairedDelete runs the production crossing sequence (recordOwnDelete, send, remove) and asserts the response to the peer's crossing Delete carries no Delete payload; reddens when crossOwnDelete stops detecting the crossing. TestDelWithoutOwnDeleteTheSameRequestIsPaired pins the row's own 'In that case' scope: outside the exception the same Delete draws the paired Delete §1.4.1 requires ('Normally, the response ... will contain Delete payloads for the paired SAs'), so a responder that never pairs cannot pass. The tags on TestLcyInformationalResponseCarriesNoDeletePayload are gone and its stale premise rewritten.

PolarityTestKind and tierProof state
negative TestDelWithoutOwnDeleteTheSameRequestIsPaired unit/verify revert, verified
positive TestDelCrossingDeleteAnswersWithoutAPairedDelete unit/verify revert, verified

RFC7296-1.4.1-5

A node MAY refuse to accept incoming data on half-closed connections but MUST NOT unilaterally close them and reuse the SPIs (§1.4.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLcyRetiredSPIsAreNeverReused unit/verify unproven
positive TestLcyRetiredSPIsAreNeverReused unit/verify unproven

RFC7296-2.4-9

If a system creates Child SAs that can fail independently from one another without the associated IKE SA being able to send a delete message, then the system MUST negotiate such Child SAs using separate IKE SAs (§2.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLcyOneChildSALivesUnderOneIKESA unit/verify unproven
positive TestLcyOneChildSALivesUnderOneIKESA unit/verify unproven

RFC7296-2.4-10

If an IKE endpoint chooses to delete Child SAs, it MUST send Delete payloads to the other end notifying it of the deletion (§2.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLcyRetiringAChildSASendsADeletePayload unit/verify unproven
positive TestLcyRetiringAChildSASendsADeletePayload unit/verify unproven

RFC7296-2.16-5

If EAP methods that do not generate a shared key are used, the AUTH payloads in messages 7 and 8 MUST be generated using SK_pi and SK_pr, respectively (§2.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEAPAuthOfKeyDerivingMethodStillUsesTheMSK unit/verify revert, verified
positive TestEAPAuthOfNonKeyDerivingMethodUsesSKpiAndSKpr unit/verify revert, verified

RFC7296-2.16-16

EAP methods that do not establish a shared key SHOULD NOT be used, as they are subject to a number of man-in-the-middle attacks [EAPMITM] if these EAP methods are used in other protocols that do not use a server-authenticated tunnel. (§2.16)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Non-compliant behaviour: an IKEv2 exchange selecting an EAP method that establishes no key when the operator did not name one. Positive: TestRFC3748IKEv2EAPModesSelectAKeyDerivingMethod fails ('auth mode %s selected an EAP method that derives no key') for any EAP mode other than AuthEAPMD5 whose newEAPSession session answers false to DerivesKey. Negative: TestRFC3748IKEv2NoAuthModeSelectsAKeylessMethod sweeps every AuthMode value through newEAPSession and startEAPExchange, and assertKeylessModeIsNamedAndAnnounced goes red when a keyless method is reached by an unnamed value or without the adoption warning. The SHOULD NOT is met as a deviation the operator must name, which the warning makes visible.

PolarityTestKind and tierProof state
negative TestRFC3748IKEv2NoAuthModeSelectsAKeylessMethod unit/verify revert, verified
positive TestRFC3748IKEv2EAPModesSelectAKeyDerivingMethod unit/verify revert, verified

RFC7296-3.4-1

The length of the Diffie-Hellman public value for MODP groups MUST be equal to the length of the prime modulus over which the exponentiation was performed, prepending zero bits to the value if necessary (§3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRFC7296MODPShortPublicValueIsRefusedOnReceipt unit/verify unproven
positive TestRFC7296MODPPublicValueMatchesModulusLength unit/verify unproven

RFC7296-1.3-1

If a CREATE_CHILD_SA exchange includes a KEi payload, at least one of the SA offers MUST include the Diffie-Hellman group of the KEi (§1.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestChildRekeyProposesDiffieHellmanWhenPFSIsEnabled unit/verify unproven
negative TestChildRekeyProposesNoDiffieHellmanWhenPFSIsDisabled unit/verify revert, verified
negative TestRkyIKERekeyOffersTheKEiGroup unit/verify unproven
positive TestChildRekeyProposesDiffieHellmanWhenPFSIsEnabled unit/verify revert, verified
positive TestRkyIKERekeyOffersTheKEiGroup unit/verify unproven

RFC7296-2.1-3

The responder MUST never retransmit a response unless it receives a retransmission of the request (§2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapRtxMidEAPReplayRefusesUnprotected unit/verify revert, verified
negative TestRtxResponderReplaysCachedResponseOnlyForDuplicate unit/verify revert, verified
positive TestEapRtxResponderReplaysCachedResponseMidEAP unit/verify revert, verified
positive TestRtxResponderReplaysCachedResponseOnlyForDuplicate unit/verify revert, verified

RFC7296-2.1-4

In that event, the responder MUST ignore the retransmitted request except insofar as it causes a retransmission of the response (§2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapRtxResponderReplaysCachedResponseMidEAP unit/verify revert, verified
negative TestRtxResponderReplaysCachedResponseOnlyForDuplicate unit/verify revert, verified
positive TestEapRtxResponderReplaysCachedResponseMidEAP unit/verify revert, verified
positive TestRtxResponderReplaysCachedResponseOnlyForDuplicate unit/verify revert, verified

RFC7296-2.1-5

The initiator MUST remember each request until it receives the corresponding response. The responder MUST remember each response until it receives a request whose sequence number is larger than or equal to the sequence number in the response plus its window size (§2.1, §2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRtxEachSideRemembersWhatItSent unit/verify unproven
negative TestWinDeleteIsRememberedUntilAnswered unit/verify revert, verified
positive TestRtxEachSideRemembersWhatItSent unit/verify unproven
positive TestWinDeleteIsRememberedUntilAnswered unit/verify revert, verified

RFC7296-2.1-6

If the responder receives a retransmitted request for which it has already forgotten the response, it MUST ignore the request (and not, for example, attempt constructing a new response) (§2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRtxResponderIgnoresRequestWithForgottenResponse unit/verify revert, verified
positive TestRtxResponderIgnoresRequestWithForgottenResponse unit/verify revert, verified

RFC7296-2.1-7

IKE is a reliable protocol: the initiator MUST retransmit a request until it either receives a corresponding response or deems the IKE SA to have failed (§2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRtxInitiatorResendsUnansweredRekeyRequest unit/verify revert, verified
negative TestRtxInitiatorResendsUnansweredSAInit unit/verify unproven
negative TestWinUnansweredRequestFailsTheSA unit/verify revert, verified
positive TestRtxInitiatorResendsUnansweredRekeyRequest unit/verify revert, verified
positive TestRtxInitiatorResendsUnansweredSAInit unit/verify unproven
positive TestWinUnansweredRequestFailsTheSA unit/verify revert, verified

RFC7296-2.1-8

A retransmission from the initiator MUST be bitwise identical to the original request (§2.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRtxRetransmissionIsBitwiseIdenticalAndReusesMessageID unit/verify revert, verified
positive TestRtxRetransmissionIsBitwiseIdenticalAndReusesMessageID unit/verify revert, verified

RFC7296-2.2-1

Retransmission of a message MUST use the same Message ID as the original message (§2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRtxRetransmissionIsBitwiseIdenticalAndReusesMessageID unit/verify revert, verified
positive TestRtxRetransmissionIsBitwiseIdenticalAndReusesMessageID unit/verify revert, verified

RFC7296-2.2-2

In the unlikely event that Message IDs grow too large to fit in 32 bits, the IKE SA MUST be closed or rekeyed (§2.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestMidInboundCounterFreezesAtTheCeiling unit/verify unproven
negative TestMidNearExhaustionRekeysTheIKESA unit/verify revert, verified
negative TestMidOutboundCounterFreezesAtTheCeiling unit/verify revert, verified
negative TestMidResponderEstablishDoesNotWrapTheCounter unit/verify unproven
positive TestMidInboundCounterFreezesAtTheCeiling unit/verify unproven
positive TestMidNearExhaustionRekeysTheIKESA unit/verify revert, verified
positive TestMidOutboundCounterFreezesAtTheCeiling unit/verify revert, verified
positive TestMidResponderEstablishDoesNotWrapTheCounter unit/verify unproven

RFC7296-2.2-3

Each endpoint in the IKE Security Association maintains two "current" Message IDs: the next one to be used for a request it initiates and the next one it expects to see in a request from the other end. (§2.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. finishResponderEstablish advances only the inbound counter; responder's first request id 0 is classified as new by the initiator

PolarityTestKind and tierProof state
negative TestMidResponderEstablishDoesNotWrapTheCounter unit/verify unproven
positive TestResponderFirstRequestMatchesWhatTheInitiatorExpects unit/verify unproven

RFC7296-2.3-2

An IKE endpoint MUST wait for a response to each of its messages before sending a subsequent message unless it has received a SET_WINDOW_SIZE Notify message from its peer (§2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestDPDNoTransportTakesNoWindow unit/verify unproven
negative TestWinOneRequestPerTick unit/verify revert, verified
negative TestWinTeardownDoesNotHang unit/verify revert, verified
positive TestWinOneRequestPerTick unit/verify revert, verified
positive TestWinTeardownDoesNotHang unit/verify revert, verified

RFC7296-2.3-4

An IKE endpoint MUST NOT exceed the peer's stated window size for transmitted IKE requests (§2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestWinResponseReleasesSlot unit/verify revert, verified
positive TestWinResponseReleasesSlot unit/verify revert, verified

RFC7296-2.3-5

This Notify message MUST NOT be sent in a response; the invalid request MUST NOT be acknowledged (§2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestOsrOutOfWindowRequestIsNotAcknowledged unit/verify unproven
positive TestImiNotificationCarriesTheFourOctetMessageID unit/verify unproven
positive TestOsrOutOfWindowRequestIsNotAcknowledged unit/verify unproven

RFC7296-2.3-7

The data associated with a SET_WINDOW_SIZE notification MUST be 4 octets long and contain the big endian representation of the number of messages the sender promises to keep (§2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSwzMalformedWindowSizeIsRefused unit/verify unproven
negative TestSwzPeerWindowSizeIsRead unit/verify unproven
negative TestNtfySetWindowSizeDataIsFourOctets unit/verify unproven
positive TestSwzPeerWindowSizeIsRead unit/verify unproven
positive TestNtfySetWindowSizeDataIsFourOctets unit/verify unproven

RFC7296-2.3-8

An IKE endpoint MUST be prepared to accept and process a request while it has a request outstanding in order to avoid a deadlock in this situation (§2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestImiHeldWindowSuppressesTheNotification unit/verify unproven
negative TestOsrOwnerLoopKeepsAForeignWindowHeld unit/verify unproven
negative TestOsrRequestAcceptedWhileOursIsOutstanding unit/verify unproven
negative TestOsrRetireOnlyFreesItsOwnWindow unit/verify unproven
positive TestOsrOwnerLoopRetiresTheStrandedWindow unit/verify unproven
positive TestOsrRequestAcceptedWhileOursIsOutstanding unit/verify unproven

RFC7296-2.3-9

Sending this notification is OPTIONAL, and notifications of this type MUST be rate limited (§2.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestImiHeldWindowSuppressesTheNotification unit/verify unproven
negative TestImiUnauthenticatedRequestDrawsNothing unit/verify unproven
positive TestImiNotificationCarriesTheFourOctetMessageID unit/verify unproven
positive TestImiRateLimitCapsTheNotification unit/verify unproven

RFC7296-2.25-1

When a peer receives a TEMPORARY_FAILURE notification, it MUST NOT immediately retry the operation; it MUST wait so that the sender may complete whatever operation caused the temporary condition (§2.25)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestMidTemporaryFailureDefersTheIKERekey unit/verify revert, verified
negative TestMidTemporaryFailureDefersTheRetry unit/verify revert, verified
positive TestMidTemporaryFailureDefersTheIKERekey unit/verify revert, verified
positive TestMidTemporaryFailureDefersTheRetry unit/verify revert, verified

RFC7296-2.8-5

If an SA has expired or is about to expire and rekeying attempts using the mechanisms described here fail, an implementation MUST close the IKE SA and any associated Child SAs and then MAY start new ones (§2.8)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRkyExhaustedRekeyClosesTheChildSAs unit/verify unproven
positive TestRkyExhaustedRekeyClosesTheChildSAs unit/verify unproven

RFC7296-2.8-6

After the new equivalent IKE SA is created, the initiator deletes the old IKE SA, and the Delete payload to delete itself MUST be the last request sent over the old IKE SA (§2.8)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRkyIKERekeyDeleteIsTheLastRequestOnTheOldSA unit/verify revert, verified
positive TestRkyIKERekeyDeleteIsTheLastRequestOnTheOldSA unit/verify revert, verified

RFC7296-2.8-7

The responder to a CREATE_CHILD_SA MUST be prepared to accept messages on an SA before sending its response to the creation request, so there is no ambiguity for the initiator (§2.8)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRkyResponderInstallsTheNewChildBeforeItAnswers unit/verify revert, verified
positive TestRkyResponderInstallsTheNewChildBeforeItAnswers unit/verify revert, verified

RFC7296-2.8.1-1

When there are two SAs eligible to receive packets, a node MUST accept incoming packets through either SA (§2.8.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRkyOldAndNewChildBothReceiveUntilThePeerDeletes unit/verify unproven
positive TestRkyOldAndNewChildBothReceiveUntilThePeerDeletes unit/verify unproven

RFC7296-2.18-2

The new IKE SA MUST reset its message counters to 0 (§2.18)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestRtxRekeyedIKESAResetsMessageCounters unit/verify unproven
positive TestRtxRekeyedIKESAResetsMessageCounters unit/verify unproven

RFC7296-2.18-3

implementations MUST perform a new Diffie-Hellman exchange when rekeying the IKE SA. In other words, an initiator MUST NOT propose the value "NONE" for the Diffie-Hellman transform, and a responder MUST NOT accept such a proposal. (§2.18)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Both roles now proven on the rekey path itself. Initiator: TestRFC7296IKERekeyInitiatorNeverProposesDHNone decrypts the real initiateIKERekey request at the peer and asserts every proposal's D-H transform is the configured group 14 and the KE payload is group 14 (a new exchange); forced toward the violation (configured group NONE) initiateIKERekey returns an error, no bytes, and consumes no message ID. Responder: TestRFC7296IKERekeyResponderRefusesDHNone rewrites only the D-H transform of the real rekey request to NONE, sets local policy to NONE too so nothing else can refuse, and asserts errors.Is ErrDHGroupNone with no SA and no response; the unmodified request is accepted with a new SA. Crypto TestPropDHNoneRefusedForIKESA keeps the NegotiateIKE-level pair. Records: initiateIKERekey, respondIKERekey, NewDHExchange, acceptDHGroup reverts observed red; the crypto-level tags carry none.

PolarityTestKind and tierProof state
negative TestPropDHNoneRefusedForIKESA unit/verify revert, verified
negative TestRFC7296IKERekeyInitiatorNeverProposesDHNone unit/verify revert, verified
negative TestRFC7296IKERekeyResponderRefusesDHNone unit/verify revert, verified
positive TestPropDHNoneRefusedForIKESA unit/verify revert, verified
positive TestRFC7296IKERekeyInitiatorNeverProposesDHNone unit/verify revert, verified
positive TestRFC7296IKERekeyResponderRefusesDHNone unit/verify revert, verified

RFC7296-3.16-1

Identifier (1 octet) - Used in PPP to distinguish replayed messages from repeated ones. Since in IKE, EAP runs over a reliable protocol, the Identifier serves no function here. In a response message, this octet MUST be set to match the identifier in the corresponding request. (§3.16)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge; row widened to the Identifier item head, obligation 'In a response message, this octet MUST be set to match the identifier in the corresponding request' (RFC 7296 3.16). TestEapfmtResponseIdentifierMatchesRequest drives the EAP peer through Identity, MS-CHAPv2 Challenge and Success with identifiers 200, 7 and 91 and requires each response to echo exactly, so a constant or a counter fails. Peer methods other than MS-CHAPv2 are not sampled. No discrimination record.

PolarityTestKind and tierProof state
negative TestEapfmtResponseIdentifierMatchesRequest unit/verify unproven
positive TestEapfmtResponseIdentifierMatchesRequest unit/verify unproven

RFC7296-3.16-2

Length (2 octets, unsigned integer) - The length of the EAP message. MUST be four less than the Payload Length of the encapsulating payload. (§3.16)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge; row widened to the Length item head, obligation 'MUST be four less than the Payload Length of the encapsulating payload' (RFC 7296 3.16). TestEapfmtEAPLengthIsFourLessThanPayloadLength reads both lengths off the encoded IKE payload for five body sizes and requires eapLen == payloadLen-4 and eapLen == 4+size, refusing a repeated or copied length; the decoder recovers every data octet. Send side only; no test feeds a received EAP payload whose lengths disagree. No discrimination record.

PolarityTestKind and tierProof state
negative TestEapfmtEAPLengthIsFourLessThanPayloadLength unit/verify unproven
positive TestEapfmtEAPLengthIsFourLessThanPayloadLength unit/verify unproven

RFC7296-3.16-3

For other codes, the EAP message length MUST be four octets and the Type and Type_Data fields MUST NOT be present. (§3.16)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Success/Failure encode to four octets with no Type; Request keeps Type

PolarityTestKind and tierProof state
negative TestEapfmtSuccessAndFailureCarryNoTypeField unit/verify unproven
positive TestEapfmtSuccessAndFailureCarryNoTypeField unit/verify unproven

RFC7296-3.16-4

In a Response (2) message, Type MUST either be Nak or match the type of the data requested (§3.16)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestEapfmtPeerResponseTypeIsNakOrMatchesRequest unit/verify unproven
positive TestEapfmtPeerResponseTypeIsNakOrMatchesRequest unit/verify unproven

RFC7296-1.7-2

This document adds the restriction in Section 2.13 that all pseudorandom functions (PRFs) used with IKEv2 MUST take variable- sized keys. (§1.7)

Audit verdict: enforced (the tests do what the requirement demands), fresh. HMAC PRFs accept 1..200-octet keys and consume the key

PolarityTestKind and tierProof state
negative TestPRFTakesVariableSizedKeys unit/verify unproven
positive TestPRFTakesVariableSizedKeys unit/verify unproven

RFC7296-2-1

All IKEv2 implementations MUST be able to send, receive, and process IKE messages that are up to 1280 octets long (§2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestMessageHandles1280Octets unit/verify unproven
positive TestMessageHandles1280Octets unit/verify unproven

RFC7296-2.5-1

The minor version number indicates new capabilities, and MUST be ignored by a node with a smaller minor version number, but used for informational purposes by the node with the larger minor version number (§2.5, §3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestMinorVersionIgnoredMajorIsNot unit/verify unproven
positive TestMinorVersionIgnoredMajorIsNot unit/verify unproven

RFC7296-2.5-2

If an endpoint receives a message with a higher major version number, it MUST drop the message (§2.5, §3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestHigherMajorVersionDropped unit/verify unproven
positive TestHigherMajorVersionDropped unit/verify unproven

RFC7296-2.5-6

Also, for forward compatibility, all fields marked RESERVED MUST be set to zero by an implementation running version 2.0 (§2.5, §3.2, §3.3.1, §3.3.2, §3.5, §3.8, §3.13, §3.15, §3.15.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestConfigAttributeReservedBitSentAsZero unit/verify unproven
negative TestReservedFieldsSentAsZero unit/verify unproven
positive TestConfigAttributeReservedBitSentAsZero unit/verify unproven
positive TestReservedFieldsSentAsZero unit/verify unproven

RFC7296-2.5-7

Also, for forward compatibility, all fields marked RESERVED MUST be set to zero by an implementation running version 2.0, and their content MUST be ignored by an implementation running version 2.0 (§2.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged under the D-10 corrected row, which now quotes the whole Section 2.5 sentence (set to zero, and content ignored). Receive clause, this row's obligation: TestRFC7296EveryReservedOctetIsIgnoredOnReceipt parses AUTH, KE, ID, TS, CP bodies and Proposal/Transform substructures with every RESERVED octet at 0xff and asserts no error and DeepEqual to the clean decode; TestRFC7296DefinedOctetBesideReservedIsNotIgnored flips the adjacent defined octet and requires a changed decode or a refusal. Set-to-zero clause: the same positive unit asserts the encoder sends each RESERVED octet as zero for those bodies, and the sending obligation is also RFC7296-2.5-6's row. Generic header flags (wire/rfc7296_test.go) and the CP attribute R bit (rfc7296_cp_test.go) keep their tags. Records: payload_auth ReadFrom and payload_ke ReadFrom reverts observed red, re-recorded for the new row text.

PolarityTestKind and tierProof state
negative TestConfigAttributeReservedBitIgnoredOnReceipt unit/verify revert, verified
negative TestRFC7296DefinedOctetBesideReservedIsNotIgnored unit/verify revert, verified
negative TestReservedFieldsIgnoredOnReceipt unit/verify revert, verified
positive TestConfigAttributeReservedBitIgnoredOnReceipt unit/verify revert, verified
positive TestRFC7296EveryReservedOctetIsIgnoredOnReceipt unit/verify revert, verified
positive TestReservedFieldsIgnoredOnReceipt unit/verify revert, verified

RFC7296-2.5-8

Similarly, payload types that are not defined are reserved for future use; implementations of a version where they are undefined MUST skip over those payloads and ignore their contents. (§2.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. undefined payload type decoded as payloadRaw and the chain continues, outer and inner chain; defined type not demoted

PolarityTestKind and tierProof state
negative TestInnerChainSkipsUndefinedType unit/verify unproven
negative TestUndefinedPayloadTypeSkipped unit/verify unproven
positive TestInnerChainSkipsUndefinedType unit/verify unproven
positive TestUndefinedPayloadTypeSkipped unit/verify unproven

RFC7296-2.5-9

If the critical flag is set and the payload type is unrecognized, the message MUST be rejected (§2.5, §4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestInnerChainRejectsCriticalUnrecognized unit/verify unproven
negative TestCriticalUnrecognizedPayloadRejected unit/verify unproven
positive TestInnerChainRejectsCriticalUnrecognized unit/verify unproven
positive TestCriticalUnrecognizedPayloadRejected unit/verify unproven

RFC7296-2.5-11

If the critical flag is not set and the payload type is unsupported, that payload MUST be ignored (§2.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestInnerChainIgnoresNonCriticalUnsupported unit/verify unproven
negative TestNonCriticalUnsupportedPayloadIgnored unit/verify unproven
positive TestInnerChainIgnoresNonCriticalUnsupported unit/verify unproven
positive TestNonCriticalUnsupportedPayloadIgnored unit/verify unproven

RFC7296-2.5-13

implementations MUST NOT reject as invalid a message with those payloads in any other order. (§2.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Nonce/KE/SA order parses with all three; engine handleAuthResponse accepts unconventional order

PolarityTestKind and tierProof state
negative TestPodAuthResponseAcceptsAuthBeforeIdentity unit/verify unproven
negative TestPayloadOrderNotRejected unit/verify unproven
positive TestPodAuthResponseAcceptsAuthBeforeIdentity unit/verify unproven
positive TestPayloadOrderNotRejected unit/verify unproven

RFC7296-2.5-14

If an endpoint supports major version n, and major version m, it MUST support all versions between n and m (§2.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNATTDispatchAppliesTheSameVersionGate unit/verify unproven
positive TestSupportedMajorVersionSetIsSingleton unit/verify unproven

RFC7296-2.5-15

If it receives a message with a major version that it supports, it MUST respond with that version number (§2.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResponderEchoesTheSupportedMajorVersion unit/verify unproven
positive TestResponderEchoesTheSupportedMajorVersion unit/verify unproven

RFC7296-2.5-16

If they mistakenly (perhaps through an active attacker sending error messages) negotiate to version n, then both will notice that the other side can support a higher version number, and they MUST break the connection and reconnect using version n+1 (§2.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNATTDispatchAppliesTheSameVersionGate unit/verify unproven
positive TestSupportedMajorVersionSetIsSingleton unit/verify unproven

RFC7296-2.5-17

Payloads sent in IKE response messages MUST NOT have the critical flag set (§2.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResponsePayloadsAreNeverCritical unit/verify unproven
positive TestResponsePayloadsAreNeverCritical unit/verify unproven

RFC7296-2.5-18

the response to the IKE request containing that payload MUST include a Notify payload UNSUPPORTED_CRITICAL_PAYLOAD, indicating an unsupported critical payload was included. In that Notify payload, the Notification Data contains the one-octet payload type. (§2.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Response side now proven through the real handler: protected INFORMATIONAL requests with an unrecognized critical inner payload (types 200 and 49) draw a response with exactly one notify, UNSUPPORTED_CRITICAL_PAYLOAD, whose Notification Data is the one octet of that type (so the data follows the payload, not a constant). Negative: the same payload with the critical bit clear is answered with no such notify. Wire tags keep the parse error carrying the type and the non-critical demotion.

PolarityTestKind and tierProof state
negative TestRFC7296NonCriticalUnknownPayloadDrawsNoUnsupportedCritical unit/verify revert, verified
negative TestCritUnknownCriticalPayloadNamesItsType unit/verify revert, verified
positive TestRFC7296UnsupportedCriticalResponseNamesThePayloadType unit/verify revert, verified
positive TestCritUnknownCriticalPayloadNamesItsType unit/verify revert, verified

RFC7296-2.21.2-1

Note, however, that request messages that contain an unsupported critical payload, or where the whole message is malformed (rather than just bad payload contents), MUST be rejected in their entirety, and MUST only lead to an UNSUPPORTED_CRITICAL_PAYLOAD or INVALID_SYNTAX Notification sent as a response. (§2.21.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30 (independent judge). Both halves asserted. Unsupported critical payload: rfc7296_inner_error_answers_test.go::TestRFC7296UnsupportedCriticalPayloadDrawsOnlyThatNotify sends a protected INFORMATIONAL whose only inner payload is private type 200 with C=1; the request never reaches the exchange handlers (peerAlive false) and the answer, decrypted under the IKE SA, carries exactly one payload, UNSUPPORTED_CRITICAL_PAYLOAD with data {200}. Malformed message: TestErrInnerParseFailureDrawsInvalidSyntaxAndOuterDrawsNothing (truncated inner chain answered with INVALID_SYNTAX only). Negative: TestCritChainReportsTruncationButNotBadContents (bad payload contents are not a malformed message). Revert record observed red on inbound.go::respondInnerParseError. Re-judged 2026-10-10 (independent judge, mode rejudge): every tagged unit is byte-identical to the judged one (git diff 2d57003d45..HEAD touches only other functions, a const block, and new functions appended to the file), so the verdict stands unchanged.

PolarityTestKind and tierProof state
negative TestCritChainReportsTruncationButNotBadContents unit/verify revert, verified
positive TestRFC7296UnsupportedCriticalPayloadDrawsOnlyThatNotify unit/verify revert, verified
positive TestErrInnerParseFailureDrawsInvalidSyntaxAndOuterDrawsNothing unit/verify revert, verified
positive TestCritChainReportsTruncationButNotBadContents unit/verify revert, verified

RFC7296-2.21.2-2

Specifically, a responder may include all the payloads associated with authentication (IDr, CERT, and AUTH) while sending error notifications for the piggybacked exchanges (FAILED_CP_REQUIRED, NO_PROPOSAL_CHOSEN, and so on), and the initiator MUST NOT fail the authentication because of this. (§2.21.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-10 against RFC 7296 S2.21.2 "a responder may include all the payloads associated with authentication (IDr, CERT, and AUTH) while sending error notifications for the piggybacked exchanges (FAILED_CP_REQUIRED, NO_PROPOSAL_CHOSEN, and so on), and the initiator MUST NOT fail the authentication because of this." New unit TestInitiatorKeepsChildlessIKESA takes a real PSK IKE_AUTH response, removes SAr2/TSi/TSr and adds NO_PROPOSAL_CHOSEN with IDr and AUTH untouched: handleAuthResponse must reach StateEstablished, mark the SA childless, log the refusal and send nothing (no Delete). Its negative control flips one AUTH octet in the same response and requires StateDead, so the outcome is decided by AUTH, not by the notify. TestErrInitiatorSurvivesPiggybackedErrorNotify (unchanged) drives NO_PROPOSAL_CHOSEN, FAILED_CP_REQUIRED and TS_UNACCEPTABLE to established and AUTHENTICATION_FAILED to dead. An initiator that failed on the notify or on the missing SAr2 goes red in both. The negatives are controls, since a MUST NOT on the receiver has no violating input. Re-judged 2026-10-10 (independent judge, mode rejudge): every tagged unit is byte-identical to the judged one (git diff 2d57003d45..HEAD touches only other functions, a const block, and new functions appended to the file), so the verdict stands unchanged.

PolarityTestKind and tierProof state
negative TestInitiatorKeepsChildlessIKESA unit/verify revert, verified
negative TestErrInitiatorSurvivesPiggybackedErrorNotify unit/verify unproven
positive TestInitiatorKeepsChildlessIKESA unit/verify revert, verified
positive TestErrInitiatorSurvivesPiggybackedErrorNotify unit/verify unproven

RFC7296-2.21.2-3

Extension documents may define new error notifications with these semantics, but MUST NOT use them unless the peer has been shown to understand them, such as by using the Vendor ID payload (§2.21.2)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestMobikeAuthExtensionErrorsRequirePeerUnderstanding unit/verify revert, verified
positive TestMobikeAuthExtensionErrorsRequirePeerUnderstanding unit/verify revert, verified

RFC7296-2.21.3-1

After the IKE SA is authenticated, all requests having errors MUST result in a response notifying the other end of the error (§2.21.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestErrNewChildRequestIsAnswered unit/verify unproven
negative TestErrRefusedChildRekeyIsAnswered unit/verify unproven
negative TestErrRefusedIKERekeyIsAnswered unit/verify unproven
positive TestDelMalformedSPISizeDrawsInvalidSyntax unit/verify unproven
positive TestErrNewChildRequestIsAnswered unit/verify unproven
positive TestErrRefusedChildRekeyIsAnswered unit/verify unproven
positive TestErrRefusedIKERekeyIsAnswered unit/verify unproven

RFC7296-2.21.4-1

If the message is marked as a response, the node can audit the suspicious event but MUST NOT respond (§2.21.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNtfOutOfSAIgnoresResponses unit/verify unproven
negative TestNtfOutOfSASkipsSAInitAndRateLimits unit/verify unproven
negative ipsec-error-notify-no-loop.ci functional/verify unproven
positive TestNtfOutOfSAIgnoresResponses unit/verify unproven
positive TestNtfOutOfSASkipsSAInitAndRateLimits unit/verify unproven
positive ipsec-error-notify-no-loop.ci functional/verify unproven

RFC7296-2.21.4-2

If a response is sent, the response MUST be sent to the IP address and port from where it came with the same IKE SPIs and the Message ID copied. (§2.21.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-15 after 1ae1c731bd moved the three reject=stderr:pattern= lines of ipsec-error-notify-no-loop.ci under the daemon cmd line; under the new harness a stderr reject is a whole-run log check, so no assertion reads less, and expect=exit and the probe's pass line still bind the fixture. RFC 7296 Section 2.21.4: 'If a response is sent, the response MUST be sent to the IP address and port from where it came with the same IKE SPIs and the Message ID copied.' tunnelIPsecErrorNotify reads the answer on the socket that sent the request and fails unless both SPIs, exchange type 37, the Response flag and Message ID 7 are copied; the ordering marker with a different initiator SPI must draw an answer carrying that SPI and Message ID 11, so the copy is per request. TestNtfOutOfSAAnswersWithInvalidIKESPI and TestNtfOutOfSAAnswerCarriesTheSocketFraming pin the same fields and the arrival socket framing at unit level.

PolarityTestKind and tierProof state
negative TestNtfOutOfSAAnswerCarriesTheSocketFraming unit/verify unproven
negative TestNtfOutOfSAAnswersWithInvalidIKESPI unit/verify unproven
negative ipsec-error-notify-no-loop.ci functional/verify unproven
positive TestNtfOutOfSAAnswerCarriesTheSocketFraming unit/verify unproven
positive TestNtfOutOfSAAnswersWithInvalidIKESPI unit/verify unproven
positive ipsec-error-notify-no-loop.ci functional/verify unproven

RFC7296-2.21.4-3

The response MUST NOT be cryptographically protected (§2.21.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNtfOutOfSAAnswerIsUnprotected unit/verify unproven
positive TestNtfOutOfSAAnswerIsUnprotected unit/verify unproven

RFC7296-2.21.4-4

The response MUST NOT be cryptographically protected and MUST contain an INVALID_IKE_SPI Notify payload. (§2.21.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-15 after 1ae1c731bd moved the .ci's stderr rejects under the daemon cmd line (whole-run scope, no assertion weakened). RFC 7296 Section 2.21.4: 'The response MUST NOT be cryptographically protected and MUST contain an INVALID_IKE_SPI Notify payload.' TestNtfOutOfSAAnswersWithInvalidIKESPI parses the answer and requires exactly one payload, a Notify of type INVALID_IKE_SPI with an empty SPI and no data, so a wrong type, a missing Notify, an extra payload or an SK payload fails; the fixture behind ipsec-error-notify-no-loop.ci requires the body after the header to be one 4-octet Notify of type 4 (INVALID_IKE_SPI) with next payload 0 through the real UDP path. The negatives (an IKE_SA_INIT to an unknown SPI draws nothing) are controls on the emitter's guard rather than violating inputs. No discrimination record.

PolarityTestKind and tierProof state
negative TestNtfOutOfSAAnswersWithInvalidIKESPI unit/verify unproven
negative ipsec-error-notify-no-loop.ci functional/verify unproven
positive TestNtfOutOfSAAnswersWithInvalidIKESPI unit/verify unproven
positive ipsec-error-notify-no-loop.ci functional/verify unproven

RFC7296-2.21.4-5

A peer receiving such an unprotected Notify payload MUST NOT respond (§2.21.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNtfEmitterIsAFixedPoint unit/verify unproven
negative ipsec-error-notify-no-loop.ci functional/verify unproven
positive TestNtfEmitterIsAFixedPoint unit/verify unproven
positive ipsec-error-notify-no-loop.ci functional/verify unproven

RFC7296-2.21.4-6

A peer receiving such an unprotected Notify payload MUST NOT respond and MUST NOT change the state of any existing SAs. (§2.21.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after 87b04ed6cd. RFC 7296 2.21.4: "A peer receiving such an unprotected Notify payload MUST NOT respond and MUST NOT change the state of any existing SAs." This row keeps the state clause (MUST NOT respond is RFC7296-2.21.4-5). The defect the previous verdict named is fixed at the producer: handleAuthResponse and handleEAPResponse (fsm.go) now return on an IKE_AUTH response with no SK payload before touching the SA, where they used to set StateDead. The new TestErrUnprotectedNotifyLeavesHalfOpenSA uses the bytes sendInvalidIKESPI writes (asserted: IKE_AUTH, R bit, one unprotected INVALID_IKE_SPI Notify), delivers them through routeInbound to an initiator SA (newInitiatorSA via testSAWithKeys) in StateAuthSent and in StateEAPInProgress, and asserts no datagram before a sentinel and State, NextMsgID, ExpectedMsgID, RetransmitTime, RetransmitCount and the EAP session unchanged. The mutant record restoring StateDead in the handleAuthResponse drop is observed red; the EAP subtest has no record, but read at the producer handleInbound's StateEAPInProgress arm reaches handleEAPResponse for this input, so a StateDead there fails the State assertion. The handshake arms read no Message ID before the SK check, so the message ID the test picks (sa.NextMsgID) does not weaken it. The established route stays as judged before: TestErrUnprotectedNotifyChangesNoState (positive, unit unchanged) with its SK-protected negative at the same R bit and Message ID, both polarities with mutant records on the inboundInvalid decrypt condition in handleOwnedInbound. Other routes, read at the producer: handleOwnedInbound drops every unprotected message silently (decryptAndParse fails on no SK); handleResponderInbound returns before its state switch on any message with the R bit, which TestNrsResponseNeverDrawsAResponse (tagged RFC7296-3.1-12) pins, untagged here; the initiator StateSAInitSent arm kills the attempt on an IKE_SA_INIT response holding only an error notify, which Section 2.21.1 sanctions ("In an IKE_SA_INIT exchange, any error notification causes the exchange to fail.") and which no keyed SA yet exists for. Residual outside this row: a half-open initiator SA still goes StateDead when an SK payload is present but fails decryption (handleAuthResponse and handleEAPResponse, 'decryption failed'), a forged-SK case, not an unprotected Notify.

PolarityTestKind and tierProof state
negative TestErrUnprotectedNotifyChangesNoState unit/verify mutant, verified
positive TestErrUnprotectedNotifyChangesNoState unit/verify mutant, verified
positive TestErrUnprotectedNotifyLeavesHalfOpenSA unit/verify mutant, verified

RFC7296-2.21.4-7

The recipient MUST NOT change the state of any SAs as a result, but may wish to audit the event to aid in diagnosing malfunctions. (§2.21.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30 (independent judge) after the row was narrowed to the MUST NOT sentence, verbatim at RFC 7296 Section 2.21.4: "The recipient MUST NOT change the state of any SAs as a result, but may wish to audit the event to aid in diagnosing malfunctions." The SHOULD-send sentence is RFC7296-2.21.4-8 {gap}. TestErrProtectedInformationalNotifyChangesNoState: a protected INFORMATIONAL carrying INVALID_SELECTORS (the kind of notify a node sends after a suspicious ESP packet) is answered, leaves the IKE SA state unchanged and the Child SA in place; control: the same exchange carrying a Delete does change state. Revert records observed red on inbound.go::handleInformationalOwned. Limit: the Child SA check is pointer identity, so an in-place mutation of the Child SA would not be seen; handleInformationalOwned acts on Delete and MOBIKE notifies only. Re-judged 2026-10-10 (independent judge, mode rejudge): every tagged unit is byte-identical to the judged one (git diff 2d57003d45..HEAD touches only other functions, a const block, and new functions appended to the file), so the verdict stands unchanged.

PolarityTestKind and tierProof state
negative TestErrProtectedInformationalNotifyChangesNoState unit/verify revert, verified
positive TestErrProtectedInformationalNotifyChangesNoState unit/verify revert, verified

RFC7296-2.21.4-8

A node receiving a suspicious message from an IP address (and port, if NAT traversal is used) with which it has an IKE SA SHOULD send an IKE Notify payload in an IKE INFORMATIONAL exchange over that SA. (§2.21.4)

Audit verdict: unimplemented (no code path enforces the requirement), fresh. Re-judged 2026-10-15 after 4fecbbd82a changed handleOwnedInbound: the only edit calls rebindChildSAs (rebind.go) when an AUTHENTICATED message moves the peer endpoint, migrating Child SAs or owing a rekey; it sends no Notify. RFC 7296 Section 2.21.4: 'A node receiving a suspicious message from an IP address (and port, if NAT traversal is used) with which it has an IKE SA SHOULD send an IKE Notify payload in an IKE INFORMATIONAL exchange over that SA.' handleOwnedInbound still returns after countErrorNotifySuppressed on outer-parse-unauthenticated, unprotected-retransmit, replay-rate-limited and invalid-msgid-unauthenticated without starting a protected exchange, and answerOutOfSA (notify_error.go) still emits only the unprotected INVALID_IKE_SPI response to an unknown SPI with no address-based existing-SA lookup. The SHOULD stays unmet and the {gap} annotation matches the code. No tests tag this row.

No test carries RFC7296-2.21.4-8, so no unit is bound to it.

RFC7296-3.10.1-1

Types in the range 0 - 16383 are intended for reporting errors. An implementation receiving a Notify payload with one of these types that it does not recognize in a response MUST assume that the corresponding request has failed entirely. (§3.10.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. unrecognized error-range notify in an IKE_AUTH response ends the exchange; unrecognized status type ignored and SA establishes Re-judged 2026-10-10 (independent judge, mode rejudge): every tagged unit is byte-identical to the judged one (git diff 2d57003d45..HEAD touches only other functions, a const block, and new functions appended to the file), so the verdict stands unchanged.

PolarityTestKind and tierProof state
negative TestErrUnrecognizedNotifyHandling unit/verify unproven
positive TestErrUnrecognizedNotifyHandling unit/verify unproven

RFC7296-3.10.1-2

Unrecognized error types in a request and status types in a request or response MUST be ignored, and they should be logged (§3.10.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestErrUnrecognizedNotifyHandling unit/verify unproven
negative TestCritNotifyTypeClassification unit/verify unproven
positive TestErrUnrecognizedNotifyHandling unit/verify unproven
positive TestCritNotifyTypeClassification unit/verify unproven

RFC7296-3.10.1-3

To avoid leaking information to someone probing a node, this status MUST be sent in response to any error not covered by one of the other status types. (§3.10.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30 (independent judge). INVALID_SYNTAX for errors no other status type covers, in an authenticated request: truncated inner chain (TestErrInnerParseFailureDrawsInvalidSyntaxAndOuterDrawsNothing) and now Payload Length 0 and 3 (rfc7296_inner_error_answers_test.go::TestRFC7296UncoveredInnerErrorsDrawInvalidSyntax), each answered with exactly one notify, INVALID_SYNTAX, and not dispatched. Every non-critical inner-chain parse error reaches the same single producer, respondInnerParseError, which answers INVALID_SYNTAX unconditionally. An invalid field value (a Delete with the wrong SPI Size) is answered with INVALID_SYNTAX under RFC7296-3.11-2's tests. Negative: an outer parse failure (Message ID and checksum never validated) draws nothing. Revert record observed red on inbound.go::respondInnerParseError. Re-judged 2026-10-10 (independent judge, mode rejudge): every tagged unit is byte-identical to the judged one (git diff 2d57003d45..HEAD touches only other functions, a const block, and new functions appended to the file), so the verdict stands unchanged.

PolarityTestKind and tierProof state
negative TestErrInnerParseFailureDrawsInvalidSyntaxAndOuterDrawsNothing unit/verify revert, verified
positive TestRFC7296UncoveredInnerErrorsDrawInvalidSyntax unit/verify revert, verified
positive TestErrInnerParseFailureDrawsInvalidSyntaxAndOuterDrawsNothing unit/verify revert, verified

RFC7296-2.6-2

Each endpoint chooses one of the two SPIs and MUST choose them so as to be unique identifiers of an IKE SA (§2.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSPIsAreUniqueIdentifiers unit/verify unproven
positive TestSPIsAreUniqueIdentifiers unit/verify unproven

RFC7296-2.6-3

The data associated with this notification MUST be between 1 and 64 octets in length (inclusive) (§2.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCkeEchoedCookieIsBoundedToo unit/verify unproven
positive TestCkeMintedCookieIsWithinTheLengthBound unit/verify unproven

RFC7296-2.6-4

If the IKE_SA_INIT response includes the COOKIE notification, the initiator MUST then retry the IKE_SA_INIT request, and include the COOKIE notification containing the received data as the first payload, and all other payloads unchanged (§2.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCkeCookieIsAbsentWithoutAChallenge unit/verify unproven
positive TestCkeRetryCarriesCookieFirstAndNothingElseChanged unit/verify unproven

RFC7296-2.6-5

When one party receives an IKE_SA_INIT request containing a cookie whose contents do not match the value expected, that party MUST ignore the cookie and process the message as if no cookie had been included; usually this means sending a response containing a new cookie (§2.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCkeValidCookieReachesTheHandshake unit/verify unproven
positive TestCkeMismatchedCookieIsIgnoredNotRejected unit/verify unproven

RFC7296-2.6.1-1

Implementations SHOULD support this shorter exchange, but MUST NOT fail if other implementations do not support this shorter exchange (§2.6.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCkeCookieAndInvalidKECombineWithoutFailing unit/verify unproven
positive TestCkeSecondCookieReplacesTheFirstWithoutFailing unit/verify unproven

RFC7296-2.10-2

Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 bits in size (§2.10)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged under the D-10 corrected row 'Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 bits in size'. The 128-bit floor, both directions: send, TestRFC7296EmittedNoncesAreAtLeast128Bits checks all six emitted nonces (IKE_SA_INIT Ni/Nr, Child SA rekey Ni/Nr, IKE SA rekey Ni/Nr off the wire) are >= 16 octets; receive, TestNonceLengthBounds accepts 16 and refuses 15 octets with ErrNonceTooShort. The randomness clause the span passes through is the verbatim text of RFC7296-2.10-4, whose own tagged units (engine/rfc7296_session_test.go) carry it; this row's units assert the floor alone, as the correction states. Record: GenerateNonce revert observed red, re-recorded for the new row text.

PolarityTestKind and tierProof state
negative TestNonceLengthBounds unit/verify revert, verified
positive TestRFC7296EmittedNoncesAreAtLeast128Bits unit/verify revert, verified
positive TestNonceLengthBounds unit/verify revert, verified

RFC7296-2.10-3

Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 bits in size, and MUST be at least half the key size of the negotiated pseudorandom function (PRF). (§2.10)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30 after the row text was widened to the whole verbatim Section 2.10 sentence (D-10, rfc/corrections/rfc7296.md). The gated clause is the half-PRF-key floor; the random choice is gated by RFC7296-2.10-4 and the 128-bit floor by RFC7296-2.10-2, which quote the leading spans of the same sentence, so this row's tests are judged on the final clause alone. Positive TestRFC7296EmittedNoncesMeetHalfOfEveryPRFKey reads every PRF from the registry and asserts all six emission sites (IKE_SA_INIT Ni/Nr, Child SA rekey Ni/Nr, IKE SA rekey Ni/Nr, rekey nonces off the wire); negative TestRFC7296EmittedNoncesMeetTheLargestPRFBound negotiates prf-hmac-sha2-512 on a rekey and checks the wire Ni/Nr meet 32 octets. Records re-recorded (GenerateNonce revert). Judge's own clause probe: GenerateNonce capped at 16 octets via go test -overlay reddens both units (sha384/sha512 halves), so both discriminate the half-PRF clause, not merely call the producer.

PolarityTestKind and tierProof state
negative TestRFC7296EmittedNoncesMeetTheLargestPRFBound unit/verify revert, verified
positive TestRFC7296EmittedNoncesMeetHalfOfEveryPRFKey unit/verify revert, verified

RFC7296-2.13-1

For algorithms that accept a variable-length key, a fixed key size MUST be specified as part of the cryptographic transform negotiated (§2.13)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestTransformRegistryStatesKeySizes unit/verify unproven
positive TestTransformRegistryStatesKeySizes unit/verify unproven

RFC7296-2.13-3

The preferred key size MUST be used as the length of SK_d, SK_pi, and SK_pr (§2.13, §2.14)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSKKeyLengthsComeFromTransforms unit/verify unproven
positive TestSKKeyLengthsComeFromTransforms unit/verify unproven

RFC7296-2.13-4

Other types of PRFs MUST specify their preferred key size (§2.13)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestTransformRegistryStatesKeySizes unit/verify unproven
positive TestTransformRegistryStatesKeySizes unit/verify unproven

RFC7296-2.15-1

The management interface by which the shared secret is provided MUST accept ASCII strings of at least 64 octets (§2.15)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPSKAcceptsAtLeast64ASCIIOctets unit/verify unproven
positive TestPSKAcceptsAtLeast64ASCIIOctets unit/verify unproven

RFC7296-2.15-2

MUST NOT add a null terminator before using them as shared secrets (§2.15)

Audit verdict: enforced (the tests do what the requirement demands), fresh. The weak finding (use path unexercised) is closed. Parse side: ipsec TestPSKHasNoNullTerminatorAdded (parseAuthConfig keeps the PSK octets, adds and strips nothing). Use side, new engine/rfc7296_psk_terminator_test.go: positive TestRFC7296PSKIsUsedWithoutANullTerminator compares computePSKAuth's AUTH with an independent stdlib HMAC-SHA2-256 prf(prf(secret,'Key Pad for IKEv2'),SignedOctets) over the secret octets alone (equal) and over secret+0x00 (not equal), and verifyPSKAuth accepts the no-terminator AUTH; negative TestRFC7296PSKWithANullTerminatorAddedIsRefused: verifyPSKAuth refuses the AUTH over secret+0x00 with errAuthFailed, so the receiving side adds no terminator either. Producers read: both pass []byte(sa.PeerCfg.Auth.PSK) to computeAuthFromSharedSecret/verifyAuthFromSharedSecret. Records: computePSKAuth and verifyPSKAuth panic reverts observed red. Judge ran both: PASS. Prose defect, not a proof gap: psktermSecret is 65 octets, while its comment and both claims say 64; the claim wording should be corrected (and the records re-recorded) by the author.

PolarityTestKind and tierProof state
negative TestRFC7296PSKWithANullTerminatorAddedIsRefused unit/verify revert, verified
negative TestPSKHasNoNullTerminatorAdded unit/verify revert, verified
positive TestRFC7296PSKIsUsedWithoutANullTerminator unit/verify revert, verified
positive TestPSKHasNoNullTerminatorAdded unit/verify revert, verified

RFC7296-2.17-1

keying material for each Child SA MUST be taken from the expanded KEYMAT using the following rules: o All keys for SAs carrying data from the initiator to the responder are taken before SAs going from the responder to the initiator. (§2.17)

Audit verdict: enforced (the tests do what the requirement demands), fresh. DeriveChildSAKeys slices recomputed prf+ KEYMAT with both initiator keys before responder keys

PolarityTestKind and tierProof state
negative TestChildSAKeymatOrder unit/verify unproven
positive TestChildSAKeymatOrder unit/verify unproven

RFC7296-2.17-2

For ESP and AH, [IPSECARCH] defines the order, namely: the encryption key (if any) MUST be taken from the first bits and the integrity key (if any) MUST be taken from the remaining bits. (§2.17)

Audit verdict: enforced (the tests do what the requirement demands), fresh. encryption key then integrity key per direction, positional, asserted against recomputed KEYMAT

PolarityTestKind and tierProof state
negative TestChildSAKeymatOrder unit/verify unproven
positive TestChildSAKeymatOrder unit/verify unproven

RFC7296-3.1-1

An Encrypted payload MUST be the last payload in a packet (§3.1, §3.14)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSKIsLastAndNeverNested unit/verify unproven
positive TestSKIsLastAndNeverNested unit/verify unproven

RFC7296-3.1-2

an Encrypted payload MUST NOT contain another Encrypted payload (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. IKE_AUTH request and response inner chains hold no SK payload; negative is a vacuity guard

PolarityTestKind and tierProof state
negative TestSKIsLastAndNeverNested unit/verify unproven
positive TestSKIsLastAndNeverNested unit/verify unproven

RFC7296-3.1-3

Initiator's SPI (8 octets) - A value chosen by the initiator to identify a unique IKE Security Association. This value MUST NOT be zero. (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Send: GenerateSPI and new SAs asserted non-zero (TestSPIZeroRules, positive, recorded on GenerateSPI). Receive, both dispatchers: TestRFC7296ZeroInitiatorSPIIsDroppedOnReceipt (port 500, dispatchInbound) and TestRFC7296ZeroInitiatorSPIIsDroppedOnTheNATTSocket (port 4500, dispatchNATTInbound, non-ESP marker) each put an SA with a zero Initiator's SPI in the table, so without the guard the zero-iSPI datagram would reach that SA's owner; the following non-zero datagram is delivered (NAT-T: marker stripped). Records are whole-producer reverts (reach); the isolation comes from the zero-iSPI SA in the table. Closure rejudge 2026-10-02: the negative tag on TestSPIZeroRules was removed, since its body never calls dispatchInbound; the negative polarity rests on the two dedicated recorded units above.

PolarityTestKind and tierProof state
negative TestRFC7296ZeroInitiatorSPIIsDroppedOnTheNATTSocket unit/verify revert, verified
negative TestRFC7296ZeroInitiatorSPIIsDroppedOnReceipt unit/verify revert, verified
positive TestSPIZeroRules unit/verify revert, verified

RFC7296-3.1-4

Responder's SPI (8 octets) - A value chosen by the responder to identify a unique IKE Security Association. This value MUST be zero in the first message of an IKE initial exchange (including repeats of that message including a cookie). (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. First message: TestSPIZeroRules asserts octets 8..15 zero in Ze's IKE_SA_INIT request, non-zero in the response. Cookie repeat: TestRFC7296ResponderSPIIsZeroInTheFirstMessageAndItsCookieRepeat answers a COOKIE challenge whose Responder's SPI is 0909..09, checks the repeat carries the COOKIE notify and the same Initiator's SPI, and asserts octets 8..15 of the repeat are zero, red on a retry that copies the challenge's SPI. Rejudged 2026-10-02: TestSPIZeroRules changed only by the removal of its RFC7296-3.1-3 negative tag lines; the 3.1-4 assertions are unchanged.

PolarityTestKind and tierProof state
negative TestSPIZeroRules unit/verify revert, verified
positive TestSPIZeroRules unit/verify revert, verified
positive TestRFC7296ResponderSPIIsZeroInTheFirstMessageAndItsCookieRepeat unit/verify revert, verified

RFC7296-3.1-5

Implementations based on this version of IKE MUST set the major version to 2 (§3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestBuiltMessagesCarryVersion2Point0 unit/verify unproven
positive TestBuiltMessagesCarryVersion2Point0 unit/verify unproven

RFC7296-3.1-6

Implementations based on this version of IKE MUST set the minor version to 0 (§3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestBuiltMessagesCarryVersion2Point0 unit/verify unproven
positive TestBuiltMessagesCarryVersion2Point0 unit/verify unproven

RFC7296-3.1-7

'X' bits MUST be cleared when sending (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. every engine-built message has X bits clear; I and R observed so the mask is not vacuous

PolarityTestKind and tierProof state
negative TestBuiltMessagesClearXAndVBits unit/verify unproven
positive TestBuiltMessagesClearXAndVBits unit/verify unproven

RFC7296-3.1-8

'X' bits MUST be cleared when sending and MUST be ignored on receipt. (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after e855bc0689. RFC 7296 3.1: "'X' bits MUST be cleared when sending and MUST be ignored on receipt." This row keeps the receive clause (the send clause is RFC7296-3.1-7, correction 2026-10-11). The earlier finding (the fresh request bypassed the dispatch site that reads the flags octet) is fixed: TestXBitsIgnoredOnReceipt now calls tryResponderSAInit, which tests pkt.Data[19] at register.go and then routes through handleInbound into handleResponderInbound (responder.go Flags&FlagResponse) and handleSAInitRequest; a protected INFORMATIONAL request with every X bit set goes through handleOwnedInbound (inbound.go isResponse) and must be answered, advance ExpectedMsgID and credit liveness; an IKE_SA_INIT response with the X bits goes through handleInbound (fsm.go StateSAInitSent arm) and must reach auth-sent. Each outcome is exact and matches the clean message, not 'no error'. Negative: the same fresh request with the R bit (not an X bit) is refused with no SA, so the positive is not passing through a flags-blind path; it is a control for the X-bit scope rather than a violation of this clause, which is the only negative an ignore obligation admits. Discrimination: mutant records at register.go tryResponderSAInit (refuse any bit but I: positive red; never refuse R: negative red). The owned and initiator sites carry no record, but by reading a break there that refuses or reclassifies on an X bit leaves the request unanswered or the initiator in sa-init-sent, both asserted. Residual, not a defect: four receive readers are not driven with X bits (fsm.go AUTH-response and EAP-response arms, the established-SA response arm, the out-of-SA guard in sendInvalidIKESPI); every one tests Flags&wire.FlagResponse alone, so the code complies, and the claim enumerates only the three messages it asserts.

PolarityTestKind and tierProof state
negative TestXBitsIgnoredOnReceipt unit/verify mutant, verified
positive TestXBitsIgnoredOnReceipt unit/verify mutant, verified

RFC7296-3.1-9

R (Response) - This bit indicates that this message is a response to a message containing the same Message ID. This bit MUST be cleared in all request messages and MUST be set in all responses. (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after the row was widened to the R item head. Whole sentence 'This bit MUST be cleared in all request messages and MUST be set in all responses' (RFC 7296 3.1). TestResponseBitMatchesDirection compares the R bit for equality with isResponse on every engine-built message, so a request with R set or a response with R clear fails. TestRFC7296InitiatorIgnoresAResponseWithTheRBitClear feeds handleInbound the responder's real IKE_SA_INIT answer with only the R bit cleared (state stays sa-init-sent), then the untouched answer (advances): isolation by a one-bit difference. Revert records on buildSAInitResponse and handleInbound are reach proofs only.

PolarityTestKind and tierProof state
negative TestRFC7296InitiatorIgnoresAResponseWithTheRBitClear unit/verify revert, verified
positive TestResponseBitMatchesDirection unit/verify revert, verified

RFC7296-3.1-11

V (Version) - This bit indicates that the transmitter is capable of speaking a higher major version number of the protocol than the one indicated in the major version number field. Implementations of IKEv2 MUST clear this bit when sending and MUST ignore it in incoming messages. (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after 9c536b0e45. RFC 7296 3.1: "Implementations of IKEv2 MUST clear this bit when sending and MUST ignore it in incoming messages." Send clause: the previous gap is closed. A grep of non-test code under internal/component/ike finds exactly five header-flags writers: writeAuthHeaderWithMsgID (auth.go), the IKE_SA_INIT request literal (initiator.go), buildSAInitResponse and sendSAInitNotifyRaw (responder.go), sendInvalidIKESPI (notify_error.go); none copies an incoming flags octet and no non-test code sets wire.FlagVersion. TestBuiltMessagesClearXAndVBits (unit unchanged) samples the first three. The new TestSAInitNotifiesClearXAndVBits drives sendSAInitNotifyRaw through both of its production callers, sendCookieChallenge (COOKIE) and sendSAInitNotify (NO_PROPOSAL_CHOSEN, INVALID_KE_PAYLOAD), and TestInvalidIKESPIClearsXAndVBits drives sendInvalidIKESPI through answerOutOfSA, once with a request carrying V and every X bit so a flags copy would be caught. Each parses the datagram the peer read, pins the notify type (which writer) and the R bit (right octet), and asserts V clear. Mutant records setting wire.FlagVersion in each header literal are observed red. Receive clause unchanged and sound: the V-bit half of TestXBitsIgnoredOnReceipt (negative tag, unit unchanged) drives tryResponderSAInit, handleOwnedInbound and handleInbound with V set and asserts the clean outcome and a major version 2 answer, with a mutant record at tryResponderSAInit. The #2 tag of TestBuiltMessagesClearXAndVBits (the encoder can set V) is an anti-vacuity control, not a second negative. Residual for the reader: the receive readers in the AUTH and EAP response arms mask R alone and are not driven with V set.

PolarityTestKind and tierProof state
negative TestBuiltMessagesClearXAndVBits unit/verify unproven
negative TestXBitsIgnoredOnReceipt unit/verify mutant, verified
positive TestInvalidIKESPIClearsXAndVBits unit/verify mutant, verified
positive TestSAInitNotifiesClearXAndVBits unit/verify mutant, verified
positive TestBuiltMessagesClearXAndVBits unit/verify unproven

RFC7296-3.1-12

An IKE endpoint MUST NOT generate a response to a message that is marked as being a response (with one exception; see Section 2.21.2) (§3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. TestNrsResponseNeverDrawsAResponse drives the responder handshake, out-of-SA admission (with a matching source so the flag is the only difference), INFORMATIONAL and CREATE_CHILD_SA paths: a message marked as a response builds and sends nothing, the same message with the flag clear is answered. TestNrsInformationalHandlerRefusesAResponse takes handleInformationalOwned at its own entry point, both ways. TestResponseBitMatchesDirection's moved negative repeats the handshake arm (R-set IKE_SA_INIT leaves the responder idle, the clear one reaches sa-init-received). The Section 2.21.2 exception is not exercised here.

PolarityTestKind and tierProof state
negative TestResponseBitMatchesDirection unit/verify revert, verified
negative TestNrsInformationalHandlerRefusesAResponse unit/verify revert, verified
negative TestNrsResponseNeverDrawsAResponse unit/verify revert, verified
positive TestNrsInformationalHandlerRefusesAResponse unit/verify revert, verified
positive TestNrsResponseNeverDrawsAResponse unit/verify revert, verified

RFC7296-3.2-2

Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type. MUST be ignored by the recipient if the recipient understands the payload type code. (§3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge; row widened to the Critical item head, kept clause 'MUST be ignored by the recipient if the recipient understands the payload type code' (RFC 7296 3.2). TestCriticalBitIgnoredForKnownType (Message.ReadFrom, outer chain) and TestInnerChainIgnoresCriticalOnKnownType (ParsePayloadChain, inner chain) parse a critical Nonce to the same *PayloadNonce and data with no error, so a parser that refused or altered a critical known payload fails. The negatives (critical unknown type refused with ErrUnsupportedCrit) are scoping controls showing the bit is read, not violations of this clause. One known type (Nonce) is sampled; chain.go consults Critical only in the unknown-payload branch. No discrimination record.

PolarityTestKind and tierProof state
negative TestInnerChainIgnoresCriticalOnKnownType unit/verify unproven
negative TestCriticalBitIgnoredForKnownType unit/verify unproven
positive TestInnerChainIgnoresCriticalOnKnownType unit/verify unproven
positive TestCriticalBitIgnoredForKnownType unit/verify unproven

RFC7296-3.2-3

all implementations MUST understand all payload types defined in this document (§3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. decodePayload yields a concrete type for all sixteen types 33-48; type 204 is ErrUnknownPayload

PolarityTestKind and tierProof state
negative TestAllDefinedPayloadTypesUnderstood unit/verify unproven
positive TestAllDefinedPayloadTypesUnderstood unit/verify unproven

RFC7296-3.2-4

Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type. MUST be ignored by the recipient if the recipient understands the payload type code. MUST be set to zero for payload types defined in this document. (§3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge; row widened to the Critical item head, kept clause 'MUST be set to zero for payload types defined in this document' (RFC 7296 3.2). TestDefinedPayloadTypesAreSentUncritical sweeps the outer and inner chains of every engine-built message and fails on any defined type with Critical set, with a non-vacuity floor; TestEngineSourceNeverSetsTheCriticalField walks the engine source and refuses a literal or assigned Critical, proven against fixtures. The #2 tag (encoder writes 0x80 when asked) is an expressibility control, not a violating input. No discrimination record.

PolarityTestKind and tierProof state
negative TestDefinedPayloadTypesAreSentUncritical unit/verify unproven
positive TestDefinedPayloadTypesAreSentUncritical unit/verify unproven
positive TestEngineSourceNeverSetsTheCriticalField unit/verify unproven

RFC7296-3.2-5

o Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. (§3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. zero bit on the wire from the encoded bytes; recipient skips as PayloadRaw; set bit refused

PolarityTestKind and tierProof state
negative TestCritSenderZeroBitRequestsSkip unit/verify unproven
positive TestCritSenderZeroBitRequestsSkip unit/verify unproven

RFC7296-3.2-6

Critical (1 bit) - MUST be set to zero if the sender wants the recipient to skip this payload if it does not understand the payload type code in the Next Payload field of the previous payload. MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type. (§3.2)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge; row widened to the Critical item head, kept clause 'MUST be set to one if the sender wants the recipient to reject this entire message if it does not understand the payload type' (RFC 7296 3.2). TestCritSenderOneBitRequestsWholeMessageRejection asserts the encoded bit is 0x80 when the sender chose rejection and that ReadFrom then rejects the whole message (ErrUnsupportedCrit, zero payloads, the payload type named); the negative asserts the bit is clear and the message accepted when the sender did not choose it. The obligation is met at the wire encoder; no engine path wants a rejection (RFC7296-3.2-4). No discrimination record.

PolarityTestKind and tierProof state
negative TestCritSenderOneBitRequestsWholeMessageRejection unit/verify unproven
positive TestCritSenderOneBitRequestsWholeMessageRejection unit/verify unproven

RFC7296-3.3-3

An SA payload MAY contain multiple proposals. If there is more than one, they MUST be ordered from most preferred to least preferred (§3.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestProposalOrderPreserved unit/verify unproven
positive TestProposalOrderPreserved unit/verify unproven

RFC7296-3.3-4

When parsing an SA, an implementation MUST check that the total Payload Length is consistent with the payload's internal lengths and counts (§3.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSAInternalLengthConsistency unit/verify unproven
positive TestSAInternalLengthConsistency unit/verify unproven

RFC7296-3.3-5

Each structure MUST have a proposal number one (1) greater than the previous structure. The first Proposal in the initiator's SA payload MUST have a Proposal Num of one (1) (§3.3, §3.3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropProposalNumbering unit/verify unproven
positive TestPropProposalNumbering unit/verify unproven

RFC7296-3.3-6

A transform MUST NOT have multiple attributes of the same type (§3.3)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropDuplicateAttributeRejected unit/verify unproven
positive TestPropDuplicateAttributeRejected unit/verify unproven

RFC7296-3.3-7

To propose alternate values for an attribute (for example, multiple key sizes for the AES encryption algorithm), an implementation MUST include multiple transforms with the same Transform Type each with a single Attribute. (§3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Proposer side now proven: the IKE and ESP offers ze builds (buildWireIKEProposals, buildWireESPProposals) for AES-CBC/GCM at 128 and 256, encoded and decoded off the wire, carry both key lengths, every ENCR transform with exactly one Key Length attribute; packing two key lengths into one transform fails it. Ze places each alternate ENCR transform in its own proposal, which meets the clause: multiple ENCR transforms, each with a single attribute. Receive side (TestPropAlternateKeyLengthsUseSeparateTransforms) refuses one transform with two key lengths: the genuine receiving-side negative (R1a).

PolarityTestKind and tierProof state
negative TestPropAlternateKeyLengthsUseSeparateTransforms unit/verify revert, verified
positive TestRFC7296AlternateKeyLengthsAreOfferedAsSeparateTransforms unit/verify revert, verified
positive TestPropAlternateKeyLengthsUseSeparateTransforms unit/verify revert, verified

RFC7296-3.3.1-1

When a proposal is accepted, the proposal number in the SA payload MUST match the number on the proposal sent that was accepted (§3.3.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropAcceptedProposalNumberMatchesOffer unit/verify unproven
positive TestPropAcceptedProposalNumberMatchesOffer unit/verify unproven

RFC7296-3.3.1-2

o SPI Size (1 octet) - For an initial IKE SA negotiation, this field MUST be zero; the SPI is obtained from the outer header. (§3.3.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Ze's IKE_SA_INIT proposals carry SPI Size 0; responder kills an initial request with SPI Size 8 and answers nothing

PolarityTestKind and tierProof state
negative TestSpzInitialIKESANegotiationNeedsZeroSPISize unit/verify unproven
negative TestPropSPISizeMatchesProtocol unit/verify unproven
positive TestSpzInitialIKESANegotiationNeedsZeroSPISize unit/verify unproven
positive TestPropSPISizeMatchesProtocol unit/verify unproven

RFC7296-3.3.3-1

A compliant implementation MUST understand all mandatory and optional types for each protocol it supports (§3.3.3)

Audit verdict: enforced (the tests do what the requirement demands), fresh. transformTypeUnderstood per protocol matches the Section 3.3.3 table; engine refuses ESN in an IKE proposal. Re-judged 2026-09-30 (leftovers): TestTftUnknownTransformTypeMakesProposalUnacceptable changed only by the two added RFC7296-3.3.2-1 tag lines; body identical to HEAD, judge ran it: PASS; verdict unchanged.

PolarityTestKind and tierProof state
negative TestPropTransformTypesUnderstoodPerProtocol unit/verify unproven
negative TestTftUnknownTransformTypeMakesProposalUnacceptable unit/verify unproven
positive TestPropTransformTypesUnderstoodPerProtocol unit/verify unproven
positive TestTftUnknownTransformTypeMakesProposalUnacceptable unit/verify unproven

RFC7296-3.3.4-2

Upon receipt of a payload with a set of Transform IDs, the implementation MUST compare the transmitted Transform IDs against those locally configured via the management controls, to verify that the proposed suite is acceptable based on local policy (§3.3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropTransformIDsComparedAgainstLocalPolicy unit/verify unproven
positive TestPropTransformIDsComparedAgainstLocalPolicy unit/verify unproven

RFC7296-3.3.4-3

The implementation MUST reject SA proposals that are not authorized by these IKE suite controls (§3.3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropUnauthorizedProposalRejected unit/verify unproven
positive TestPropUnauthorizedProposalRejected unit/verify unproven

RFC7296-3.3.5-1

Attributes described as fixed length MUST NOT be encoded using the variable-length encoding unless that length exceeds two bytes (§3.3.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropFixedLengthAttributeRejectsTLVEncoding unit/verify unproven
positive TestPropFixedLengthAttributeRejectsTLVEncoding unit/verify unproven

RFC7296-3.3.5-2

Variable-length attributes MUST NOT be encoded as fixed-length even if their value can fit into two octets (§3.3.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropVariableLengthAttributeRejectsTVEncoding unit/verify unproven
positive TestPropVariableLengthAttributeRejectsTVEncoding unit/verify unproven

RFC7296-3.3.5-3

The Key Length attribute specifies the key length in bits (MUST use network byte order) (§3.3.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. 256 encodes 01 00; swapped octets read as 1

PolarityTestKind and tierProof state
negative TestPropKeyLengthUsesNetworkByteOrder unit/verify unproven
positive TestPropKeyLengthUsesNetworkByteOrder unit/verify unproven

RFC7296-3.3.5-4

The Key Length attribute MUST NOT be used with transforms that use a fixed-length key (§3.3.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropKeyLengthRejectedOnFixedKeyTransform unit/verify unproven
positive TestPropKeyLengthRejectedOnFixedKeyTransform unit/verify unproven

RFC7296-3.3.5-5

o Some transforms specify that the Key Length attribute MUST be always included (omitting the attribute is not allowed, and proposals not containing it MUST be rejected). (§3.3.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Whole row proven. Sender clause (MUST be always included): new TestRFC7296OffersAlwaysCarryTheRequiredKeyLength builds the IKE offer (buildWireIKEProposals) and the ESP offer (espProposalToWire) for all 10 configurable AES ciphers (CBC, GCM, CCM 8/12/16 at 128/256) and asserts exactly one Key Length attribute equal to the configured size; an omitted, duplicated or wrong attribute is red (single-polarity by nature: a builder has no violating input). Receiver clause (proposals not containing it MUST be rejected): crypto TestPropKeyLengthRequiredTransformRejectedWithoutIt, AES-CBC/CTR offers without the attribute refused with ErrKeyLengthMissing and accepted with it. Ze builds no AES-CTR offer. Records: encAttrs revert observed red on the sender unit; the crypto receiver tags carry no record.

PolarityTestKind and tierProof state
negative TestPropKeyLengthRequiredTransformRejectedWithoutIt unit/verify revert, verified
positive TestPropKeyLengthRequiredTransformRejectedWithoutIt unit/verify revert, verified
positive TestRFC7296OffersAlwaysCarryTheRequiredKeyLength unit/verify revert, verified

RFC7296-3.3.6-4

If the responder receives a proposal that contains a Transform Type it does not understand, or a proposal that is missing a mandatory Transform Type, it MUST consider this proposal unacceptable; however, other proposals in the same SA payload are processed as usual (§3.3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropProposalMissingMandatoryTransformTypeUnacceptable unit/verify unproven
negative TestTftForeignTransformTypeRefusedInESPOffer unit/verify unproven
negative TestTftUnknownTransformTypeMakesProposalUnacceptable unit/verify unproven
positive TestPropProposalMissingMandatoryTransformTypeUnacceptable unit/verify unproven
positive TestTftForeignTransformTypeRefusedInESPOffer unit/verify unproven
positive TestTftUnknownTransformTypeMakesProposalUnacceptable unit/verify unproven

RFC7296-3.3.6-5

Similarly, if the responder receives a transform that it does not understand, or one that contains a Transform Attribute it does not understand, it MUST consider this transform unacceptable; other transforms with the same Transform Type are processed as usual. (§3.3.6)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Judged 2026-09-30 at the producers after the D-8 fix: wire Transform.AttrsUnderstood (attrFormats, Key Length only); appendIKECombinations and espProposalMatches drop a transform carrying an unknown attribute and keep its siblings, and refuse the proposal only when an offered type loses every transform (IKEProposal.UnacceptableTransformType -> ErrTransformUnacceptable in ikeProposalComplete; ESP offered!=usable). This matches Section 3.3.6: the transform is unacceptable, other transforms of the same type are processed as usual, and a type with nothing acceptable leaves no complete set to select. Negative TestRFC7296UnacceptableTransformAloneRefusesTheProposal: unknown ENCR id alone, and each IKE type (ENCR/PRF/INTEG/D-H) and ESP type (ENCR/INTEG/ESN) carrying attribute 99 alone is refused, with a per-type control without the attribute accepted, so the attribute is the only difference (isolated); this failed before the fix. Positive TestRFC7296UnacceptableTransformLeavesSiblingsOnOffer: the unknown-id and unknown-attribute transform beside an understood sibling, both orders, IKE accepted with the sibling's ENCR and ESP matched (catches an over-reaction that refuses the type or proposal). ESP response is built from config, so no unacceptable attribute is echoed. HEAD crypto/engine tags remain supplementary. Records: appendIKECombinations +, espProposalMatches -, observed red.

PolarityTestKind and tierProof state
negative TestPropUnknownTransformIDMakesTransformUnacceptable unit/verify revert, verified
negative TestAltUnusableAlternativesAreStillRefused unit/verify revert, verified
negative TestRFC7296UnacceptableTransformAloneRefusesTheProposal unit/verify revert, verified
positive TestPropUnknownTransformIDMakesTransformUnacceptable unit/verify revert, verified
positive TestAltDHAlternativesAreBothOffered unit/verify revert, verified
positive TestRFC7296UnacceptableTransformLeavesSiblingsOnOffer unit/verify revert, verified

RFC7296-3.3.6-7

Any attributes of a selected transform MUST be returned unmodified (§3.3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropSelectedTransformAttributesUnmodified unit/verify unproven
positive TestPropSelectedTransformAttributesUnmodified unit/verify unproven

RFC7296-3.9-1

The size of the Nonce Data MUST be between 16 and 256 octets, inclusive (§3.9)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestNonceLengthBounds unit/verify unproven
positive TestNonceLengthBounds unit/verify unproven

RFC7296-3.10-3

For a notification concerning the IKE SA, the SPI Size MUST be zero and the field must be empty. (§3.10)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Producer side now proven: every notify of the IKE_SA_INIT request ze builds and the UNSUPPORTED_CRITICAL_PAYLOAD error answer ze sends, decoded off the wire, carry SPI Size 0 and no SPI octets (error data exactly one octet). Negative (R1b): an IKE-SA notify struct naming Protocol ID 1 and SPI Size 8 with no SPI octets is still encoded with SPI Size 0 and an empty SPI field. Engine notify producers read: only REKEY_SA (a Child SA notify, rekey.go) sets an SPI. INITIAL_CONTACT is not driven end to end; it uses the same WriteTo. Wire TestNotifyIKESAHasEmptySPI kept.

PolarityTestKind and tierProof state
negative TestRFC7296IKESANotifyWithAnSPISizeButNoSPIIsSentEmpty unit/verify revert, verified
negative TestNotifyIKESAHasEmptySPI unit/verify revert, verified
positive TestRFC7296IKESANotifiesZeSendsCarryNoSPI unit/verify revert, verified
positive TestNotifyIKESAHasEmptySPI unit/verify revert, verified

RFC7296-3.10-4

For notifications concerning Child SAs, this field MUST contain either (2) to indicate AH or (3) to indicate ESP. (§3.10)

Audit verdict: enforced (the tests do what the requirement demands), fresh. SPI-bearing notify with AH/ESP round-trips; Protocol ID 0,1,4,255 beside an SPI refused with ErrNotifyProtocolID

PolarityTestKind and tierProof state
negative TestNtfyChildSAProtocolIDIsAHOrESP unit/verify unproven
positive TestNtfyChildSAProtocolIDIsAHOrESP unit/verify unproven

RFC7296-3.10-5

If the SPI field is empty, this field MUST be sent as zero and MUST be ignored on receipt. (§3.10)

Audit verdict: enforced (the tests do what the requirement demands), fresh. WriteTo zeroes Protocol ID for an empty SPI; ReadFrom discards it; kept when an SPI is present

PolarityTestKind and tierProof state
negative TestNtfyEmptySPIProtocolIDIgnoredOnReceipt unit/verify unproven
negative TestNtfyEmptySPISendsProtocolIDZero unit/verify unproven
positive TestNtfyEmptySPIProtocolIDIgnoredOnReceipt unit/verify unproven
positive TestNtfyEmptySPISendsProtocolIDZero unit/verify unproven

RFC7296-3.11-1

each SPI MUST be for the same protocol. Mixing of protocol identifiers MUST NOT be performed in the Delete payload. (§3.11)

Audit verdict: enforced (the tests do what the requirement demands), fresh. PayloadDelete holds one ProtocolID by construction; two protocols need two payloads

PolarityTestKind and tierProof state
negative TestDeletePayloadSingleProtocol unit/verify unproven
positive TestDeletePayloadSingleProtocol unit/verify unproven

RFC7296-3.11-2

SPI Size (1 octet) - Length in octets of the SPI as defined by the protocol ID. It MUST be zero for IKE (SPI is in message header) or four for AH and ESP. (§3.11)

Audit verdict: enforced (the tests do what the requirement demands), fresh. TestRFC7296DeleteWrongSPISizeForItsProtocolIsRefused drives IKE size 4, AH 0 and 8, ESP 0 through handleInformationalOwned: exactly one INVALID_SYNTAX, no Delete, no SA removed, no reestablish. Each case reddens under the break of its own deleteMalformed arm. TestRFC7296DeleteSPISizeFixedForItsProtocolIsAccepted: IKE 0 and AH 4 draw no notify, so the refusal is per-protocol size and not a refusal of IKE/AH Deletes. The older ESP-size-3 units and the wire units carry no discrimination record; the wire negative (truncation) proves a neighbouring rule.

PolarityTestKind and tierProof state
negative TestRFC7296DeleteWrongSPISizeForItsProtocolIsRefused unit/verify revert, verified
negative TestDelMalformedSPISizeDrawsInvalidSyntax unit/verify revert, verified
negative TestDeleteSPISizeByProtocol unit/verify revert, verified
positive TestRFC7296DeleteSPISizeFixedForItsProtocolIsAccepted unit/verify revert, verified
positive TestDelWellFormedSPISizeIsAccepted unit/verify revert, verified
positive TestDeleteSPISizeByProtocol unit/verify revert, verified

RFC7296-3.12-2

Unfamiliar Vendor IDs MUST be ignored (§3.12)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestVendorIDIgnoredButPreserved unit/verify unproven
positive TestVendorIDIgnoredButPreserved unit/verify unproven

RFC7296-3.12-3

Writers of documents who wish to extend this protocol MUST define a Vendor ID payload to announce the ability to implement the extension in the document (§3.12)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestVendorIDIgnoredButPreserved unit/verify unproven
positive TestVendorIDIgnoredButPreserved unit/verify unproven

RFC7296-3.12-4

A Vendor ID payload MUST NOT change the interpretation of any information defined in this specification (i.e., the critical bit MUST be set to 0) (§3.12)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestVendorIDDoesNotChangeInterpretation unit/verify unproven
positive TestVendorIDDoesNotChangeInterpretation unit/verify unproven

RFC7296-3.14-2

Senders MUST select a new unpredictable IV for every message (§3.14)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSKSelectsFreshIVPerMessage unit/verify unproven
positive TestSKSelectsFreshIVPerMessage unit/verify unproven

RFC7296-3.14-3

Initialization Vector - For CBC mode ciphers, the length of the initialization vector (IV) is equal to the block length of the underlying encryption algorithm. Senders MUST select a new unpredictable IV for every message; recipients MUST accept any value. (§3.14)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after the fix round (2691e815b1); only the positive's claim comment changed. RFC 7296 3.14: "Senders MUST select a new unpredictable IV for every message; recipients MUST accept any value." This row's tests carry the recipient clause (the sender clause is RFC7296-3.14-2). TestSKAcceptsAnyIVOnReceipt now claims the three IVs it sends (all-zero, all-ones, ascending) and decrypts each to the exact single Delete payload through decryptAndParse; its claim points the repeated IV to TestRFC7296RecipientAcceptsAnIVTheSenderShouldNotHaveChosen, which decrypts a repeated IV and the previous final ciphertext block used as IV, the inputs a policing recipient would refuse. Claim and body now agree; the earlier defect is resolved. Revert records on auth.go::decryptSKPayload for both units.

PolarityTestKind and tierProof state
negative TestRFC7296RecipientAcceptsAnIVTheSenderShouldNotHaveChosen unit/verify revert, verified
positive TestSKAcceptsAnyIVOnReceipt unit/verify revert, verified

RFC7296-3.14-4

Padding MAY contain any value chosen by the sender, and MUST have a length that makes the combination of the payloads, the Padding, and the Pad Length to be a multiple of the encryption block size (§3.14)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestSKPaddingAlignsAndChecksumCoversCiphertext unit/verify unproven
positive TestSKPaddingAlignsAndChecksumCoversCiphertext unit/verify unproven

RFC7296-3.14-5

the recipient MUST accept any length that results in proper alignment (§3.14)

Audit verdict: enforced (the tests do what the requirement demands), fresh. minimum pad and +16/+32 accepted; over-long Pad Length refused with a valid MAC

PolarityTestKind and tierProof state
negative TestSKAcceptsAnyAligningPadLength unit/verify unproven
positive TestSKAcceptsAnyAligningPadLength unit/verify unproven

RFC7296-3.14-6

The checksum MUST be computed over the encrypted message (§3.14)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge because the unit TestSKAcceptsAnyIVOnReceipt moved; the move is a claim comment for RFC7296-3.14-3 only, and its RFC7296-3.14-6 negative claim and body are unchanged. RFC 7296 3.14: "The checksum MUST be computed over the encrypted message." The proof rests on the dedicated pair: TestRFC7296ChecksumIsTheHMACOfTheEncryptedMessage recomputes HMAC-SHA2-256-128 under SK_ai outside Ze over header, SK header, IV and ciphertext and requires Ze's ICV to equal it, and TestRFC7296ChecksumOverThePlaintextIsRefused refuses an ICV computed over the plaintext while the same construction over the ciphertext is accepted. TestSKAcceptsAnyIVOnReceipt's negative (a flipped final ICV octet refused) and TestSKPaddingAlignsAndChecksumCoversCiphertext add integrity-refusal floors only; a plaintext-MAC implementation would also refuse a flipped octet, so those units alone would not discriminate the scope, but the pair above does.

PolarityTestKind and tierProof state
negative TestRFC7296ChecksumOverThePlaintextIsRefused unit/verify revert, verified
negative TestSKAcceptsAnyIVOnReceipt unit/verify revert, verified
negative TestSKPaddingAlignsAndChecksumCoversCiphertext unit/verify revert, verified
positive TestRFC7296ChecksumIsTheHMACOfTheEncryptedMessage unit/verify revert, verified
positive TestSKPaddingAlignsAndChecksumCoversCiphertext unit/verify revert, verified

RFC7296-3.14-7

Peers MUST NOT negotiate transforms for which no such specification exists (§3.14)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestPropUnspecifiedTransformRefused unit/verify unproven
positive TestPropUnspecifiedTransformRefused unit/verify unproven

RFC7296-5-2

Though the security of negotiated Child SAs does not depend on the strength of the encryption and integrity protection negotiated in the IKE SA, implementations MUST NOT negotiate NONE as the IKE integrity protection algorithm or ENCR_NULL as the IKE encryption algorithm. (§5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30. RFC 7296 Section 5: 'implementations MUST NOT negotiate NONE as the IKE integrity protection algorithm or ENCR_NULL as the IKE encryption algorithm.' The earlier residual is closed: the negative in TestRFC7296NegotiationRefusesNullIntegrityAndNullCipher now asserts errors.Is ErrProposalIncomplete for AUTH_NONE beside AES-CBC and ErrTransformUnspecified for ENCR_NULL, on both NegotiateIKE (responder) and VerifyAcceptedIKE (initiator), with policy holding the identical proposal; its positive accepts AES-CBC/HMAC-SHA2-256-128 on both. TestIKENeverNegotiatesNullAlgorithms keeps only its positive tag (the lookups refuse none/null, so ze cannot build a null proposal); its trailing block is now labelled a control, which it is. Three records observed red. Judge's own probe: removing the AUTH_NONE clause of ikeProposalComplete via go test -overlay reddens the negative on both sides.

PolarityTestKind and tierProof state
negative TestRFC7296NegotiationRefusesNullIntegrityAndNullCipher unit/verify revert, verified
positive TestRFC7296NegotiationRefusesNullIntegrityAndNullCipher unit/verify revert, verified
positive TestIKENeverNegotiatesNullAlgorithms unit/verify revert, verified

RFC7296-5-3

For this reason, a PRF whose output is less than 128 bits (e.g., 3DES-CBC) MUST NOT be used with this protocol. (§5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. NegotiateIKE refuses a registered 64-bit PRF; prfOutputAcceptable floor at 128; every specified PRF at or above it

PolarityTestKind and tierProof state
negative TestPrfFloorRefusesOutputBelow128Bits unit/verify unproven
negative TestPropPRFOutputBelow128BitsRefused unit/verify unproven
positive TestPrfFloorRefusesOutputBelow128Bits unit/verify unproven
positive TestPropPRFOutputBelow128BitsRefused unit/verify unproven

RFC7296-2.19-1

Since the IKE_AUTH exchange creates an IKE SA and a Child SA, the IRAC MUST request the IRAS-controlled address (and optionally other information concerning the protected network) in the IKE_AUTH exchange (§2.19, §4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestZeSendsNoConfigurationRequest unit/verify unproven
positive TestZeSendsNoConfigurationRequest unit/verify unproven

RFC7296-2.19-4

CP(CFG_REQUEST) MUST contain at least an INTERNAL_ADDRESS attribute (either IPv4 or IPv6) but MAY contain any number of additional attributes the initiator wants returned in the response (§2.19)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestZeSendsNoConfigurationRequest unit/verify unproven
positive TestZeSendsNoConfigurationRequest unit/verify unproven

RFC7296-2.20-1

An IKE implementation MAY decline to give out version information prior to authentication or even after authentication in case some implementation is known to have some security weakness. In that case, it MUST either return an empty string or no CP payload if CP is not supported. (§2.20)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Section 2.20's method: TestRFC7296InformationalVersionRequestDrawsNoCP sends the product INFORMATIONAL handler (handleInformationalOwned, MOBIKE enabled so mobikeResponsePayloads builds the answer) a post-auth CP(CFG_REQUEST, empty APPLICATION_VERSION) and asserts the response the peer decrypts carries no CP; TestRFC7296InformationalVersionRequestReflectsNoVersionString pushes toward reflection with a non-empty version string and asserts no CP and no non-empty APPLICATION_VERSION. IKE_AUTH path: TestRFC7296ResponderAnswersAVersionRequestWithNoCP. Sweep: TestZeDeclinesApplicationVersion. Ze supports no CP, so the no-CP arm is the one that binds.

PolarityTestKind and tierProof state
negative TestZeDeclinesApplicationVersion unit/verify revert, verified
negative TestRFC7296InformationalVersionRequestReflectsNoVersionString unit/verify revert, verified
positive TestZeDeclinesApplicationVersion unit/verify revert, verified
positive TestRFC7296InformationalVersionRequestDrawsNoCP unit/verify revert, verified
positive TestRFC7296ResponderAnswersAVersionRequestWithNoCP unit/verify revert, verified

RFC7296-3.15.1-2

An empty INTERNAL_IP4_NETMASK attribute can be included in a CFG_REQUEST to request this information (although the gateway can send the information even when not requested). Non-empty values for this attribute in a CFG_REQUEST do not make sense and thus MUST NOT be included. (§3.15.1)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-01 under owner ruling 5 (ruling 2 reading). Ze sends no CFG_REQUEST: no production code constructs a wire.PayloadCP (only the parser does), and TestZeSendsNoConfigRequestNetmask sweeps every engine-built chain (IKE_SA_INIT, IKE_AUTH, INFORMATIONAL, delete, IKE rekey; outer and decrypted inner, with a vacuity guard) and asserts no CP(CFG_REQUEST). Negative (handling of a peer's violation): a peer CFG_REQUEST with a non-empty 4-octet netmask is decrypted and parsed, not rejected, with the value preserved (RFC 7296 Section 2.5 tolerance). Both polarities hold observed-red revert records added 2026-09-30 (buildEncryptedMessageEx, decryptAndParse). The positive would miss a future CP builder only on an exchange the sweep does not drive.

PolarityTestKind and tierProof state
negative TestZeSendsNoConfigRequestNetmask unit/verify revert, verified
positive TestZeSendsNoConfigRequestNetmask unit/verify revert, verified

RFC7296-3.15.1-5

The responder MUST return a Configuration payload if it accepted any of the configuration data, and the Configuration payload MUST contain the attributes that the responder accepted with zero-length data (§3.15.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCFGSetIsIgnoredAndDrawsNoCFGACK unit/verify unproven
positive TestCFGSetIsIgnoredAndDrawsNoCFGACK unit/verify unproven

RFC7296-3.15.1-6

Those attributes that it did not accept MUST NOT be in the CFG_ACK Configuration payload (§3.15.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCFGSetIsIgnoredAndDrawsNoCFGACK unit/verify unproven
positive TestCFGSetIsIgnoredAndDrawsNoCFGACK unit/verify unproven

RFC7296-3.15.1-7

If no attributes were accepted, the responder MUST return either an empty CFG_ACK payload or a response message without a CFG_ACK payload (§3.15.1)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCFGSetIsIgnoredAndDrawsNoCFGACK unit/verify unproven
positive TestCFGSetIsIgnoredAndDrawsNoCFGACK unit/verify unproven

RFC7296-2.4-2

If there has only been outgoing traffic on all of the SAs associated with an IKE SA, it is essential to confirm liveness of the other endpoint to avoid black holes. If no cryptographically protected messages have been received on an IKE SA or any of its Child SAs recently, the system needs to perform a liveness check in order to prevent sending messages to a dead peer. (§2.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-18 (independent auditor, after 98975fb2d8; the earlier weak verdict recorded no tagged unit). Section 2.4: "If no cryptographically protected messages have been received on an IKE SA or any of its Child SAs recently, the system needs to perform a liveness check in order to prevent sending messages to a dead peer." Positive TestRFC7296LivenessCheckFollowsTheInterval arms the state newDPDState builds for a 30-second interval (the YANG default when no dead-peer-detection block is configured, ze-ipsec-conf.yang), asserts no probe at 29 s, one probe at 31 s that reaches the peer's socket, and the probe awaited; red if newDPDState arms nothing (recorded revert) or shouldSend ignores the interval. Negative TestRFC7296LivenessCheckWaitsForTheOutstandingProbe asserts shouldSend false at 61 s and 300 s and an unchanged Message ID while the probe is outstanding: that is the single-request rule of Sections 2.1 and 2.3, a neighbouring obligation, so the negative side of this row rests on the 29-second assertion in the positive. Seams: dpdArmedTick restates the two lines of maintainSA (established.go) rather than driving the owner loop, and lastSent is reset only by sendDPD, so ze probes every interval whether or not protected traffic arrived; that over-checks and does not violate this SHOULD.

PolarityTestKind and tierProof state
negative TestRFC7296LivenessCheckWaitsForTheOutstandingProbe unit/verify mutant, verified
positive TestRFC7296LivenessCheckFollowsTheInterval unit/verify revert, verified

RFC7296-2.4-3

Since IKE is designed to operate in spite of DoS attacks from the network, an endpoint MUST NOT conclude that the other endpoint has failed based on any routing information (e.g., ICMP messages) or IKE messages that arrive without cryptographic protection (e.g., Notify messages complaining about unknown SPIs). (§2.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-12 (independent auditor). SHIFTED by 6e063fb498 (tests: give ten assert-nothing tests a real assertion), whose hunks sit in untagged sibling tests and the import block. The tagged unit is byte-identical (gate-verified) and no helper it calls changed. Verdict stands. Re-judged 2026-09-30. Unprotected-message clause unchanged: TestRteUnownedEstablishedSATrustsNothing (cleartext Delete/CREATE_CHILD_SA refused, authenticated Delete still ends the SA) and the two responder IKE_SA_INIT units. Routing-information clause now asserted with real loopback ICMP (linux, unprivileged, ran and passed, not skipped): the IKE socket sets IP_RECVERR and the queued Port Unreachable is consumed by the transport's real error-queue path (records: panic in drainErrorQueue + and deliverQueuedError - observed red, so the ICMP path runs in each unit). Negative TestRFC7296ICMPFromThePeerWhileWaitingFailsNothing: a Port Unreachable from the peer's own address:port while a probe waits, plus a Fragmentation Needed routed into handleSizeRefusal (the engine's only ICMP consumer): SA stays Established, probe stays outstanding with no sa-failed answer, nothing reaches Refusals, later authenticated answer settles it. Positive TestRFC7296ICMPUnreachableDoesNotFailTheSA: after a queued Port Unreachable the SA's next request reaches the peer and the peer's authenticated answer settles the probe as fits. Limit: the assertion covers today's consumers (Refusals channel, handleSizeRefusal); a new ICMP consumer outside them would need its own test.

PolarityTestKind and tierProof state
negative TestRFC7296ICMPFromThePeerWhileWaitingFailsNothing unit/verify revert, verified
negative TestResponderKeepsOldSAOnUnauthenticatedInit unit/verify revert, verified
negative TestRteUnownedEstablishedSATrustsNothing unit/verify revert, verified
positive TestRFC7296ICMPUnreachableDoesNotFailTheSA unit/verify revert, verified
positive TestResponderAcceptsReinitAfterStaleSA unit/verify revert, verified
positive TestRteUnownedEstablishedSATrustsNothing unit/verify revert, verified

RFC7296-2.4-4

The INITIAL_CONTACT notification, if sent, MUST be in the first IKE_AUTH request or response, not as a separate exchange afterwards (§2.4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-12 (independent auditor). SHIFTED by 6e063fb498 (tests: give ten assert-nothing tests a real assertion), whose hunks sit in untagged sibling tests and the import block. The tagged unit is byte-identical (gate-verified) and no helper it calls changed. Verdict stands. Re-read 2026-09-27. Forbidden: INITIAL_CONTACT sent outside the first IKE_AUTH. TestInitiatorEmitsInitialContact fails if the responder did not parse it from the first IKE_AUTH; TestInitialContactAbsentFromRekey fails if an IKE rekey CREATE_CHILD_SA carries it. buildAuthRequest (auth.go) is the only producer of NotifyInitialContact, so no other exchange can carry it.

PolarityTestKind and tierProof state
negative TestInitialContactAbsentFromRekey unit/verify unproven
positive TestInitiatorEmitsInitialContact unit/verify unproven

RFC7296-3.4-2

This Diffie-Hellman Group Num MUST match a Diffie-Hellman group specified in a proposal in the SA payload that is sent in the same message (§3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResInitiatorRejectsKEGroupOutsideTheAcceptedOffer unit/verify unproven
negative TestKesaKEGroupNotOfferedIsRejected unit/verify unproven
positive TestKesaKEGroupOfferedIsAccepted unit/verify unproven

RFC7296-3.4-3

If none of the proposals in that SA payload specifies a Diffie-Hellman group, the KE payload MUST NOT be present (§3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestKesaKEWithoutDHProposalIsRejected unit/verify unproven
positive TestKesaAbsentKEIsAlwaysAllowed unit/verify unproven

RFC7296-3.3.6-8

If one of the proposals offered is for the Diffie-Hellman group of NONE, and the responder selects that Diffie-Hellman group, then it MUST ignore the initiator's KE payload and omit the KE payload from the response (§3.3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResIKESANeverSelectsDHGroupNone unit/verify unproven
positive TestResSelectedDHGroupNoneOmitsKEFromTheResponse unit/verify unproven

RFC7296-2.4-14

This notification MUST NOT be sent by an entity that may be replicated (§2.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResInitialContactNotSentByReplicableIdentity unit/verify unproven
positive TestResInitialContactSentByNonReplicableIdentity unit/verify unproven

RFC7296-2.8-8

When the lifetime of a Security Association expires, the Security Association MUST NOT be used (§2.8)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResExpiredSAIsNotUsed unit/verify unproven
positive TestResRekeyLeadLeavesRoomBeforeHardExpiry unit/verify unproven
positive TestResUnexpiredSAIsUsed unit/verify unproven

RFC7296-4-1

If the responder rejects the CREATE_CHILD_SA request with a NO_ADDITIONAL_SAS notification, the implementation MUST be capable of instead deleting the old SA and creating a new one (§4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestResOtherRekeyFailuresDoNotReestablish unit/verify unproven
positive TestResNoAdditionalSAsTriggersReestablish unit/verify unproven

RFC7296-2.15-3

It MUST also accept a hex encoding of the shared secret (§2.15)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestHexEncodingIsExplicitAndNeverGuessed unit/verify unproven
positive TestPSKAcceptsHexEncoding unit/verify unproven

RFC7296-3.3.4-4

All implementations of IKEv2 MUST include a management facility that enables a user or system administrator to specify the suites that are acceptable for use with IKE (§3.3.4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestIKESuitePolicyRejectsAnUnhonourableSuite unit/verify unproven
positive TestIKESuitePolicyIsOperatorSpecified unit/verify unproven

RFC7296-3.5-2

To assure maximum interoperability, implementations MUST be configurable to send at least one of ID_IPV4_ADDR, ID_FQDN, ID_RFC822_ADDR, or ID_KEY_ID (§3.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestLocalIDIsOperatorControlledNotDerived unit/verify unproven
positive TestLocalIDTypeFollowsConfiguredIdentity unit/verify unproven

RFC7296-3.5-3

To assure maximum interoperability, implementations MUST be configurable to send at least one of ID_IPV4_ADDR, ID_FQDN, ID_RFC822_ADDR, or ID_KEY_ID, and MUST be configurable to accept all of these four types. (§3.5)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-10-11 by an independent judge after the fix round (2691e815b1). RFC 7296 3.5: "implementations MUST be configurable to send at least one of ID_IPV4_ADDR, ID_FQDN, ID_RFC822_ADDR, or ID_KEY_ID, and MUST be configurable to accept all of these four types." The send clause is proven under RFC7296-3.5-2 (buildIDPayload tests); this row's tests carry the accept clause. Positive TestRemoteIDAcceptsEveryMandatoryType (unchanged) requires checkRemoteIdentity to accept all four types under a configured remote-id, each with an anti-vacuity refusal of a wrong value, so refusing any of the four or short-circuiting on an empty remote-id fails. Negative TestRemoteIDRefusesTypesItCannotCompare: its claim now names ID_DER_ASN1_GN only, which is exactly what the body sends, and requires the not-comparable branch ("cannot compare") rather than a value mismatch, so a checker that accepts every type turns red; the earlier defect (claim naming ID_DER_ASN1_DN, which RFC7296-4-4 requires accepted) is resolved. Revert record on remote_id.go::assertedIdentity.

PolarityTestKind and tierProof state
negative TestRemoteIDRefusesTypesItCannotCompare unit/verify revert, verified
positive TestRemoteIDAcceptsEveryMandatoryType unit/verify unproven

RFC7296-3.5-4

IPv6-capable implementations MUST additionally be configurable to accept ID_IPV6_ADDR (§3.5)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestIPv6IdentityLengthIsEnforced unit/verify unproven
positive TestRemoteIDAcceptsIPv6Identity unit/verify unproven

RFC7296-3.6-1

Implementations MUST be capable of being configured to send and accept up to four X.509 certificates in support of authentication (§3.6)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestCcnCertificateCountIsBoundedAndConfigurable unit/verify unproven
negative TestCcnCertificateCountReachesFourInBothDirections unit/verify unproven
negative TestCcnOverlongChainKillsTheSAOnBothRoles unit/verify unproven
negative ipsec-certificate-count-range.ci functional/verify unproven
positive TestCcnCertificateCountReachesFourInBothDirections unit/verify unproven

RFC7296-3.6-2

and also MUST be capable of being configured to send and accept the two Hash and URL formats (with HTTP URLs). (§3.6)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-judged 2026-09-30 (independent judge). Send half unchanged: TestChuBothHashAndURLFormatsAreConfigurable fails unless buildCertPayloads emits encodings 12 and 13 with the SHA-1 and URL. Accept half now asserted: rfc7296_hash_url_accept_test.go::TestRFC7296ReceivedHashAndURLFormatsAreAcceptedWhenConfigured, hash-and-url ON, receives encoding 12 (leaf DER) and encoding 13 (DER bundle leaf+intermediate) with http URLs on a loopback server; acceptedCertEncoding admits each, storeRemoteCerts fetches (server hit), matches the SHA-1, stores the leaf as the peer cert and the bundle's intermediate in the chain. Negative: TestChuHashAndURLIsOffByDefault drops encodings 12 and 13 and refuses a live, hash-matching fetch with the option off, and the ON control admits it. Revert record observed red on cert_payload.go::acceptedCertEncoding. Re-judge 2026-10-12 (independent auditor) after 6e7a370dba changed test/parse/ipsec-hash-and-url-accepted.ci: the only edit adds bgp router-id 203.0.113.253 to the peer block, because a YANG mandatory leaf is now refused when absent (RFC 7950 7.6.5). The vpn ipsec block, the hash-and-url/certificate-url/certificate-url-allow leaves, the der-asn1-dn remote-id and the expectations (exit 0, stdout 'configuration valid') are unchanged. The edit keeps the buffer isolated: without it validate would fail on the bgp mandatory leaf, a neighbouring rule, rather than on the IPsec surface under test. RFC 7296 text re-read at the cited section. Verdict unchanged.

PolarityTestKind and tierProof state
negative TestChuBothHashAndURLFormatsAreConfigurable unit/verify revert, verified
negative TestChuHashAndURLIsOffByDefault unit/verify revert, verified
positive TestChuBothHashAndURLFormatsAreConfigurable unit/verify revert, verified
positive TestRFC7296ReceivedHashAndURLFormatsAreAcceptedWhenConfigured unit/verify revert, verified
positive ipsec-hash-and-url-accepted.ci functional/verify revert, verified

RFC7296-3.6-3

Implementations MUST support the "http:" scheme for hash-and-URL lookup (§3.6, §1.7)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestChuHashURLLookupRefusesEverythingOutsideTheBound unit/verify unproven
negative TestChuHashURLLookupUsesHTTPAndVerifiesTheHash unit/verify unproven
positive TestChuHashURLLookupCacheIsContentAddressed unit/verify unproven
positive TestChuHashURLLookupUsesHTTPAndVerifiesTheHash unit/verify unproven

RFC7296-4-4

For an implementation to be called conforming to this specification, it MUST be possible to configure it to accept the following: o Public Key Infrastructure using X.509 (PKIX) Certificates containing and signed by RSA keys of size 1024 or 2048 bits, where the ID passed is any of ID_KEY_ID, ID_FQDN, ID_RFC822_ADDR, or ID_DER_ASN1_DN. o Shared key authentication where the ID passed is any of ID_KEY_ID, ID_FQDN, or ID_RFC822_ADDR. (§4)

Audit verdict: enforced (the tests do what the requirement demands), fresh. Re-read 2026-09-27. Forbidden: a configuration that cannot accept RSA-1024/2048 PKIX under ID_KEY_ID, ID_FQDN, ID_RFC822_ADDR, ID_DER_ASN1_DN, or PSK under ID_KEY_ID, ID_FQDN, ID_RFC822_ADDR. TestCfmConformanceConfigurationSetIsAcceptable fails if verifyRemoteAuth refuses RSA-1024+FQDN, RSA-2048+RFC822, RSA-2048+DN, RSA-2048+KEY_ID or PSK with each of the three; TestCfmConformanceSetDoesNotAcceptWhatItMustNot shows a mismatched identity is refused; the .ci tests show the DN remote-id commits and remote-id-type is a closed set. Every key size and every ID type is covered, not the full cross product. Re-judge 2026-10-12 (independent auditor) after 6e7a370dba changed test/parse/ipsec-hash-and-url-accepted.ci: the only edit adds bgp router-id 203.0.113.253 to the peer block, because a YANG mandatory leaf is now refused when absent (RFC 7950 7.6.5). The vpn ipsec block, the hash-and-url/certificate-url/certificate-url-allow leaves, the der-asn1-dn remote-id and the expectations (exit 0, stdout 'configuration valid') are unchanged. The edit keeps the buffer isolated: without it validate would fail on the bgp mandatory leaf, a neighbouring rule, rather than on the IPsec surface under test. RFC 7296 text re-read at the cited section. Verdict unchanged.

PolarityTestKind and tierProof state
negative TestCfmConformanceConfigurationSetIsAcceptable unit/verify unproven
negative TestCfmConformanceSetDoesNotAcceptWhatItMustNot unit/verify unproven
negative ipsec-remote-id-type-enum.ci functional/verify unproven
positive TestCfmConformanceConfigurationSetIsAcceptable unit/verify unproven
positive ipsec-hash-and-url-accepted.ci functional/verify unproven

RFC7296-4-5

Every implementation MUST be capable of doing four-message IKE_SA_INIT and IKE_AUTH exchanges establishing two SAs (one for IKE, one for ESP or AH) (§4)

Audit verdict: not audited: no reader has judged these tests

PolarityTestKind and tierProof state
negative TestFourmFirstPairEstablishesNeitherSA unit/verify unproven
positive TestResponderHandshakePSKEndToEnd unit/verify unproven

Extraction sign-off

FieldValue
Reviewer six /ze-implement agents, one per section range, spec-rfcgate-1b-rfc7296-pilot AC-5; merged and re-checked in the main thread; site 2.13:2 re-walked by the spec-rfc-verdict-fix-ike-eap crypto author
Signed off 2026-09-30
Register rfc2119
Source rfc/full/rfc7296.txt
Source fingerprint a6f1a101b818977b
Record rfc/extraction/rfc7296.json
Mapped sentences 230
Declined as scope 19
Relocated to a spec, which Ze OWES 12
Unclassified 0

Sections

SectionNameSitesDispositionReason
front not stated 0 skipped (front-matter) The abstract, the status of this memo, the copyright notice and the table of contents. No protocol obligation appears before Section 1.
1 not stated 1 walked The introduction names the exchange types and their order. Its one keyword site is the exchange-order sentence, mapped to RFC7296-1-1. The rest of the section describes what each exchange carries.
1.1 not stated 0 walked One paragraph introducing the four usage scenarios below it. It states no obligation.
1.1.1 not stated 0 walked A figure and one paragraph on the security gateway to security gateway tunnel. It describes a deployment, not protocol behavior.
1.1.2 The endpoint-to-endpoint transport mode scenario 0 walked The endpoint-to-endpoint transport mode scenario. Its only keyword is a MAY on application-layer access control, which gates nothing.
1.1.3 not stated 0 walked The endpoint to security gateway tunnel scenario, including why the initiator asks for an address through configuration payloads. It states no obligation.
1.1.4 not stated 0 walked One paragraph on nested combinations of the earlier scenarios. It states no obligation.
1.2 The initial exchanges 5 walked The initial exchanges. Five keyword sites map to rows RFC7296-1.2-2 through RFC7296-1.2-6. Row RFC7296-1.2-1 is read from two indicative sentences, that the initial exchanges are four messages and that every message after IKE_SA_INIT is cryptographically protected, and neither carries a keyword.
1.3 The CREATE_CHILD_SA exchange 3 walked The CREATE_CHILD_SA exchange. Two of its three keyword sites map to RFC7296-1.3-1 and RFC7296-1.3-2; the third restates the first. The NO_ADDITIONAL_SAS paragraph carries no keyword and no row.
1.3.1 Creating a new Child SA 2 walked Creating a new Child SA. Both keyword sites sit in the USE_TRANSPORT_MODE paragraph and map to RFC7296-1.3.1-1 and RFC7296-1.3.1-2. The TFC padding and non-first-fragment paragraphs carry no keyword.
1.3.2 Rekeying the IKE SA 1 walked Rekeying the IKE SA. Its one keyword site makes the KEi payload mandatory, and row RFC7296-1.3.3-1 holds that obligation under an id and a citation that name Section 1.3.3 instead.
1.3.3 Rekeying a Child SA 1 walked Rekeying a Child SA. Its one keyword site binds the REKEY_SA notification into a CREATE_CHILD_SA exchange that replaces an ESP or AH SA. No row stated that obligation when the walk began: it was extracted during the walk as RFC7296-1.3.3-2, which site 1.3.3:1 now maps to. Note that RFC7296-1.3.3-1 is a different row whose obligation sits in section 1.3.2; its anchor is a recorded Known Limitation and was deliberately left alone. Rows RFC7296-1.3.3-3 and RFC7296-1.3.3-4 are read from the two sentences that give the rekey request its SA, Ni, optional KEi, TSi and TSr payloads and the rekey response its TS payloads; neither carries a keyword (added 2026-09-29, the mistagged-unit fix of spec-rfc-verdict-fix-ike-eap).
1.4 The INFORMATIONAL exchange 4 walked The INFORMATIONAL exchange. Four keyword sites map to RFC7296-1.4-5, to RFC7296-1.4-3 twice, and to RFC7296-1.4-4.
1.4.1 Deleting an SA 6 walked Deleting an SA. Six keyword sites map to RFC7296-1.4.1-1 twice and to RFC7296-1.4.1-4 through RFC7296-1.4.1-7. Row RFC7296-1.4-1 is read from the sentence that the response carries Delete payloads for the paired SAs in the other direction, which carries no keyword; that row cites Section 1.4.
1.5 Informational messages outside an IKE SA 1 walked Informational messages outside an IKE SA. Its one keyword site bars an answer to the unprotected message and maps to RFC7296-1.5-1. The closing paragraphs that build the response carry no keyword, and row RFC7296-2.21.4-2 cites Section 2.21.4 first.
1.6 Requirements terminology 0 walked Requirements terminology. It points at [IPSECARCH] for the primitive terms and gives the RFC 2119 reading of the keywords. It states no protocol obligation.
1.7 The change list against RFC 4306 7 walked The change list against RFC 4306. Three sites carry obligations that live in Sections 2.5, 2.13 and 3.6, two are prose about the keywords themselves, one quotes the Section 1.3.2 change, and one states the configuration attribute type 5 rule that no row in rfc/short/rfc7296.md holds.
1.8 The change list against RFC 5996 0 walked The change list against RFC 5996. Every entry names a section that was added, clarified or corrected. It states no obligation.
2 IKE protocol details and variations 2 walked IKE protocol details and variations. Two keyword sites: the 1280-octet message size and the four zero octets that prefix an IKE message on port 4500.
2.1 Retransmission timers 7 walked Retransmission timers. Seven keyword sites map to rows RFC7296-2.1-3 through RFC7296-2.1-8. The half-open IKE SA paragraphs and the one-way message paragraph that follow carry no keyword and no row.
2.2 Message ID sequence numbers 2 walked Message ID sequence numbers. Two keyword sites map to RFC7296-2.2-1 and RFC7296-2.2-2. The counter paragraph carries no keyword and states an obligation the capitalised scan cannot see: each endpoint maintains two INDEPENDENT current Message IDs. It is recorded as RFC7296-2.2-3 in unsourced-ids. The original-initiator paragraph carries no keyword and states no obligation.
2.3 Window size for overlapping requests 9 walked Window size for overlapping requests. Six sites map to the Section 2.3 rows, two map to RFC7296-2.1-5 which cites Section 2.1 and Section 2.3, and one restates the window limit that site 2.3:4 maps.
2.4 not stated 8 walked Walked the whole section: state loss after a crash, INITIAL_CONTACT, liveness detection, retransmission, and Child SA deletion. The eight sites carry every capitalised obligation. The empty INFORMATIONAL liveness exchange is described in indicative prose with no keyword.
2.5 not stated 11 walked Walked the version number and forward compatibility rules, including the critical flag paragraph. Eleven sites carry the obligations. Two sentences each carry two obligations while deriving one site, so the second obligation of each has no site.
2.6 not stated 4 walked Walked the SPI text, the cookie exchange, the worked cookie construction, and the terminology note. Four sites carry the obligations. The identification of an IKE SA by the SPI pair is stated in indicative prose in the first paragraph.
2.6.1 not stated 1 walked Walked the interaction of COOKIE and INVALID_KE_PAYLOAD, including the three round trip diagram. The section states one obligation, in its closing sentence, and the site carries it.
2.7 not stated 5 walked Walked the algorithm negotiation rules. The five sites state one rule set that the summary captures in two rows, so three sites restate obligations those rows already carry.
2.8 not stated 4 walked Walked the rekeying section: lifetime expiry, rekey failure, IKE SA replacement, proactive rekey, and the window where the two ends disagree about an SA. Four sites carry the capitalised obligations. Independent lifetime policy is written as a difference from IKEv1 in indicative prose.
2.8.1 not stated 1 walked Walked the simultaneous Child SA rekeying rules and both packet loss traces. The site carries the accept-on-either-SA obligation. The lowest-of-four-nonces collision rule is written as a SHOULD in this section, so it derives no MUST-level site.
2.8.2 not stated 1 walked Walked the simultaneous IKE SA rekeying case, the TEMPORARY_FAILURE path, and the message trace. The site carries the one capitalised obligation, that the surviving IKE SA inherits the Child SAs.
2.8.3 not stated 0 walked Walked the comparison of IKE SA rekeying against reauthentication. The section states what each mechanism does and how reauthentication is built from the existing exchanges. It imposes no obligation and derives no site.
2.9 not stated 1 walked Walked the traffic selector negotiation text, including the four narrowing bullets and the SINGLE_PAIR_REQUIRED discussion. One bullet carries a capitalised MUST and is mapped. The TS_UNACCEPTABLE bullet and the narrowing-not-widening rule are written in indicative prose.
2.9.1 not stated 0 walked Walked the section on selectors that violate the initiator's own policy. It is a worked example of dropped traffic and closes with a general statement of the hazard. It imposes no obligation and derives no site.
2.9.2 not stated 2 walked Walked the rekeying selector rules. The two sites carry the two prohibitions, one binding the new SA and one binding the responder.
2.10 not stated 1 walked Walked the nonce section. One sentence carries three obligations and derives one site, so the two size floors have no site of their own.
2.11 not stated 2 walked Walked the address and port agility section, four sentences long. It derives two sites. The first sentence carries two obligations, so the second has no site of its own.
2.12 not stated 1 walked Walked the Diffie-Hellman exponential reuse section. Its one obligation is the forget-the-keys sentence, which the site carries. The reuse strategies are stated as choices that do not affect interoperability.
2.13 not stated 4 walked Walked the keying material section through the prf+ definition and its 255-iteration limit. The four sites carry the key size and key derivation obligations. The prf+ construction is stated as a definition.
2.14 not stated 1 walked The section derives SKEYSEED and the seven SK_ values with prf and prf+. Its one MUST-level sentence fixes the length of SK_d, SK_pi and SK_pr, and the summary carries that obligation as RFC7296-2.13-3, which cites both sections.
2.15 not stated 2 walked The section defines the signed octets and the pre-shared-key AUTH computation. Its three MUST-level obligations sit in one management-interface passage that the extractor cut into two sites, so the null-terminator half has no site of its own and is recorded unsourced.
2.16 not stated 8 walked Every MUST-level sentence of the EAP section derives a site, and the eight sites map one to one onto the eight requirement ids anchored to this section. The remaining text is the message diagram and SHOULD NOT or MAY guidance.
2.17 not stated 2 walked The section gives KEYMAT and three ordering bullets. Both MUST-level sites map to the two §2.17 rows, and the first bullet's ordering rule is already inside the text of RFC7296-2.17-1.
2.18 not stated 3 walked The section derives SKEYSEED for a rekeyed IKE SA and states two obligations: a new Diffie-Hellman exchange, and a message-counter reset. Both §2.18 rows are the target of a site.
2.19 not stated 6 walked Two of the six MUST-level sentences map to the two §2.19 rows the summary carries. The other four are the Configuration payload obligations that the 2026-07-31 owner ruling moved to plan/immediate/spec-ipsec-remote-access.md as RFC7296-2.19-2, -3, -5 and -6; those ids are not in rfc/short/rfc7296.md, so their sites stay unclassified.
2.20 not stated 1 walked The section shows the APPLICATION_VERSION exchange. Its one MUST states what a peer that declines to give version information returns, and RFC7296-2.20-1 carries it.
2.21 not stated 0 walked The section states the general error-handling rule in indicative prose and MAY constructions: a badly formatted or unacceptable request draws a Notify, and a bad response draws none. It derives no MUST-level site and no summary row cites §2.21.
2.21.1 not stated 0 walked IKE_SA_INIT error handling is written with 'should' throughout, because every notification at that point is unauthenticated. The section derives no site and no summary row cites §2.21.1.
2.21.2 not stated 3 walked Three MUST-level sentences and three rows: whole-message rejection, the initiator not failing authentication over a piggybacked error, and the limit on new error notifications defined by extension documents.
2.21.3 not stated 1 walked The section's one MUST requires a response for every errored request once the IKE SA is authenticated. The rest is SHOULD NOT guidance against starting new exchanges to report errors.
2.21.4 not stated 5 walked Five sites carry the out-of-SA rules for a message on port 500 or 4500 with no known IKE SA. Two of those sentences state two obligations each, so RFC7296-2.21.4-4 and -6 have no site of their own and are recorded unsourced. RFC7296-2.21.4-8, the SHOULD to send a protected Notify over an existing IKE SA after a suspicious message, is below the MUST-level scan, so it is recorded unsourced too.
2.22 not stated 2 walked Both MUST-level sentences are IPComp obligations: where an IPCOMP_SUPPORTED notification can appear, and what an implementation accepts and compresses with. The 2026-07-31 owner ruling moved the four §2.22 rows to plan/spec-ipsec-ipcomp.md, so no id exists in rfc/short/rfc7296.md and both sites stay unclassified.
2.23 not stated 10 walked Nine of the ten sites map to a summary row and one is the section's own applicability statement. RFC7296-2.23-3, the four zero octets prepended to a tunnelled IKE header, and RFC7296-2.23-12, the SPI rule that lets a receiver tell ESP from IKE on port 4500, are stated in indicative prose with no MUST-level keyword, so they are recorded unsourced. RFC7296-2.23-13, the SHOULD to adopt the address and port of an integrity-validated packet that arrives from a new endpoint, is below the MUST-level scan, so it is recorded unsourced too.
2.23.1 not stated 3 walked Read the transport mode NAT traversal scenario and the client and responder rule lists. Three MUST sites, all mapped; every other rule in the section is SHOULD or MAY.
2.24 not stated 1 walked Read the ECN section. Its one normative sentence carries two MUSTs and yields one site, so RFC7296-2.24-2 (the [IPSECARCH] encapsulation and decapsulation processing) has no site of its own.
2.25 not stated 1 walked Read the exchange collision section. The TEMPORARY_FAILURE retry ban is its only MUST; the TEMPORARY_FAILURE and CHILD_SA_NOT_FOUND sending rules are SHOULD.
2.25.1 not stated 0 walked Read the Child SA rekey and close collision rules. Every rule in the section is SHOULD, so the section holds no MUST-level site and no requirement row cites it.
2.25.2 not stated 0 walked Read the IKE SA rekey and close collision rules. Every rule in the section is SHOULD, so the section holds no MUST-level site and no requirement row cites it.
3 not stated 0 walked Read the section head. Its one normative sentence is a SHOULD NOT about items marked UNSPECIFIED, so the section holds no MUST-level site.
3.1 not stated 13 walked Read the IKE header section and every field description. Two rows share a source sentence with the row mapped from the same site: RFC7296-3.1-2 (no Encrypted payload inside an Encrypted payload) sits in site 3.1:1, and RFC7296-3.1-8 (ignore X bits on receipt) sits in site 3.1:9.
3.2 not stated 6 walked Read the generic payload header section, the payload type table and the Critical bit paragraph. All six sites map. Sites 3.2:1 and 3.2:2 state the sender obligations for the Critical bit; they were unextracted and are now carried by RFC7296-3.2-5 and RFC7296-3.2-6.
3.3 not stated 7 walked Read the Security Association payload section, its nesting rules and its proposal example. RFC7296-3.3-1 (combined-mode ciphers and normal ciphers go in separate proposals) is written with a lowercase must, so it has no capitalised site.
3.3.1 not stated 4 walked Read the proposal substructure and every field description. Four sites, all mapped, two of them to the RESERVED rows that cite this section.
3.3.2 not stated 1 walked Read the transform substructure, the Transform Type table and the Transform ID tables. RFC7296-3.3.2-1 (an IKE SA proposal carries ENCR, PRF, INTEG and D-H) is read from the Used In column of that table, which carries no keyword.
3.3.3 not stated 1 walked Read the valid Transform Types section and its mandatory and optional table. Its one MUST is mapped.
3.3.4 not stated 5 walked Read the mandatory Transform IDs section. Three MUSTs bind the implementation and are mapped; two sentences use the keyword to describe other documents' suite specifications and are excluded.
3.3.5 not stated 5 walked Read the transform attribute section, the attribute format figure and the Key Length rules. Five sites, all mapped; the interoperability note at the end is SHOULD.
3.3.6 not stated 8 walked Read the whole section: the responder selection rules, the handling of an unknown Transform Type or Transform Attribute, and the three Diffie-Hellman negotiation paragraphs. Section 3.3.6 treats Diffie-Hellman negotiation in indicative prose; the mandate that an IKE proposal carries a D-H transform is the mandatory Transform Type table of Section 3.3.3, which RFC7296-3.3.2-1 carries (RFC7296-3.3.6-1, a duplicate of that span, was retired 2026-09-29).
3.4 not stated 4 walked Read the Key Exchange payload section, the payload figure and the two paragraphs that follow it. All four sites map, and the INVALID_KE_PAYLOAD rejection maps to the row the summary anchors at Section 1.3.
3.5 not stated 5 walked Read the Identification payload section, the ID Type table and the interoperability paragraph. RFC7296-3.5-3 has no site of its own: one sentence carries the send obligation and the accept obligation together, and site 3.5:4 maps the send half.
3.6 not stated 3 walked Read the Certificate payload section, the Certificate Encoding table, the CertBundle ASN.1 module and the two closing paragraphs. RFC7296-3.6-2 has no site of its own: one sentence carries the four-certificate obligation and the Hash and URL obligation together, and site 3.6:1 maps the first half.
3.7 not stated 0 walked Read the Certificate Request payload section in full. It derives no site: its obligations are written at SHOULD and MAY level, such as CERTREQ payloads MAY be included and a certificate chain SHOULD be sent back to the requestor. The summary declares no requirement anchored at Section 3.7.
3.8 not stated 1 walked Read the Authentication payload section and the Auth Method table. Its one site is the RESERVED field rule, which restates the forward compatibility rule of Section 2.5. The only summary row anchored at Section 3.8 is a SHOULD and never gates.
3.9 not stated 2 walked Read the Nonce payload section. Both sites map: the 16 to 256 octet size range, and the ban on reusing a nonce value.
3.10 not stated 3 walked Read the Notify payload section and its field list. All three sites map to the Protocol ID and SPI Size rules that the field descriptions state.
3.10.1 not stated 4 walked Read the Notify Message Types section, including the error type table and the status type table. Three sites map to the error handling paragraph and the INVALID_SYNTAX entry, and the fourth repeats the ignore rule for status types.
3.11 not stated 3 walked Read the Delete payload section and its field list. Two sites carry the same one-protocol-per-payload rule, and the third carries the SPI Size rule.
3.12 not stated 3 walked Read the Vendor ID payload section. All three sites map: the critical bit rule, the ignore rule for an unfamiliar Vendor ID, and the obligation on writers of documents that extend the protocol.
3.13 not stated 1 walked Read the Traffic Selector payload section, its field list and the TSi/TSr matching example. Its one site is the RESERVED field rule of Section 2.5. The summary declares no requirement anchored at Section 3.13.
3.13.1 not stated 4 walked Read the Traffic Selector substructure section, the Start Port and End Port descriptions, and the ANY and OPAQUE paragraph. Three sites map and one restates the port encoding that the first two carry.
3.14 not stated 6 walked Read the Encrypted payload section, its field list, and the padding and checksum rules. RFC7296-3.14-3 has no site of its own: one sentence binds the sender to a new unpredictable IV and the recipient to accept any value, and site 3.14:3 maps the sender half.
3.15 Configuration payload header 1 walked Configuration payload header. The one site is the 3-octet RESERVED field; the rest of the section names payload type 47, lists the four CFG Type values and says the attribute list can be empty.
3.15.1 not stated 8 walked Configuration Attribute format, the attribute-type table, the per-attribute entries and the CFG_REQUEST/CFG_REPLY and CFG_SET/CFG_ACK paragraphs. Eight sites. Three of them state obligations rfc/short/rfc7296.md carries no row for, recorded on those sites.
3.15.2 not stated 0 walked The meaning of INTERNAL_IP4_SUBNET and INTERNAL_IP6_SUBNET, given as four worked CFG_REPLY examples. It says what a gateway conveys with the attribute and closes by saying the attribute cannot be used reliably in a CFG_REQUEST. No sentence obliges a speaker.
3.15.3 Configuration payloads for IPv6 0 walked Configuration payloads for IPv6. One worked exchange, the gateway's address-selection behavior at MAY level, and the limitation that an IKEv2 tunnel is not a full IPv6 interface. No obligation is stated.
3.15.4 Address assignment failures 0 walked Address assignment failures. The section states in indicative prose that a responder which cannot assign an address responds with INTERNAL_ADDRESS_FAILURE, and sends it only when no address can be assigned. That obligation carries no capitalised keyword and rfc/short/rfc7296.md declares no row for it, so unsourced-ids cannot name it. It needs a checklist row.
3.16 The EAP payload and the EAP message format 4 walked The EAP payload and the EAP message format. Four sites, one per field rule: Identifier, Length, Type presence and Type value. Each has its own row.
4 Conformance requirements 10 walked Conformance requirements. Ten sites: the section opener, the two payload-handling rules, the minimal-implementation paragraph, the three Configuration payload conditionals and the configurable-authentication list. RFC7296-3.2-3 is listed unsourced because Section 4 states it in the same sentence as site 4:2, which is mapped to RFC7296-2.5-8.
5 Security considerations 3 walked Security considerations. Three capitalised sites: the PRF output floor, the ban on NONE and ENCR_NULL inside the IKE SA, and public-key authentication of the server before EAP starts. The rest of the section is analysis and SHOULD-level advice.
5.1 Traffic selector authorization 0 walked Traffic selector authorization. It describes the Peer Authorization Database of [IPSECARCH] and reads an assigned inner address as a temporary PAD entry. The constraints it names belong to that document; the section states none of its own.
6 IANA considerations 0 skipped (iana) IANA considerations. It records that IANA registered the IKEv2 types and values in [IKEV2IANA], deprecated the Raw RSA Key certificate encoding and repointed the RFC 5996 references.
7 References heading 0 skipped (references) References heading.
7.1 Normative references 0 skipped (references) Normative references.
7.2 Informative references 0 skipped (references) Informative references.
A Summary of changes from IKEv1 0 skipped (appendix-non-normative) Summary of changes from IKEv1. Twelve numbered goals of the revision, written as a design record. It obliges no implementation.
B Diffie-Hellman groups 0 walked Diffie-Hellman groups. It defines two groups for use in IKE and says group 1 is kept for historic reasons. The prime and generator it carries are data, not a sentence that binds a speaker, so the section yields no site.
B.1 not stated 0 walked Group 1, 768-bit MODP: the assigned id, the prime and the generator 2. Constants only.
B.2 not stated 0 walked Group 2, 1024-bit MODP: the assigned id, the prime and the generator 2. Constants only.
C Exchanges and payloads 0 skipped (appendix-non-normative) Exchanges and payloads. The appendix says of itself that it is purely informative, and that the body of the document is correct wherever the two disagree.
C.1 not stated 0 skipped (appendix-non-normative) IKE_SA_INIT payload diagram: request, normal response, cookie response and the INVALID_KE_PAYLOAD response. Diagram only, under Appendix C's informative statement.
C.2 not stated 0 skipped (appendix-non-normative) IKE_AUTH without EAP: request, response and the Child SA error response. Diagram only, under Appendix C's informative statement.
C.3 not stated 0 skipped (appendix-non-normative) IKE_AUTH with EAP: first pair, the repeated EAP pair and the last pair. Diagram only, under Appendix C's informative statement.
C.4 not stated 0 skipped (appendix-non-normative) CREATE_CHILD_SA for creating or rekeying Child SAs, with the error and INVALID_KE_PAYLOAD responses. Diagram only, under Appendix C's informative statement.
C.5 not stated 0 skipped (appendix-non-normative) CREATE_CHILD_SA for rekeying the IKE SA, where KEi and KEr are mandatory. Diagram only, under Appendix C's informative statement.
C.6 not stated 0 skipped (appendix-non-normative) INFORMATIONAL exchange: notify, delete and Configuration payloads in request and response. Diagram only, under Appendix C's informative statement.

Excluded sentences

SiteExcluded kindReasonQuote
1.3:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The sentence restates the one before it from the side of the KEi: the group the initiator expects the responder to accept is the group set it proposes, which the parenthesis about additional groups confirms. Site 1.3:1 maps RFC7296-1.3-1. The Diffie-Hellman group of the KEi MUST be an element of the group the initiator expects the responder to accept (additional Diffie-Hellman groups can be proposed).
1.7:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The sentence reports what IKEv2 developers observed about RFC 4306. The keyword names a class of requirement in that earlier document and imposes nothing. They also have noted that there are MUST- level requirements that are not related to interoperability.
1.7:2 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The sentence sets how a reader interprets the lower-case words should and must in this document. It is a reading convention, and the keyword is the word being defined. All non-capitalized uses of the words SHOULD and MUST now mean their normal English sense, not the interoperability sense of [MUSTSHOULD].
1.7:3 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, ignore proposals carrying configuration attribute type 5, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-1.7-3 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-1.7-3) Implementations that conform to this document MUST ignore proposals that have configuration attribute type 5, the old value for INTERNAL_ADDRESS_EXPIRY.
1.7:5 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The sentence quotes the Section 1.3.2 change that turned the KEi payload from SHOULD to MUST. Site 1.3.2:1 maps RFC7296-1.3.3-1, which is that obligation. In Section 1.3.2, "The KEi payload SHOULD be included" was changed to be "The KEi payload MUST be included".
2.3:5 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The RFC opens this sentence with 'In other words' and restates the window limit as a wait for the responses up through request X-N. Site 2.3:4 maps RFC7296-2.3-4. In other words, if the responder stated its window size is N, then when the initiator needs to make a request X, it MUST wait until it has received responses to all requests up through request X-N.
2.7:1 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
This sentence introduces the negotiation rules that follow it, and each of those rules restates the single-suite obligation with its own site. RFC7296-2.7-1 carries it, mapped from the exactly-one-transform-per-type site. The responder MUST choose a single suite, which may be any subset of the SA proposal following the rules below.
2.7:3 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
Accepting one proposal or rejecting them all with an error is the second half of RFC7296-2.7-1, whose first half the exactly-one-transform-per-type site maps. The responder MUST accept a single proposal or reject them all and return an error.
2.7:5 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The sentence opens with 'For example' and applies the preceding rule to a named ESP proposal. It states no obligation the preceding sentence does not, and RFC7296-2.7-1 carries that obligation. For example: if an ESP proposal includes transforms ENCR_3DES, ENCR_AES w/keysize 128, ENCR_AES w/keysize 256, AUTH_HMAC_MD5, and AUTH_HMAC_SHA, the accepted suite MUST contain one of the ENCR_ transforms and one of the AUTH_ transforms.
2.13:2 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
The sentence binds the specification of a cryptographic transform: the transform's defining document must state how keys are derived from arbitrary values, and no implementation fills that role. Ze implements no transform the condition names either: encryptionRegistry (`internal/component/ike/crypto/transform.go`) holds AES CBC, GCM and CCM only, for which every value of the fixed size is a valid key. Row RFC7296-2.13-2 was retired on 2026-09-30. For algorithms for which not all values are valid keys (such as DES or 3DES with key parity), the algorithm by which keys are derived from arbitrary values MUST be specified by the cryptographic transform.
2.19:2 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, the CP payload's position in the responder's payload chain, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-2.19-2 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-2.19-2) Initiator Responder ------------------------------------------------------------------- HDR, SK {IDi, [CERT,] [CERTREQ,] [IDr,] AUTH, CP(CFG_REQUEST), SAi2, TSi, TSr} --> <-- HDR, SK {IDr, [CERT,] AUTH, CP(CFG_REPLY), SAr2, TSi, TSr} In all cases, the CP payload MUST be inserted before the SA payload.
2.19:3 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, never send an unsolicited CFG_REPLY, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-2.19-3 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-2.19-3) In variations of the protocol where there are multiple IKE_AUTH exchanges, the CP payloads MUST be inserted in the messages containing the SA payloads.
2.19:5 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, emit FAILED_CP_REQUIRED when a required CP is absent, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-2.19-5 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-2.19-5) The responder MUST NOT send a CFG_REPLY without having first received a CP(CFG_REQUEST) from the initiator, because we do not want the IRAS to perform an unnecessary configuration lookup if the IRAC cannot process the REPLY.
2.19:6 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, the SA state after a failed configuration exchange, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-2.19-6 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-2.19-6) In the case where the IRAS's configuration requires that CP be used for a given identity IDi, but IRAC has failed to send a CP(CFG_REQUEST), IRAS MUST fail the request, and terminate the Child SA creation with a FAILED_CP_REQUIRED error.
2.22:1 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, IPComp association negotiation, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-2.22-1 in plan/spec-ipsec-ipcomp.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/spec-ipsec-ipcomp.md as RFC7296-2.22-1) These payloads MUST NOT occur in messages that do not contain SA payloads.
2.22:2 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, IPComp CPI handling, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-2.22-2 in plan/spec-ipsec-ipcomp.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/spec-ipsec-ipcomp.md as RFC7296-2.22-2) Although there has been discussion of allowing multiple compression algorithms to be accepted and to have different compression algorithms available for the two directions of a Child SA, implementations of this specification MUST NOT accept an IPComp algorithm that was not proposed, MUST NOT accept more than one, and MUST NOT compress using an algorithm other than one proposed and accepted in the setup of the Child SA.
2.23:6 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
An applicability statement, not an obligation: it tells the reader that the MUSTs in the bullet list below bind only implementations that support NAT traversal, which the preceding sentence calls optional. In this section only, requirements listed as MUST apply only to implementations supporting NAT traversal.
3.1:5 binds-another-role
never bound Ze
the obligation is addressed to a role Ze never acts as
Presumed wrong until justified: Ze rarely implements one side of a protocol, so the reason beside this row must name the role, show Ze never acts as it, and cite the producer that would.
The sentence sets the major version for implementations of previous IKE versions and of ISAKMP. Ze implements IKEv2 only, so the obligation binds an IKEv1 or ISAKMP implementation. The producer that would act as it if ze did is the IKE header codec, which writes and reads the version octet: `MajorVersion` (`internal/component/ike/wire/header.go`) is encoded at byte 17 and ze sets it for IKEv2 alone, so no IKEv1 or ISAKMP exchange exists here to carry the obligation. Implementations based on previous versions of IKE and ISAKMP MUST set the major version to 1.
3.3.4:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The keywords name the suite specifications that were removed from this document. The sentence records an editorial change and binds no implementation. The specification of suites that MUST and SHOULD be supported for interoperability has been removed from this document because they are likely to change more rapidly than this document evolves.
3.3.4:5 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The sentence removes an expectation: a suite that another document makes mandatory to implement need not sit in local policy. The keyword names that other document's obligation, not one this sentence imposes. Note that cryptographic suites that MUST be implemented need not be configured as acceptable to local policy.
3.3.6:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The sentence narrows the same selection rule to the proposal level. Site 3.3.6:1 maps RFC7296-2.7-1, which already binds the responder to one proposal or a rejection of all of them. If there are multiple proposals, the responder MUST choose a single proposal.
3.3.6:3 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The sentence narrows the same selection rule to one transform per Transform Type. Section 2.7 states it as the accepted suite containing exactly one transform of each type, which RFC7296-2.7-1 captures. If the selected proposal has multiple transforms with the same type, the responder MUST choose a single one.
3.10.1:3 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The paragraph on status types repeats the ignore rule of the preceding paragraph. Site 3.10.1:2 maps RFC7296-3.10.1-2, whose text already covers an unrecognized status type in a request or a response. Notify payloads with status types MAY be added to any message and MUST be ignored if not recognized.
3.11:2 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
The mixing ban is the same obligation as the preceding sentence, written as a prohibition. Site 3.11:1 maps RFC7296-3.11-1, whose text carries both sentences. Mixing of protocol identifiers MUST NOT be performed in the Delete payload.
3.13.1:3 duplicate-of
never bound Ze
the same obligation is already captured under another requirement id
ANY ports means start port 0 and end port 65535, which is the port encoding the two field descriptions already state. Site 3.13.1:1 maps RFC7296-3.13.1-1 and site 3.13.1:2 maps RFC7296-3.13.1-2. Systems that are complying with [IPSECARCH] that wish to indicate "ANY" ports MUST set the start port to 0 and the end port to 65535; note that according to [IPSECARCH], "ANY" includes "OPAQUE".
3.15.1:2 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, at most one netmask, and only beside an INTERNAL_IP4_ADDRESS, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-3.15.1-1 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-3.15.1-1) Only one netmask is allowed in the request and response messages (e.g., 255.255.255.0), and it MUST be used only with an INTERNAL_IP4_ADDRESS attribute.
3.15.1:4 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, a SUPPORTED_ATTRIBUTES request carries zero length, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-3.15.1-3 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-3.15.1-3) o SUPPORTED_ATTRIBUTES - When used within a Request, this attribute MUST be zero-length and specifies a query to the responder to reply back with all of the attributes that it supports.
3.15.1:5 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, ignore attributes the responder does not recognize, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-3.15.1-4 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-3.15.1-4) Unrecognized or unsupported attributes MUST be ignored in both requests and responses.
4:1 not-a-requirement
never bound Ze
the sentence states a fact or describes another document, and directs no implementation
The opening sentence of Section 4, which describes what the section contains. Its capitalised words sit inside the quoted phrase "MUST support", naming the class of requirements that follow. It binds nobody. In order to assure that all implementations of IKEv2 can interoperate, there are "MUST support" requirements in addition to those listed elsewhere.
4:8 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, parse the CFG_REQUEST and recognize the address attribute, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-4-2 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-4-2) If an implementation supports responding to such requests, it MUST parse the CP payload of type CFG_REQUEST in the first message in the IKE_AUTH exchange and recognize a field of type INTERNAL_IP4_ADDRESS or INTERNAL_IP6_ADDRESS.
4:9 relocated-to-spec
Ze owes it
the obligation is real and unbuilt, and a named spec owes it
The obligation, return a CFG_REPLY carrying an address of the requested type, was moved out of rfc/short/rfc7296.md by owner ruling D-1 (2026-07-31) and is reserved as RFC7296-4-3 in plan/immediate/spec-ipsec-remote-access.md. It is gated at that destination, so nothing is dropped: this site records where the obligation went, and the tripwire reds if that spec or that id disappears. (relocated to plan/immediate/spec-ipsec-remote-access.md as RFC7296-4-3) If it supports leasing an address of the appropriate type, it MUST return a CP payload of type CFG_REPLY containing an address of the requested type.

Superseded

No document obsoletes RFC 7296, so its obligations are stated where they were written.