RFC 5609

State Machines for the Protocol for Carrying Authentication for Network Access (PANA)

πŸ“… published August 2009, from ietf

RFC 5609: State Machines for the Protocol for Carrying Authentication for Network Access (PANA) πŸ¦‹

okay so this RFC is from August 2009 and it's an Informational doc, which means it's giving "here's some helpful info" and not a formal standard πŸ’…. It was written by V. Fajardo (Ed.) from Telcordia Technologies, Y. Ohba from Toshiba, and R. Marin-Lopez from Univ. of Murcia. It doesn't obsoletes or updates anything, since the original title block doesn't list anything it obsoletes or updates 🌸

Abstract ✨

okay so this doc defines the conceptual state machines for PANA (the Protocol for Carrying Authentication for Network Access) 🧚 there are two of them: the PANA Client (PaC) state machine and the PANA Authentication Agent (PAA) state machine. they show how PANA can interface with the EAP (Extensible Authentication Protocol) state machines πŸ”₯ but ngl the big thing to know is that the state machines and models are informative only. implementations can get the same results using different methods, so you're not locked in 🫢

Status of This Memo πŸŽ€

this memo gives info to the Internet community. it does NOT specify an Internet standard of any kind πŸ’€ distribution of this memo is unlimited, so share it with everyone who needs it ✨

Copyright (c) 2009 IETF Trust and the persons identified as the document authors. All rights reserved. πŸ’œ

this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents in effect on the date of publication of this document (http://trustee.ietf.org/license-info). please review these documents carefully, bestie, because they describe your rights and restrictions with respect to this document πŸ™ˆ

Table of Contents πŸ“

1. Introduction ....................................................3
2. Terminology .....................................................3
3. Interface between PANA and EAP ..................................3
4. Document Authority ..............................................5
5. Notations .......................................................5
6. Common Rules ....................................................6
   6.1. Common Procedures ..........................................6
   6.2. Common Variables ...........................................9
   6.3. Configurable Values .......................................10
   6.4. Common Message Initialization Rules .......................10
   6.5. Common Retransmission Rules ...............................10
   6.6. Common State Transitions ..................................11
7. PaC State Machine ..............................................12
   7.1. Interface between PaC and EAP Peer ........................12
        7.1.1. Delivering EAP Messages from PaC to EAP Peer .......12
        7.1.2. Delivering EAP Messages from EAP Peer to PaC .......12
        7.1.3. EAP Restart Notification from PaC to EAP Peer ......13
        7.1.4. EAP Authentication Result Notification from
               EAP Peer to PaC ....................................13
        7.1.5. Alternate Failure Notification from PaC to
               EAP Peer ...........................................13
   7.2. Configurable Values .......................................13
   7.3. Variables .................................................14
   7.4. Procedures ................................................15
   7.5. PaC State Transition Table ................................15
8. PAA State Machine ..............................................21
   8.1. Interface between PAA and EAP Authenticator ...............21
        8.1.1. EAP Restart Notification from PAA to EAP
               Authenticator ......................................21
        8.1.2. Delivering EAP Responses from PAA to EAP
               Authenticator ......................................22
        8.1.3. Delivering EAP Messages from EAP
               Authenticator to PAA ...............................22
        8.1.4. EAP Authentication Result Notification from
               EAP Authenticator to PAA ...........................22
   8.2. Variables .................................................23
   8.3. Procedures ................................................24
   8.4. PAA State Transition Table ................................24
9. Implementation Considerations ..................................29
   9.1. PAA and PaC Interface to Service Management Entity ........29
10. Security Considerations .......................................29
11. Acknowledgments ...............................................29
12. References ....................................................29
   12.1. Normative References .....................................29
   12.2. Informative References ...................................30

1. Introduction ✨

okay so this doc defines the state machines for PANA [RFC5191] 🧚 there's one for the PANA Client (PaC) and one for the PANA Authentication Agent (PAA). each state machine is specified through a set of variables, procedures, and a state transition table πŸ’– same reminder as the abstract: the state machines and models here are informative only, and implementations can get similar results with different models and/or methods 🫢

so here's the vibe of how PANA works. a PANA execution is several exchanges that carry authentication info. specifically, EAP PDUs get transported inside PANA PDUs between PaC and PAA. so PANA is a lower layer for EAP πŸ”₯ that means a PANA state machine runs based on an EAP state machine execution, and vice versa. this doc also shows, for both PaC and PAA, the interface between an EAP state machine and a PANA state machine, and how that interface lets them exchange info πŸ¦‹ thanks to this interface, a PANA state machine can get told about events happening in an EAP state machine and make its execution depend on those events. iconic, honestly πŸ‘‘

the details of EAP state machines are out of scope for this doc. you can find more info in [RFC4137]. still, the PANA state machines here have been coordinated with the state machines shown in [RFC4137] πŸ’…

this doc does three things: it defines the PaC and PAA state machines, it defines their interfaces to EAP state machines (which run on top of PANA), and it gives some implementation considerations. that last part is because this doc is not a specification. it's an implementation guideline 🌈

2. Terminology πŸŽ€

this doc reuses the terminology from [RFC5191]. no need to reinvent the wheel, slay ✨

3. Interface between PANA and EAP 🧚

PANA carries EAP messages exchanged between an EAP peer and an EAP authenticator (see Figure 1) πŸ’œ so a PANA state machine interacts with an EAP state machine.

two state machines are defined here: the PaC state machine (see Section 7) and the PAA state machine (see Section 8). each one has a set of variables, procedures, and a state transition table. a subset of those variables and procedures defines the interface between a PANA state machine and an EAP state machine, and the state transition table defines how the PANA state machine behaves based on the results it gets through them πŸ”₯

on one side, the PaC state machine talks to an EAP peer state machine to run PANA on the PaC side. on the other side, the PAA state machine talks to an EAP authenticator state machine to run PANA on the PAA side πŸ¦‹

                 Peer             |EAP            Auth
                 EAP    <---------|------------>  EAP
                ^ |               |              ^ |
                | |               | EAP-Message  | |  EAP-Message
   EAP-Message    | |EAP-Message  |                | |
                  | v             |PANA            | v
                 PaC    <---------|------------>  PAA

Figure 1: Interface between PANA and EAP

so two interfaces are needed between PANA state machines and EAP state machines:

  • Interface between the PaC state machine and the EAP peer state machine
  • Interface between the PAA state machine and the EAP authenticator state machine

in general, the PaC and PAA state machines present EAP messages to the EAP peer and authenticator state machines through the interface, respectively. then the EAP peer and authenticator state machines process those messages and send EAP messages back through the PaC and PAA state machines, which are the ones actually transmitting them πŸ’–

here's the lowdown on [RFC4137]. it specifies four interfaces to lower layers: (i) an interface between the EAP peer state machine and a lower layer, (ii) an interface between the EAP standalone authenticator state machine and a lower layer, (iii) an interface between the EAP full authenticator state machine and a lower layer, and (iv) an interface between the EAP backend authenticator state machine and a lower layer 🌸 in this doc, PANA is the lower layer of EAP, so only the first three interfaces matter to PANA. the second and third interfaces are the same. the EAP standalone authenticator or the EAP full authenticator (and its state machine in [RFC4137]) are called the EAP authenticator and the EAP authenticator state machine in this doc πŸ™ˆ if an EAP peer and an EAP authenticator follow the state machines in [RFC4137], the interfaces between PANA and EAP could be based on that doc. the detailed definitions of the PANA and EAP interfaces are in the later sections ✨

4. Document Authority πŸ‘‘

this doc is meant to comply with the technical content of the related docs, which are [RFC5191] and [RFC4137] 🫢 but if there's ever a discrepancy, those related docs are the authoritative ones and they take precedence over this doc. no debate, bestie πŸ’…


more parts coming, so stay tuned, bestie πŸ§šπŸ’œ

5. Notations πŸ“βœ¨

okay so these state transition tables are mostly built on the conventions from [RFC4137] πŸ’… the full text is down below, bestie

the tables show how the protocol runs as a bunch of cooperating state machines. each machine is a group of connected, mutually exclusive states, and only one state per machine can be active at any given time 🫢

every legal move from one state to another is written as a triplet of (exit condition, exit action, exit state). conditions are expressions that come out as TRUE or FALSE, and if it's TRUE the condition is met πŸ”₯ there's also a special wildcard state called "ANY" that matches any state in each machine, except the ones that get explicitly listed as exception states. the exit conditions of a wildcard state only get checked after all the other exit conditions for the current state are met 🌸

now the execution rules, which are very precise πŸ€“

  • on exit from a state, the exit actions for that state and the exit condition run exactly once, in the order they're written
  • (quick aside: [RFC4137] runs its procedures on entry to a state, and that's one of the big differences between that doc and this one πŸ‘‘)
  • each exit action is atomic, which means one finishes completely before the next one starts πŸ’–
  • no exit action ever runs outside of a state block
  • only one state block's exit actions run at a time, even when the conditions for state blocks in different state machines are all satisfied πŸ¦‹
  • all exit actions in a running state block finish before the transition to any other state block and before that block runs
  • running a state block looks atomic compared to every other state block, and the transition condition from the previous state is TRUE when it kicks off ✨
  • the order of state blocks across different state machines is undefined, except for whatever their transition conditions force 🌈
  • if a variable gets set to a value in a state block, it keeps that value until a later state block runs an exit action that changes it πŸ’œ

once the move from the previous state to the current one is done, every exit condition for the current state gets evaluated (wildcard ones included) until one of them is met πŸŽ€

any event variable gets set to TRUE when its event happens, and it goes back to FALSE right after the action tied to the current state and that event finishes 🫢

as for the special symbols and operators, their meaning is defined in [RFC4137] πŸ’…

6. Common Rules πŸŽ€

this section covers the procedures, variables, message initialization rules, and state transitions that the PaC and PAA state machines both share 🧚

throughout the document, the string "PANA_MESSAGE_NAME" stands in for any of the abbreviated PANA message names: "PCI", "PAR", "PAN", "PTR", "PTA", "PNR", and "PNA" πŸ“

6.1. Common Procedures πŸ› οΈ

void None()

a null procedure, so literally nothing happens πŸ™ˆ

void Disconnect()

deletes the PANA session along with its matching EAP session and authorization state πŸ’€

boolean Authorize()

creates or modifies authorization state πŸ” it returns TRUE if authorization works, and FALSE if it doesn't. it's assumed that the Authorize() procedure of the PaC state machine always returns TRUE. the tricky case is when a non-key-generating EAP method is used but a PANA SA is still needed after successful authentication (generate_pana_sa() returns TRUE). then Authorize() has to return FALSE, no exceptions 😭

void Tx:PANA_MESSAGE_NAME[flag](AVPs)

sends a PANA message to the peering PANA entity πŸ“¨ the "flag" argument holds one or more flags (for example Tx:PAR[C]) that get set on the message, except the 'R' (Request) flag. the "AVPs" argument is a list of optional AVP names to insert into the message, except the AUTH AVP πŸ’œ

before the actual transmission, this procedure does the following:

if (flag==S)
  PANA_MESSAGE_NAME.S_flag=Set;
if (flag==C)
  PANA_MESSAGE_NAME.C_flag=Set;
if (flag==A)
  PANA_MESSAGE_NAME.A_flag=Set;
if (flag==P)
  PANA_MESSAGE_NAME.P_flag=Set;
PANA_MESSAGE_NAME.insert_avp(AVPs);
if (key_available())
  PANA_MESSAGE_NANE.insert_avp("AUTH");
void TxEAP()

hands an EAP message over to the EAP state machine it's connected to πŸ¦‹

void RtxTimerStart()

starts the retransmission timer, resets RTX_COUNTER to zero, and sets a sensible value for RTX_MAX_NUM ⏱️ the spec assumes RTX_MAX_NUM is set to the same default for every message. implementations can also reset RTX_MAX_NUM inside this procedure though, and the value can change depending on which message was sent 🌸

void RtxTimerStop()

stops the retransmission timer βœ‹

void SessionTimerReStart(TIMEOUT)

(re)starts the PANA session timer ⏰ TIMEOUT is the expiration time for that session timer, and when it runs out it triggers a SESS_TIMEOUT event πŸ”₯

void SessionTimerStop()

stops the current PANA session timer πŸ›‘

void Retransmit()

resends a PANA message and bumps RTX_COUNTER up by one (1) πŸ”

void EAP_Restart()

(re)starts an EAP conversation, which re-initializes an existing EAP session 🌈

void PANA_MESSAGE_NAME.insert_avp("AVP_NAME1", "AVP_NAME2",...)

inserts the AVPs for each AVP name in the list into the PANA message 🧩 when an AVP name ends with "*", zero, one, or more AVPs get inserted. otherwise exactly one AVP gets inserted πŸ’–

boolean PANA_MESSAGE_NAME.exist_avp("AVP_NAME")

checks whether an AVP with that name is in the given PANA message πŸ” returns TRUE if it's found and FALSE if it's not πŸ‘€

boolean generate_pana_sa()

checks two things: whether the EAP method in use generates keys, and whether a PANA SA will be set up after successful authentication πŸ”‘ for the PaC, it also checks and matches the PRF and Integrity algorithm AVPs that the PAA advertised in the PAR[S] message. for the PAA, it indicates whether those PRF and Integrity algorithm AVPs are going to be sent in the PAR[S] πŸ’… it returns TRUE if a PANA SA will be generated, and FALSE otherwise

boolean key_available()

checks whether the PANA session has a PANA_AUTH_KEY πŸ—οΈ if the state machine already has one, it returns TRUE. if not, it tries to grab a Master Session Key (MSK) from the EAP entity. if it gets an MSK, it computes a PANA_AUTH_KEY from it and returns TRUE. otherwise it returns FALSE πŸ‘‘

6.2. Common Variables 🌷

PAR.RESULT_CODE πŸ“‹

this holds the Result-Code AVP value from the PANA-Auth-Request message currently being processed. when it carries PANA_SUCCESS, the spec assumes that PAR message always has an EAP-Payload AVP carrying an EAP-Success message πŸŽ‰

NONCE_SENT 🎲

set to TRUE to show that a Nonce-AVP has already been sent, and set to FALSE otherwise 🫢

RTX_COUNTER πŸ”’

the current number of retransmissions for the outstanding PANA message πŸ”

Rx:PANA_MESSAGE_NAME[flag] πŸ“¬

an event variable that gets set to TRUE when the given PANA message comes in from the peering PANA entity πŸ’Œ the "flag" is one flag (for example Rx:PAR[C]), except the 'R' (Request) flag.

RTX_TIMEOUT ⏰

an event variable that gets set to TRUE when the retransmission timer runs out 😱

REAUTH πŸ”„

an event variable that gets set to TRUE when a re-authentication phase gets kicked off. it can only be set while in the OPEN state πŸ¦‹

TERMINATE πŸšͺ

an event variable that gets set to TRUE when the PANA session termination starts. it can only be set while in the OPEN state πŸ’€

PANA_PING πŸ“

an event variable that gets set to TRUE when a liveness test based on the PANA-Notification exchange starts. it can only be set while in the OPEN state ✨

SESS_TIMEOUT βŒ›

an event variable that gets set to TRUE when the session timer has expired πŸ™ˆ

LIFETIME_SESS_TIMEOUT πŸŽ€

a configurable value that the PaC and PAA use to close or disconnect an established session during the access phase. this variable marks when the session expires, and it's set to the value of the Session-Lifetime AVP if that AVP is in the last PANA-Auth-Request message (for the PaC). otherwise the value is assumed to be infinite, so it never expires. when LIFETIME_SESS_TIMEOUT expires, the SESS_TIMEOUT event variable gets set πŸ”₯

ANY 🌍

an event variable that gets set to TRUE whenever any event happens 🫢

6.3. Configurable Values βš™οΈ

RTX_MAX_NUM πŸ”§

the configurable maximum for how many retransmissions should be tried before giving up πŸ›‘

6.4. Common Message Initialization Rules πŸŽ€

when a message is getting ready to send, it gets initialized like this πŸ’…

  • for a request message, the R-flag in the header is set. otherwise the R-flag is not set
  • the other message header flags are not set at all. state machine actions set them explicitly
  • AVPs that have to be included in a message get inserted with the right values set ✨

6.5. Common Retransmission Rules πŸ”

the state machines in this document assume that both the PaC and the PAA cache the last answer message they sent. this scheme is described in Section 5.2 of [RFC5191] πŸ’Œ when the PaC or PAA gets a retransmitted or duplicate request, it can resend the matching answer without any help from the EAP layer. to keep the state machine descriptions simple, though, this caching scheme is left out of the state machines below 🫢 if there's no matching answer for a retransmitted request, the request just gets handled by the corresponding state machine 🌸

6.6. Common State Transitions

Okay so these transitions can happen from pretty much any state, with a few exemptions that get called out. πŸ’…

   ----------
   State: ANY
   ----------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - (Re-transmissions)- - - - - - - - - -
   RTX_TIMEOUT &&           Retransmit();              (no change)
   RTX_COUNTER<
   RTX_MAX_NUM
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - (Reach maximum number of transmissions)- - - - - -
   (RTX_TIMEOUT &&          Disconnect();              CLOSED
    RTX_COUNTER>=
    RTX_MAX_NUM) ||
   SESS_TIMEOUT
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

So for ANY state, if the retransmit timer goes off and the counter is still under the max, we just retransmit and stay where we are. πŸ” But if the counter hits RTX_MAX_NUM or the session times out, we disconnect and land in CLOSED. Rip. πŸ’€

   -------------------------
   State: ANY except INITIAL
   -------------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - (liveness test initiated by peer)- - - - - -
   Rx:PNR[P]                Tx:PNA[P]();               (no change)

Everywhere except INITIAL, if the peer starts a liveness test (that's a PNR[P] coming in), we answer with a PNA[P] and don't change state. Very polite of us. 🫢

   -------------------------------
   State: ANY except WAIT_PNA_PING
   -------------------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - (liveness test response) - - - - - - - -
   Rx:PNA[P]                None();                    (no change)

And everywhere except WAIT_PNA_PING, if a PNA[P] shows up as a liveness test response, we do nothing and stay put. Easy. ✨

The following transitions can happen on any exit condition inside the specified state.

   -------------
   State: CLOSED
   -------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - -(Catch all event on closed state) - - - - - - - -
   ANY                      None();                    CLOSED
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

And CLOSED is the catch-all: whatever happens, we do nothing and stay CLOSED. Very chill state, honestly. 😌


7. PaC State Machine ✨

7.1. Interface between PaC and EAP Peer

This is the interface for how a PaC and an EAP peer talk to each other. πŸ¦‹ Its whole job is delivering EAP messages: the EAP peer gets EAP requests and sends EAP responses through the PaC. It also lets the PaC tell the EAP peer about PaC events, and lets the EAP peer tell the PaC about its own events. These message deliveries and notifications line up directly with the entries in the PaC state transition table, and they only happen inside their associated states or exit actions. Keep that in mind, bestie. πŸŽ€

7.1.1. Delivering EAP Messages from PaC to EAP Peer

TxEAP() is the procedure in the PaC state machine that delivers the EAP messages carried in PANA-Auth-Request messages to the EAP peer. It only works after an EAP restart event has been notified to the EAP peer, and before any event that ends the EAP peer session. If the EAP peer follows the EAP peer state machine defined in [RFC4137], then TxEAP() sets the eapReq variable of that EAP peer state machine and puts the EAP request into the eapReqData variable. πŸ’Œ

7.1.2. Delivering EAP Messages from EAP Peer to PaC

The EAP peer hands an EAP message to the PaC through the EAP_RESPONSE event variable. That variable gets set when the EAP peer passes the EAP message down to its lower layer. If the EAP peer follows the EAP peer state machine defined in [RFC4137], then EAP_RESPONSE refers to the eapResp variable of the EAP peer state machine, and the EAP message itself is in the eapRespData variable. πŸ“¨

7.1.3. EAP Restart Notification from PaC to EAP Peer

The EAP peer state machine defined in [RFC4137] has an initialization procedure it runs before it can receive any EAP message. πŸ”„ So the PaC state machine has an event notification mechanism to send an EAP (re)start event to the EAP peer. That notification happens through the EAP_Restart() procedure, which lives in the initialization action of the PaC state machine.

7.1.4. EAP Authentication Result Notification from EAP Peer to PaC

So the EAP peer can tell the PaC whether EAP authentication worked, we have the EAP_SUCCESS and EAP_FAILURE event variables. If the EAP peer follows the EAP peer state machine defined in [RFC4137], those event variables refer to the eapSuccess and eapFail variables of that state machine, in that order. In that setup, if EAP_SUCCESS is set to TRUE and the EAP authentication method in use generates an MSK, then eapKeyAvailable is set to TRUE and eapKeyData holds the MSK. πŸ”‘

Heads up, though: EAP_SUCCESS and EAP_FAILURE can be set to TRUE even before the PaC gets a PAR with the 'Complete' flag set from the PAA. Plan for that, bestie. πŸ‘€

7.1.5. Alternate Failure Notification from PaC to EAP Peer

alt_reject() is the procedure in the PaC state machine that tells the EAP peer about an authentication failure event without sending along an EAP message. If the EAP peer follows the EAP peer state machine defined in [RFC4137], alt_reject() sets the altReject variable of that state machine. The [RFC4137] EAP peer state machine also defines an altAccept variable, but PANA never uses it. That's because in PANA, EAP-Success messages are reliably delivered by the last PANA-Auth exchange, so there's no need. πŸ’…

7.2. Configurable Values

  • FAILED_SESS_TIMEOUT

This is a configurable value. It lets the PaC figure out whether the PaC authentication and authorization phase has stalled without an explicit EAP success or failure notification. Stalled = no vibes, no result. πŸ₯€

7.3. Variables

  • AUTH_USER

This event variable gets set to TRUE when the application triggers the start of an EAP-based (re-)authentication. πŸš€

  • EAP_SUCCESS

This event variable gets set to TRUE when the EAP peer decides that an EAP conversation finished with success. πŸŽ‰

  • EAP_FAILURE

This event variable gets set to TRUE when the EAP peer decides that an EAP conversation finished with failure. πŸ’”

  • EAP_RESPONSE

This event variable gets set to TRUE when the EAP peer delivers an EAP message to the PaC. It shows up together with an EAP message that came in from the EAP peer. πŸ“¬

  • EAP_RESP_TIMEOUT

This event variable gets set to TRUE when the PaC has passed an EAP message down to the EAP layer and doesn't get a follow-up EAP message from the EAP layer within a given period. It's basically a time limit for certain EAP methods where a human might need to do something, like type a password. ⏳

  • EAP_DISCARD

This event variable gets set to TRUE when the EAP peer says it silently discarded the last EAP-Request it got. This event doesn't come with any EAP message. If the EAP peer follows the EAP peer state machine defined in [RFC4137], this event variable refers to eapNoResp.

Note, this one is spicy: this specification does not support silently discarding EAP messages. They're treated as fatal errors instead. This may have an impact on denial-of-service resistance. 🚨😭

7.4. Procedures

  • boolean eap_piggyback()

This procedure returns TRUE to say whether the next EAP response will be carried in the pending PAN message for optimization. ✨

  • void alt_reject()

This procedure tells the EAP peer about an authentication failure event without sending an EAP message along with it. πŸ™…β€β™€οΈ

  • void EAP_RespTimerStart()

This is the procedure that starts a timer for receiving an EAP-Response from the EAP peer. ⏱️

  • void EAP_RespTimerStop()

This is the procedure that stops that same timer, the one for receiving an EAP-Response from the EAP peer. πŸ›‘

7.5. PaC State Transition Table ✨

okay bestie, this is the big one πŸ’… the whole PaC choreography lives here, state by state. every block below is copied exactly, so the table is literally the spec 🫢

   ------------------------------
   State: INITIAL (Initial State)
   ------------------------------

   Initialization Action:

     NONCE_SENT=Unset;
     RTX_COUNTER=0;
     RtxTimerStop();

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+-----------
   - - - - - - - - - - (PaC-initiated Handshake) - - - - - - - - -
   AUTH_USER                Tx:PCI[]();                INITIAL
                            RtxTimerStart();
                            SessionTimerReStart
                              (FAILED_SESS_TIMEOUT);
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - -(PAA-initiated Handshake, not optimized) - - - - -
   Rx:PAR[S] &&             EAP_Restart();             WAIT_PAA
   !PAR.exist_avp           SessionTimerReStart
   ("EAP-Payload")              (FAILED_SESS_TIMEOUT);
                            if (generate_pana_sa())
                                Tx:PAN[S]("PRF-Algorithm",
                                   "Integrity-Algorithm");
                            else
                                Tx:PAN[S]();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   - - - - - - - -(PAA-initiated Handshake, optimized) - - - - - -
   Rx:PAR[S] &&             EAP_Restart();             INITIAL
   PAR.exist_avp            TxEAP();
   ("EAP-Payload") &&       SessionTimerReStart
   eap_piggyback()            (FAILED_SESS_TIMEOUT);

   Rx:PAR[S] &&             EAP_Restart();             WAIT_EAP_MSG
   PAR.exist_avp            TxEAP();
   ("EAP-Payload") &&       SessionTimerReStart
   !eap_piggyback()           (FAILED_SESS_TIMEOUT);
                            if (generate_pana_sa())
                                Tx:PAN[S]("PRF-Algorithm",
                                  "Integrity-Algorithm");
                            else
                                Tx:PAN[S]();

   EAP_RESPONSE             if (generate_pana_sa())    WAIT_PAA
                                Tx:PAN[S]("EAP-Payload",
                                  "PRF-Algorithm",
                                  "Integrity-Algorithm");
                            else
                                Tx:PAN[S]("EAP-Payload");
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

first up is INITIAL: it sets up the nonce, the retransmission counter and the timer, then waits for whichever handshake kicks off first πŸ¦‹

   ---------------
   State: WAIT_PAA
   ---------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - - -(PAR-PAN exchange) - - - - - - - -
   Rx:PAR[] &&              RtxTimerStop();            WAIT_EAP_MSG
   !eap_piggyback()         TxEAP();
                            EAP_RespTimerStart();
                            if (NONCE_SENT==Unset) {
                              NONCE_SENT=Set;
                              Tx:PAN[]("Nonce");
                            }
                            else
                              Tx:PAN[]();

   Rx:PAR[] &&              RtxTimerStop();            WAIT_EAP_MSG
   eap_piggyback()          TxEAP();
                            EAP_RespTimerStart();

   Rx:PAN[]                 RtxTimerStop();            WAIT_PAA

   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   - - - - - - - - - - - - - - -(PANA result) - - - - - - - - - -
   Rx:PAR[C] &&             TxEAP();                   WAIT_EAP_RESULT
   PAR.RESULT_CODE==
     PANA_SUCCESS

   Rx:PAR[C] &&             if (PAR.exist_avp          WAIT_EAP_RESULT_
   PAR.RESULT_CODE!=          ("EAP-Payload"))         CLOSE
     PANA_SUCCESS             TxEAP();
                            else
                               alt_reject();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_PAA is the "waiting on the PAA" spot 🌸 it either hops over to EAP land or hears the PANA result and heads toward the EAP result

   -------------------
   State: WAIT_EAP_MSG
   -------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - (Return PAN/PAR from EAP) - - - - - - - - -
   EAP_RESPONSE &&          EAP_RespTimerStop()        WAIT_PAA
   eap_piggyback()          if (NONCE_SENT==Unset) {
                              Tx:PAN[]("EAP-Payload",
                                       "Nonce");
                              NONCE_SENT=Set;
                            }
                            else
                              Tx:PAN[]("EAP-Payload");

   EAP_RESPONSE &&          EAP_RespTimerStop()        WAIT_PAA
   !eap_piggyback()         Tx:PAR[]("EAP-Payload");
                            RtxTimerStart();

   EAP_RESP_TIMEOUT &&      Tx:PAN[]();                WAIT_PAA
   eap_piggyback()

   EAP_DISCARD &&           Tx:PAN[]();                CLOSED
   eap_piggyback()          SessionTimerStop();
                            Disconnect();

   EAP_FAILURE ||           SessionTimerStop();        CLOSED
   (EAP_DISCARD &&          Disconnect();
   !eap_piggyback())
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_EAP_MSG is where the EAP messages get passed around, and the exits are either a PAN or PAR coming back or the whole thing getting tossed πŸ“

   ----------------------
   State: WAIT_EAP_RESULT
   ----------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - (EAP Result) - - - - - - - - - - - - -
   EAP_SUCCESS             if (PAR.exist_avp           OPEN
                              ("Key-Id"))
                             Tx:PAN[C]("Key-Id");
                           else
                             Tx:PAN[C]();
                           Authorize();
                           SessionTimerReStart
                             (LIFETIME_SESS_TIMEOUT);

   EAP_FAILURE             Tx:PAN[C]();                CLOSED
                           SessionTimerStop();
                           Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_EAP_RESULT is the moment of truth ✨ success opens the session and sets the lifetime timer, failure closes everything down 😭

   ----------------------------
   State: WAIT_EAP_RESULT_CLOSE
   ----------------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - (EAP Result) - - - - - - - - - - - - -
   EAP_SUCCESS ||          if (EAP_SUCCESS &&         CLOSED
   EAP_FAILURE               PAR.exist_avp("Key-Id"))
                             Tx:PAN[C]("Key-Id");
                           else
                             Tx:PAN[C]();
                           SessionTimerStop();
                           Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_EAP_RESULT_CLOSE is basically the "we're leaving anyway" state, so whatever EAP result shows up, it wraps up and closes πŸŽ€

   -----------
   State: OPEN
   -----------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - (liveness test initiated by PaC)- - - - - -
   PANA_PING                Tx:PNR[P]();               WAIT_PNA_PING
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - (re-authentication initiated by PaC)- - - - - -
   REAUTH                   NONCE_SENT=Unset;          WAIT_PNA_REAUTH
                            Tx:PNR[A]();
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - (re-authentication initiated by PAA)- - - - - -
   Rx:PAR[]                 EAP_RespTimerStart();      WAIT_EAP_MSG
                            TxEAP();
                            if (!eap_piggyback())
                              Tx:PAN[]("Nonce");
                            else
                              NONCE_SENT=Unset;
                            SessionTimerReStart
                              (FAILED_SESS_TIMEOUT);
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - -(Session termination initiated by PAA) - - - - - -
   Rx:PTR[]                 Tx:PTA[]();                CLOSED
                            SessionTimerStop();
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - -(Session termination initiated by PaC) - - - - - -
   TERMINATE                Tx:PTR[]();                SESS_TERM
                            RtxTimerStart();
                            SessionTimerStop();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

OPEN is the happy hangout spot 🌈 liveness pings, re-auth from either side, and termination from either side all branch off from here

   ----------------------
   State: WAIT_PNA_REAUTH
   ----------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - -(re-authentication initiated by PaC) - - - - -
   Rx:PNA[A]                RtxTimerStop();            WAIT_PAA
                            SessionTimerReStart
                              (FAILED_SESS_TIMEOUT);
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - -(Session termination initiated by PAA) - - - - - -
   Rx:PTR[]                 RtxTimerStop();            CLOSED
                            Tx:PTA[]();
                            SessionTimerStop();
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_PNA_REAUTH waits for the answer to the PaC's re-auth request, and it can still get shut down by the PAA in the meantime πŸ™ˆ

   --------------------
   State: WAIT_PNA_PING
   --------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - -(liveness test initiated by PaC) - - - - - - -
   Rx:PNA[P]                RtxTimerStop();            OPEN
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - (re-authentication initiated by PAA)- - - - -
   Rx:PAR[]                 RtxTimerStop();            WAIT_EAP_MSG
                            EAP_RespTimerStart();
                            TxEAP();
                            if (!eap_piggyback())
                              Tx:PAN[]("Nonce");
                            else
                              NONCE_SENT=Unset;
                            SessionTimerReStart
                              (FAILED_SESS_TIMEOUT);
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - -(Session termination initiated by PAA) - - - - - -
   Rx:PTR[]                 RtxTimerStop();            CLOSED
                            Tx:PTA[]();
                            SessionTimerStop();
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_PNA_PING is the same deal but for liveness checks: a PNA means back to OPEN, and the PAA can still crash the party with a PAR or PTR πŸ’œ

   ----------------
   State: SESS_TERM
   ----------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - -(Session termination initiated by PaC) - - - - -
   Rx:PTA[]                 Disconnect();              CLOSED
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

and finally SESS_TERM, the quiet little exit lounge where the PaC just waits for its PTA and then disconnects πŸ¦‹


8. PAA State Machine ✨

Now we flip to the PAA side πŸ‘‘ same vibes, opposite seat.

8.1. Interface between PAA and EAP Authenticator πŸŽ€

okay so the PAA and the EAP authenticator need a way to talk, bestie 🫢 there's a way to deliver EAP messages over to the authenticator, a way to tell it about PAA events, and a way to hear back when the authenticator has something to say. all of this only happens inside the context of the related states or exit actions, so no random side-chatter πŸ’…

8.1.1. EAP Restart Notification from PAA to EAP Authenticator 🌸

so the EAP authenticator state machine, the one defined in [RFC4137], has its own initialization step before it sends out the first EAP request 🧚 to get it ready, the PAA state machine has an event notification to send over an EAP (re)start event. that notification happens through the EAP_Restart() procedure, which lives in the initialization action of the PAA state machine πŸ’–

8.1.2. Delivering EAP Responses from PAA to EAP Authenticator ✨

okay so the TxEAP() procedure in the PAA state machine is the thing that actually delivers the EAP-Responses riding inside PANA-Auth-Answer messages over to the EAP authenticator πŸ“¬ it's giving postal service bestie πŸ’Œ BUT it only gets to work after an EAP restart event has been notified to the EAP authenticator, and it stops being a thing once any event ends the EAP authenticator session πŸ›‘ 🫢

if the EAP authenticator is following the EAP authenticator state machines from [RFC4137], then TxEAP() sets the eapResp variable of that state machine and drops the response into eapRespData 🧚 the way that everything just clicks into place 😭πŸ”₯

8.1.3. Delivering EAP Messages from EAP Authenticator to PAA πŸ¦‹

so an EAP request makes its way from the EAP authenticator to the PAA through the EAP_REQUEST event variable πŸ’Œ the event variable gets set when the EAP authenticator hands the EAP request down to its lower layer 🌊 ngl this is the moment the request officially leaves the building πŸƒβ€β™€οΈπŸ’¨

again, if the EAP authenticator is running the [RFC4137] state machines, then EAP_REQUEST is basically the eapReq variable of that state machine, and the actual EAP request is sitting in eapReqData πŸŽ€ iykyk, it's all just a little relay race between variables πŸπŸ’–

8.1.4. EAP Authentication Result Notification from EAP Authenticator to PAA πŸ†

okay this is the big moment, the result announcement πŸ₯ΉπŸ“£ so the EAP authenticator needs a way to tell the PAA how the EAP authentication went, and for that we get three event variables: EAP_SUCCESS, EAP_FAILURE, and EAP_TIMEOUT πŸ‘‘ they are giving very "pick a winner" energy ✨

if the EAP authenticator is using the [RFC4137] state machines, those three map onto eapSuccess, eapFail, and eapTimeout respectively 🌈 now here's the tea πŸ«–: when EAP_SUCCESS is set to TRUE, an EAP-Success message is sitting in the eapReqData variable of that EAP authenticator state machine πŸŽ‰ and then, on top of that, eapKeyAvailable gets set to TRUE and eapKeyData holds an MSK, but only if the EAP authentication method in use actually generated an MSK as a result of the successful authentication πŸ”‘ (not every method does, so this part is conditional, bestie πŸ’…)

flip side: when EAP_FAILURE is set to TRUE, an EAP-Failure message shows up in eapReqData πŸ’€ rip 😭

and the PAA uses EAP_SUCCESS and EAP_FAILURE as its trigger to send a PAR message to the PaC πŸ“¨ that's the cue, no cap πŸš€


8.2. Variables πŸ’œ

OPTIMIZED_INIT 🌸

this one tells us whether the PAA can piggyback an EAP-Request onto the initial PANA-Auth-Request 🎁 if it can, it's TRUE, and if it can't, it's set to FALSE πŸ™ˆ simple and iconic πŸ’…

PAC_FOUND πŸ”

this gets set to TRUE as a result of a PAA-initiated handshake 🀝 so basically, the PAA went looking and found the PaC, periodt πŸ§šβ€β™€οΈ

REAUTH_TIMEOUT ⏰

this is an event variable that gets set to TRUE when the PAA decides it's time to kick off a re-authentication with the PaC πŸ” the re-authentication timeout should be set to a value less than the session timeout carried in the Session-Lifetime AVP, if that AVP is present 🫢 so leave yourself some breathing room, bestie 🌷

EAP_SUCCESS πŸŽ‰

this event variable gets set to TRUE when an EAP conversation wraps up with success ✨ it comes along with an EAP-Success message that's passed in from the EAP authenticator πŸ₯³

EAP_FAILURE πŸ’”

this event variable gets set to TRUE when an EAP conversation ends in failure 😭 it rides along with an EAP-Failure message passed from the EAP authenticator πŸ™ƒ

EAP_REQUEST πŸ’Œ

this event variable gets set to TRUE when the EAP authenticator delivers an EAP Request to the PAA πŸ“¬ it accompanies an EAP-Request message that the PAA received from the EAP authenticator πŸ¦‹

EAP_TIMEOUT βŒ›

this event variable gets set to TRUE when an EAP conversation times out without ever producing an EAP-Success or an EAP-Failure message 😢 and this one doesn't come with any EAP message attached, so it's just the vibes of silence πŸŒ™

EAP_DISCARD πŸ—‘οΈ

this event variable gets set to TRUE when the EAP authenticator says it has silently discarded the last EAP-Response message it received 🀫 same as the timeout, it doesn't accompany any EAP message πŸ’œ and if the EAP authenticator is following the [RFC4137] state machines, this event variable refers to eapNoReq ✨


8.3. Procedures πŸ› οΈ

new_key_available() πŸ”‘

this is the procedure that checks whether the PANA session has a new PANA_AUTH_KEY πŸ‘€ here's how it goes, step by step, bestie:

  • if the state machine already has a PANA_AUTH_KEY, it returns FALSE πŸ™…β€β™€οΈ
  • if the state machine doesn't have a PANA_AUTH_KEY, it tries to retrieve an MSK from the EAP entity πŸ”
  • if an MSK gets retrieved, it computes a PANA_AUTH_KEY from that MSK and returns TRUE πŸŽ€
  • otherwise, it returns FALSE πŸ’€

the whole thing is very "check if I already have it, if not go get it, if got it make it" energy and I am obsessed 😭🫢

8.4. PAA State Transition Table ✨

okay so this is the PAA's whole rulebook, state by state, transition by transition πŸ¦‹ each table is a little story of what happens when a message shows up, what the PAA does about it, and where it ends up next. I've kept every line exactly as written, so the code is ready to implement πŸ’…

   ------------------------------
   State: INITIAL (Initial State)
   ------------------------------

   Initialization Action:

     OPTIMIZED_INIT=Set|Unset;
     NONCE_SENT=Unset;
     RTX_COUNTER=0;
     RtxTimerStop();

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
    - - - - - - - - (PCI and PAA initiated PANA) - - - - - - - - -
   (Rx:PCI[] ||             if (OPTIMIZED_INIT ==      INITIAL
    PAC_FOUND)                  Set) {
                              EAP_Restart();
                              SessionTimerReStart
                               (FAILED_SESS_TIMEOUT);
                            }
                            else {
                              if (generate_pana_sa())
                                   Tx:PAR[S]("PRF-Algorithm",
                                      "Integrity-Algorithm");
                              else
                                   Tx:PAR[S]();

                            }

   EAP_REQUEST              if (generate_pana_sa())    INITIAL
                                Tx:PAR[S]("EAP-Payload",
                                   "PRF-Algorithm",
                                   "Integrity-Algorithm");
                            else
                                Tx:PAR[S]("EAP-Payload");
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   - - - - - - - - - - - - - - (PAN Handling)  - - - - - - - - - -
   Rx:PAN[S] &&             if (PAN.exist_avp          WAIT_EAP_MSG
   ((OPTIMIZED_INIT ==         ("EAP-Payload"))
     Unset) ||                TxEAP();
   PAN.exist_avp            else {
     ("EAP-Payload"))         EAP_Restart();
                              SessionTimerReStart
                               (FAILED_SESS_TIMEOUT);
                            }

   Rx:PAN[S] &&             None();                    WAIT_PAN_OR_PAR
   (OPTIMIZED_INIT ==
     Set) &&
   ! PAN.exist_avp
    ("EAP-Payload")

   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Next up, WAIT_EAP_MSG, where the PAA is waiting on EAP stuff to come back 🧚

   -------------------
   State: WAIT_EAP_MSG
   -------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - -(Receiving EAP-Request)- - - - - - - - -
   EAP_REQUEST              if (NONCE_SENT==Unset) {   WAIT_PAN_OR_PAR
                              Tx:PAR[]("Nonce",
                                       "EAP-Payload");
                              NONCE_SENT=Set;
                            }
                            else
                              Tx:PAR[]("EAP-Payload");
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - - -(Receiving EAP-Success/Failure) - - - - -
   EAP_FAILURE              PAR.RESULT_CODE =          WAIT_FAIL_PAN
                              PANA_AUTHENTICATION_

                                  REJECTED;
                            Tx:PAR[C]("EAP-Payload");
                            RtxTimerStart();
                            SessionTimerStop();

   EAP_SUCCESS &&           PAR.RESULT_CODE =          WAIT_SUCC_PAN
   Authorize()                PANA_SUCCESS;
                            if (new_key_available())
                              Tx:PAR[C]("EAP-Payload",
                                   "Key-Id");
                            else
                              Tx:PAR[C]("EAP-Payload");
                            RtxTimerStart();

   EAP_SUCCESS &&           PAR.RESULT_CODE =          WAIT_FAIL_PAN
   !Authorize()               PANA_AUTHORIZATION_
                                REJECTED;
                            if (new_key_available())
                              Tx:PAR[C]("EAP-Payload",
                                   "Key-Id");
                            else
                              Tx:PAR[C]("EAP-Payload");
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - (Receiving EAP-Timeout or invalid message) - - - - -
   EAP_TIMEOUT ||           SessionTimerStop();        CLOSED
   EAP_DISCARD              Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Now WAIT_SUCC_PAN, the "waiting for the happy PAN" state πŸŽ€

   --------------------
   State: WAIT_SUCC_PAN
   --------------------

   Event/Condition          Action                     Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - (PAN Processing)- - - - - - - - - - -
   Rx:PAN[C]                RtxTimerStop();            OPEN
                            SessionTimerReStart
                              (LIFETIME_SESS_TIMEOUT);
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

And WAIT_FAIL_PAN, the "well, that didn't go well" version πŸ₯²

   --------------------
   State: WAIT_FAIL_PAN
   --------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - - (PAN Processing)- - - - - - - - - -
   Rx:PAN[C]                RtxTimerStop();            CLOSED
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Then we hit OPEN, the main character state where the session is actually live πŸ‘‘

   -----------

   State: OPEN
   -----------

   Event/Condition          Action                     Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - (re-authentication initiated by PaC) - - - - - -
   Rx:PNR[A]                NONCE_SENT=Unset;          WAIT_EAP_MSG
                            EAP_Restart();
                            Tx:PNA[A]();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - (re-authentication initiated by PAA)- - - - - -
   REAUTH ||                NONCE_SENT=Unset;          WAIT_EAP_MSG
   REAUTH_TIMEOUT           EAP_Restart();

   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - (liveness test based on PNR-PNA exchange initiated by PAA)-
   PANA_PING                Tx:PNR[P]();               WAIT_PNA_PING
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - (Session termination initiated from PAA)- - - -
   TERMINATE                Tx:PTR[]();                SESS_TERM
                            SessionTimerStop();
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - (Session termination initiated from PaC)- - - -
   Rx:PTR[]                 Tx:PTA[]();                CLOSED
                            SessionTimerStop();
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_PNA_PING is the "I sent a ping and I'm waiting for the reply" moment πŸ“

   --------------------
   State: WAIT_PNA_PING
   --------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - -(PNA processing) - - - - - - - - - -
   Rx:PNA[P]                RtxTimerStop();            OPEN
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - (re-authentication initiated by PaC) - - - - - -
   Rx:PNR[A]                RtxTimerStop();            WAIT_EAP_MSG
                            NONCE_SENT=Unset;
                            EAP_Restart();
                            Tx:PNA[A]();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - (Session termination initiated from PaC)- - - - -
   Rx:PTR[]                 RtxTimerStop();            CLOSED
                            Tx:PTA[]();
                            SessionTimerStop();
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

WAIT_PAN_OR_PAR is the state where the PAA is juggling PAN and PAR messages 🀹

   ----------------------
   State: WAIT_PAN_OR_PAR
   ----------------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - (PAR Processing)- - - - - - - - - - -
   Rx:PAR[]                 TxEAP();                   WAIT_EAP_MSG
                            RtxTimerStop();
                            Tx:PAN[]();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - (Pass EAP Response to the EAP authenticator)- - - -
   Rx:PAN[] &&              TxEAP();                   WAIT_EAP_MSG
   PAN.exist_avp            RtxTimerStop();
   ("EAP-Payload")
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - - (PAN without an EAP response) - - - - - - -
   Rx:PAN[] &&              RtxTimerStop();            WAIT_PAN_OR_PAR
   !PAN.exist_avp
   ("EAP-Payload")
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - - - - - -(EAP retransmission) - - - - - - - - - -
   EAP_REQUEST              RtxTimerStop();            WAIT_PAN_OR_PAR
                            Tx:PAR[]("EAP-Payload");
                            RtxTimerStart();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   - - - - - - - (EAP authentication timeout or failure)- - - - -
   EAP_FAILURE ||           RtxTimerStop();            CLOSED
   EAP_TIMEOUT ||           SessionTimerStop();
   EAP_DISCARD              Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

And finally SESS_TERM, the wind-down state where the PAA is waiting for its PTA πŸŒ™

   ----------------
   State: SESS_TERM
   ----------------

   Exit Condition           Exit Action                Exit State
   ------------------------+--------------------------+------------
   - - - - - - - - - - - - - -(PTA processing) - - - - - - - - - -
   Rx:PTA[]                 RtxTimerStop();            CLOSED
                            Disconnect();
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

9. Implementation Considerations πŸ› οΈ

9.1. PAA and PaC Interface to Service Management Entity πŸ’…

okay so bestie, picture every device or network box as having its own PANA protocol stack that other modules inside the device can just borrow 🫢 one of those modules is the Service Management Entity (SME), which is a generic name for any module that manages services, including network protocols, that are installed on a device or piece of equipment ✨ to plug PANA into the SME, the recommended move is a generic interface called the SME-PANA interface, sitting between the SME and the PANA protocol stack, and the implementation is the one that provides it πŸŽ€ that interface should include common procedures like startup, shutdown, and re-authenticate signals, and it should also let you pull out keying material πŸ”‘

For the PAA, the SME-PANA interface should also offer a way to hand filtering parameters over to the Enforcement Point(s) when cryptographic filtering is in use 🧚 those filtering parameters include keying material for bootstrapping secured transport, like IPsec πŸ” and if the PAA is talking to the backend authentication server over a AAA protocol, its SME may also expose an interface to that AAA protocol so it can grab authorization parameters, such as the authorization lifetime and extra filtering parameters πŸ’œ

10. Security Considerations 🚨

This is the serious part, no cap. This document's intent is to describe the PANA state machines fully. To this end, any security concerns with this document are likely a reflection of security concerns with PANA itself. So if PANA has security issues, they're going to show up here too, and that's on PANA, not this doc 😭

11. Acknowledgments 🫢

This work was started from state machines originally made by Dan Forsberg. Thank you, Dan, you literally laid the groundwork for all of this πŸ’–

12. References πŸ“š

12.1. Normative References πŸ”₯

   [RFC5191]  Forsberg, D., Ohba, Y., Patil, B., Tschofenig, H., and A.
              Yegin, "Protocol for Carrying Authentication for Network
              Access (PANA)", RFC 5191, May 2008.

12.2. Informative References ✨

okay so the informative stuff is just one bestie: [RFC4137] πŸ¦‹ It's the state machines doc for EAP peers and authenticators, and it's giving "read this if you want the full picture" energy.

[RFC4137] Vollbrecht, J., Eronen, P., Petroni, N., and Y. Ohba, "State Machines for Extensible Authentication Protocol (EAP) Peer and Authenticator", RFC 4137, August 2005.

Authors' Addresses πŸ’–

here are the authors, the brains behind this whole thing πŸ‘‘ Victor Fajardo (editor) is at Telcordia Technologies, Yoshihiro Ohba is at Toshiba Corporate Research and Development Center, and Rafa Marin-Lopez is at the University of Murcia 🌸 their contact details are below, exactly as written:

Victor Fajardo (editor)
Telcordia Technologies
1 Telcordia Drive
Piscataway, NJ  08854
USA

Phone: +1 732 699 5368
EMail: vfajardo@research.telcordia.com


Yoshihiro Ohba
Toshiba Corporate Research and Development Center
1 Komukai-Toshiba-cho, Saiwai-ku
Kawasaki, Kanagawa  212-8582
Japan

Phone: +81 44 549 2230
EMail: yoshihiro.ohba@toshiba.co.jp


Rafa Marin-Lopez
University of Murcia
Campus de Espinardo S/N, Facultad de Informatica
Murcia  30100
Spain

Phone: +34 868 888 501
EMail: rafa@um.es
πŸ“¦ where this page comes from