Nimble Out-of-Band Authentication for EAP (EAP-NOOB)
updated by
- rfc-9965 — The eap.arpa. Domain and Extensible Authentication Protocol (EAP) Provisioning
Extracted elements (29)
EAP-NOOB requires dynamically generated OOB messages rather than static printed codes because the receipt of the OOB message authorizes the server to take ownership of the device. Static codes could be leaked before deployment and reused to claim unauthorized ownership; dynamic messages prevent this.
EAP-NOOB requires multiple separate EAP conversations rather than one because the user-assisted OOB step can take arbitrarily long — far exceeding EAP's internal timeout tolerances. IoT devices with output-only interfaces (e.g., blinking LEDs) must perform the Initial Exchange opportunistically and wait with a several-minute NoobTimeout for the OOB step to occur.
Servers are RECOMMENDED to support both OOB directions (Dirs=3) for maximum flexibility, but peers are RECOMMENDED to select only one direction (Dirp=1 or 2) even when both are technically possible. Selecting both would present users with two OOB messages when only one needs to be delivered, causing confusion; the protocol resolves simultaneous delivery by prioritizing the server-to-peer direction.
When two OOB messages are simultaneously delivered in both directions (a rare but possible event due to poor UI design), the server detects this by observing both endpoints in OOB Received (2) state and MUST act as if only the server-to-peer message was delivered, using it as a tiebreaker to resolve the ambiguity.
A peer that has not received an OOB message SHOULD wait at least the server-specified SleepTime (seconds) before initiating EAP again with the same server. If the server has not sent any SleepTime, the peer MUST wait for the application-specified minimum SleepTimeDefault.
Both the server and peer MUST compute keys Kms and Kmp and the message authentication codes MACs and MACp in the Completion Exchange, and MUST compare the received MAC with a locally computed value. Mismatch MUST trigger error code 4001 and EAP-Failure.
Once the association enters Registered (4) state, the server MUST NOT delete the association or return to ephemeral states 0–2 without explicit user approval, and MUST NOT repeat the OOB Step with the same peer except after a user-initiated reset or persistent storage failure.
The 17-element JSON array inputs to Hoob and HMAC functions MUST be copied verbatim from sent/received in-band messages; JSON object members MUST NOT be reordered or reencoded, and white space MUST NOT be added. Nonces and MACs MUST be base64url encoded without padding when sent as JSON strings.
The server MUST determine the exchange type (Initial, Completion, Waiting, or Reconnect) based on the combination of peer and server states per Table 14. All other state combinations are error situations requiring user action, and the server SHOULD send error code 2002 to the peer.
The server MUST generate PeerIds such that they do not repeat and cannot be guessed by the peer or third parties before the server sends them. A recommended approach is to choose a random 16-byte value and base64url encode it without padding into a 22-character ASCII string.
The PeerId assigned by the server is a persistent identifier linkable across network connections, enabling tracking of the peer device. The PeerInfo field may include device-identifying attributes (brand, model, serial number) that further facilitate tracking. Applications should limit PeerInfo content to what is necessary for OOB delivery, and the generic NAI 'noob@eap-noob.arpa' reveals that a device is being bootstrapped.
Key derivation uses NIST C(2e,0s,ECC CDH) ECDHE followed by the NIST one-step KDF (SP 800-56Ar3 §5.8.2.1) with AlgorithmId='EAP-NOOB' (8-byte ASCII). KDF outputs (per Table 5): MSK (bytes 0–63), EMSK (64–127), AMSK (128–191), MethodId (192–223), MAC keys Kms/Kmp (224–287), and persistent key Kz (288–319, KeyingMode 0 and 3 only).
Peers initially use the reserved generic NAI 'noob@eap-noob.arpa' to signal EAP-NOOB support to the server and enable AAA routing. The server MAY assign a custom NAI via the NewNAI field in Initial or Reconnect Exchange requests (Type=2 and Type=7). NAI values MUST follow RFC 7542 utf8-username syntax.
The Completion Exchange uses one or two request-response pairs (optional Type=5 to discover NoobId, then mandatory Type=6) to exchange NoobId (identifying the specific OOB message) and mutual HMACs MACs and MACp. Successful MAC verification by both sides results in EAP-Success and transition to Registered (4) state.
The Initial Exchange comprises a common handshake plus two EAP-NOOB request-response pairs (Type=2 and Type=3). The server allocates a PeerId, negotiates protocol version and cryptosuite (Vers/Verp, Cryptosuites/Cryptosuitep), exchanges OOB direction indicators (Dirs/Dirp) and ServerInfo/PeerInfo, and performs an ECDHE key exchange (PKs, PKp) with 32-byte nonces (Ns, Np). The exchange always ends in EAP-Failure.
The OOB Step transfers a single unidirectional out-of-band message containing PeerId, the 16-byte secret nonce Noob, and the 16-byte cryptographic fingerprint Hoob. The OOB receiver MUST compare Hoob against a locally computed value; if equal, the receiver moves to OOB Received (2) state; otherwise the OOB message MUST be rejected.
The persistent EAP-NOOB association MUST store at minimum: PeerId, Verp, Cryptosuitep, NAI, and Kz (32-byte persistent key material). The peer additionally stores CryptosuitepPrev and KzPrev to enable cryptosuite upgrade rollback upon detection of a lost final response (Type=9) in a previous Reconnect Exchange.
The Reconnect Exchange provides fast reconnect without repeating the OOB Step, using three request-response pairs (Type=7 for cryptosuite negotiation, Type=8 for KeyingMode/nonces/optional ECDHE keys, Type=9 for mutual MACs2). The KeyingMode field (0=Completion, 1=reconnect no ECDHE, 2=reconnect with ECDHE same suite, 3=reconnect with ECDHE new suite) selects the key derivation variant.
The Waiting Exchange (Type=4) is sent when the OOB Step has not yet occurred; it always ends in EAP-Failure. The server MAY include a SleepTime value (integer 0–3600 seconds) to rate-limit peer probing attempts.
IANA creates an 'EAP-NOOB Cryptosuites' registry. Suite 1 (mandatory-to-implement) uses Curve25519 ECDHE and SHA-256. The Cryptosuites field is a JSON array of integer identifiers ordered by decreasing server priority; the peer responds with a single integer Cryptosuitep. New entries require Specification Required.
IANA creates an 'EAP-NOOB Error Codes' registry with ranges: 1xxx (invalid messages, e.g., 1001 invalid NAI, 1002 unparseable JSON, 1005 invalid ECDHE key), 2xxx (state/peer errors, e.g., 2001 unwanted peer, 2002 state mismatch, 2003 unrecognized NoobId), 3xxx (negotiation failures), 4xxx (cryptographic verification failures, e.g., 4001 incorrect MAC).
IANA creates an 'EAP-NOOB Message Types' registry with integer values 0–9: Type=0 (error notification), Types 1–3 (common handshake and Initial Exchange), Type=4 (Waiting Exchange), Types 5–6 (Completion Exchange), Types 7–9 (Reconnect Exchange). New entries require Specification Required.
IANA creates 'EAP-NOOB ServerInfo Data Fields' and 'EAP-NOOB PeerInfo Data Fields' registries for extensible JSON member names in the ServerInfo and PeerInfo objects. IANA also reserves the domain name 'eap-noob.arpa' for use as the default peer NAI realm.
EAP-NOOB authentication relies on the OOB channel being secure against eavesdropping and modification. The ECDHE exchange establishes keys over an insecure network, and the Hoob fingerprint sent via OOB authenticates the entire Initial Exchange to the OOB receiver, binding the key exchange to the correct participants.
In the Reconnect Exchange, the server SHOULD NOT offer and the peer MUST NOT accept protocol versions or cryptosuites weaker than those in the current persistent association. The CryptosuitepPrev/KzPrev rollback mechanism protects against synchronization failures caused by a lost final response during cryptosuite upgrades.
Misbinding attacks occur when a rogue server intercepts the OOB channel and tricks the user into associating the peer with an attacker-controlled server. EAP-NOOB mitigates this by including ServerInfo and all negotiated parameters in Hoob, enabling users to verify the intended server identity through the OOB channel before completing the association.
EAP-NOOB defines a five-state association state machine shared by both server and peer: Unregistered (0), Waiting for OOB (1), OOB Received (2), Reconnecting (3), and Registered (4). States 0–2 are ephemeral and can be reset by timeout or error; states 3–4 are persistent and can only be exited by explicit user reset or storage failure.
All EAP-NOOB in-band messages are formatted as JSON objects (RFC 8259) in UTF-8. Key field sizes: Noob=16 bytes, Hoob=16 bytes (truncated hash), NoobId=16 bytes (truncated hash), nonces Ns/Np/Ns2/Np2=32 bytes each, MACs/MACp/MACs2/MACp2=32 bytes each (truncated HMAC). ECDHE public keys PKs/PKp are in JWK format (RFC 7517). ServerInfo and PeerInfo JSON objects MUST NOT exceed 500 bytes each.
The OOB message carries PeerId, Noob (16-byte random secret), and Hoob computed as H(Dir,Vers,Verp,PeerId,Cryptosuites,Dirs,ServerInfo,Cryptosuitep,Dirp,NAI,PeerInfo,0,PKs,Ns,PKp,Np,Noob) truncated to 16 bytes. NoobId is computed as H('NoobId',Noob) truncated to 16 bytes. The Dir field (1=peer-to-server, 2=server-to-peer) is included in Hoob but is never sent over any channel.