RFC 2522

Photuris: Session-Key Management Protocol

๐Ÿ“… published March 1999, from ietf

RFC 2522: Photuris: Session-Key Management Protocol ๐Ÿฆ‹

okay bestie, this one is RFC 2522, and it's giving "experimental and iconic" ๐Ÿ’…โœจ. The title is Photuris: Session-Key Management Protocol, it's from March 1999, and it's in the Experimental category ๐Ÿงช. Two authors: P. Karn from Qualcomm and W. Simpson from DayDreamer ๐Ÿ‘‘. It's from the Network Working Group. The header doesn't list anything it obsoletes or updates, so it's just doing its own thing ๐ŸŒธ.


Status of this Memo ๐ŸŽ€

ngl this part is kind of a disclaimer, but it matters. This document defines an Experimental Protocol for the Internet community ๐Ÿงช. It is not an Internet standard of any kind ๐Ÿ™…โ€โ™€๏ธ. People are literally asking for discussion and suggestions to make it better ๐Ÿ’–. Distribution of this memo is unlimited ๐Ÿฆ‹.

The legal bit, verbatim so nobody gets confused: Copyright (C) The Internet Society (1999). and Copyright (C) Philip Karn and William Allen Simpson (1994-1999). All Rights Reserved ๐Ÿ”’.

Abstract ๐ŸŒˆ

okay so Photuris is a session-key management protocol built to work with the IP Security Protocols, which are AH and ESP ๐Ÿ”. This document lays out the basic protocol mechanisms, so it's the foundation of the whole thing ๐Ÿงฑโœจ.

Table of Contents ๐Ÿ“š

     1.     Introduction ..........................................    1
        1.1       Terminology .....................................    1
        1.2       Protocol Overview ...............................    3
        1.3       Security Parameters .............................    5
        1.4       LifeTimes .......................................    6
           1.4.1  Exchange LifeTimes ..............................    6
           1.4.2  SPI LifeTimes ...................................    7
        1.5       Random Number Generation ........................    8

     2.     Protocol Details ......................................    9
        2.1       UDP .............................................    9
        2.2       Header Format ...................................   10
        2.3       Variable Precision Integers .....................   11
        2.4       Exchange-Schemes ................................   13
        2.5       Attributes ......................................   13

     3.     Cookie Exchange .......................................   14
           3.0.1  Send Cookie_Request .............................   14
           3.0.2  Receive Cookie_Request ..........................   15
           3.0.3  Send Cookie_Response ............................   15
           3.0.4  Receive Cookie_Response .........................   16
        3.1       Cookie_Request ..................................   17
        3.2       Cookie_Response .................................   18
        3.3       Cookie Generation ...............................   19
           3.3.1  Initiator Cookie ................................   19
           3.3.2  Responder Cookie ................................   20

     4.     Value Exchange ........................................   21
           4.0.1  Send Value_Request ..............................   21
           4.0.2  Receive Value_Request ...........................   22
           4.0.3  Send Value_Response .............................   22
           4.0.4  Receive Value_Response ..........................   23
        4.1       Value_Request ...................................   24
        4.2       Value_Response ..................................   25
        4.3       Offered Attribute List ..........................   26

     5.     Identification Exchange ...............................   28
           5.0.1  Send Identity_Request ...........................   29
           5.0.2  Receive Identity_Request ........................   29
           5.0.3  Send Identity_Response ..........................   30
           5.0.4  Receive Identity_Response .......................   30
        5.1       Identity_Messages ...............................   31
        5.2       Attribute Choices List ..........................   33
        5.3       Shared-Secret ...................................   34
        5.4       Identity Verification ...........................   34
        5.5       Privacy-Key Computation .........................   36
        5.6       Session-Key Computation .........................   37

     6.     SPI Messages ..........................................   38
           6.0.1  Send SPI_Needed .................................   38
           6.0.2  Receive SPI_Needed ..............................   39
           6.0.3  Send SPI_Update .................................   39
           6.0.4  Receive SPI_Update ..............................   39
           6.0.5  Automated SPI_Updates ...........................   40
        6.1       SPI_Needed ......................................   41
        6.2       SPI_Update ......................................   43
           6.2.1  Creation ........................................   44
           6.2.2  Deletion ........................................   45
           6.2.3  Modification ....................................   45
        6.3       Validity Verification ...........................   45

     7.     Error Messages ........................................   46
        7.1       Bad_Cookie ......................................   47
        7.2       Resource_Limit ..................................   47
        7.3       Verification_Failure ............................   48
        7.4       Message_Reject ..................................   49

     8.     Public Value Exchanges ................................   50
        8.1       Modular Exponentiation Groups ...................   50
        8.2       Moduli Selection ................................   50
           8.2.1  Bootstrap Moduli ................................   51
           8.2.2  Learning Moduli .................................   51
        8.3       Generator Selection .............................   51
        8.4       Exponent Selection ..............................   52
        8.5       Defective Exchange Values .......................   53

     9.     Basic Exchange-Schemes ................................   54

     10.    Basic Key-Generation-Function .........................   55
        10.1      MD5 Hash ........................................   55

     11.    Basic Privacy-Method ..................................   55
        11.1      Simple Masking ..................................   55

     12.    Basic Validity-Method .................................   55
        12.1      MD5-IPMAC Check .................................   55

     13.    Basic Attributes ......................................   56
        13.1      Padding .........................................   56
        13.2      AH-Attributes ...................................   57
        13.3      ESP-Attributes ..................................   57
        13.4      MD5-IPMAC .......................................   58
           13.4.1 Symmetric Identification ........................   58
           13.4.2 Authentication ..................................   59
        13.5      Organizational ..................................   60

     APPENDICES ...................................................   61

     A.     Automaton .............................................   61
        A.1       State Transition Table ..........................   62
        A.2       States ..........................................   65
           A.2.1  Initial .........................................   65
           A.2.2  Cookie ..........................................   66
           A.2.3  Value ...........................................   66
           A.2.4  Identity ........................................   66
           A.2.5  Ready ...........................................   66
           A.2.6  Update ..........................................   66

     B.     Use of Identification and Secrets .....................   67
        B.1       Identification ..................................   67
        B.2       Group Identity With Group Secret ................   67
        B.3       Multiple Identities With Group Secrets ..........   68
        B.4       Multiple Identities With Multiple Secrets .......   69

     OPERATIONAL CONSIDERATIONS ...................................   70

     SECURITY CONSIDERATIONS ......................................   70

     HISTORY ......................................................   71

     ACKNOWLEDGEMENTS .............................................   72

     REFERENCES ...................................................   73

     CONTACTS .....................................................   75

     COPYRIGHT ....................................................   76

1. Introduction โœจ

okay so Photuris [Firefly] sets up short-lived session-keys between two parties, and the cute part is that the session-keys never get sent across the Internet ๐Ÿซข๐Ÿ”. These session-keys directly replace the long-lived secret-keys (things like passwords and passphrases) that people have historically set up for security purposes ๐Ÿ™ˆ.

The basic Photuris protocol uses those existing, previously configured secret-keys to identify the parties ๐Ÿชช. The whole point is to speed up deployment and cut down on admin configuration changes, which is literally the dream ๐Ÿ˜ญ๐Ÿ™Œ.

This document is mainly for implementing the Photuris protocol ๐Ÿ› ๏ธ. It doesn't go into service and application interface definitions, but it does mention some basic policy areas that are needed for the protocol mechanisms to be implemented and run properly ๐Ÿ’….

Since the basic Photuris protocol is extensible, expect new data types and new protocol behaviour ๐ŸŒˆ. Implementors are especially warned not to rely on values in the examples being current or complete, since the examples are there to teach, not to be copied ๐Ÿงš๐Ÿ’€.


Part 1 of 14 is done, bestie ๐ŸŽ€. Part 2 is next, and it's where the protocol details get juicy ๐Ÿ“๐Ÿ’–.

1.1. Terminology โœจ

okay so first things first, we need to get the vocab down ๐Ÿ’… In this doc, the key words "MAY", "MUST, "MUST NOT", "optional", "recommended", "SHOULD", and "SHOULD NOT" are read the way [RFC-2119] says. Here's the glossary:

  • byte: an 8-bit quantity, also called "octet" in standardese ๐Ÿ“
  • exchange-value: the publically distributable value used to work out a shared-secret. Here it means a Diffie-Hellman exchange, NOT the public part of a public/private key-pair ๐Ÿฆ‹
  • private-key: a value that stays secret and is part of an asymmetric public/private key-pair ๐Ÿ”
  • public-key: a publically distributable value that's part of an asymmetric public/private key-pair ๐ŸŒธ
  • secret-key: a symmetric key that is NOT publically distributable. Here it's separated from an asymmetric public/private key-pair. An example is a user password ๐Ÿ™ˆ
  • Security Association (SA): a collection of parameters describing the security relationship between two nodes. These include the identities of the parties, the transform (including algorithm and algorithm mode), the key(s) (like a session-key, secret-key, or appropriate public/private key-pair), and maybe other stuff like sensitivity labelling โœจ
  • Security Parameters Index (SPI): a number that points to a particular set of uni-directional attributes used under a Security Association, like transform(s) and session-key(s). The number is relative to the IP Destination, which is the SPI Owner, and it's unique per IP (Next Header) Protocol. So the same value MAY be used by multiple protocols to concurrently indicate different Security Association parameters ๐Ÿ‘‘
  • session-key: a key that the parties independently derive from a shared-secret, used for keying one direction of traffic. This key changes frequently ๐Ÿ”ฅ
  • shared-secret: as used here, the calculated result of the Photuris exchange ๐Ÿ’œ
  • SPI Owner: the party that corresponds to the IP Destination, aka the intended recipient of a protected datagram ๐Ÿงš
  • SPI User: the party that corresponds to the IP Source, aka the sender of a protected datagram ๐ŸŽ€
  • transform: a cryptographic manipulation of a particular set of data. Here it means certain well-specified methods (defined elsewhere). For example, AH-MD5 [RFC-1828] turns an IP datagram into a cryptographic hash, and ESP-DES-CBC [RFC-1829] turns plaintext into ciphertext and back again ๐Ÿฆ‹

Many of these terms are hierarchically related, so here's the family tree:

Security Association (bi-directional)
 - one or more lists of Security Parameters (uni-directional)
  -- one or more Attributes
   --- may have a key
   --- may indicate a transform

Implementors will find details of cryptographic hashing (such as MD5), encryption algorithms and modes (such as DES), digital signatures (such as DSS), and other algorithms in [Schneier95]. ๐Ÿ“š


1.2. Protocol Overview ๐ŸŒˆ

the Photuris protocol is made of a few simple phases, and they're honestly so iconic ๐Ÿ˜ญ

  1. A "Cookie" Exchange guards against simple flooding attacks sent with bogus IP Sources or UDP Ports. Each party passes a "cookie" to the other.

Then the Responder offers a list of supported Exchange-Schemes for calculating a shared-secret.

  1. A Value Exchange establishes a shared-secret between the parties. Each party passes an Exchange-Value to the other, and those values are used to calculate the shared-secret. The Responder stays stateless until a shared-secret has been created.

On top of that, each party offers supported attributes for setting up new Security Parameters.

  1. An Identification Exchange identifies the parties to each other, and verifies the integrity of values sent in phases 1 and 2.

The shared-secret also gives a basis for generating separate session-keys in each direction, which are then used for conventional authentication or encryption. Extra security attributes get exchanged as needed.

This exchange is masked for party privacy protection with a message privacy-key based on the shared-secret. That hides the identities of the parties, hides the Security Parameter attribute values, and improves security for the exchange protocol and security transforms. ๐Ÿซถ

  1. Extra messages may get exchanged to periodically change the session-keys, and to set up new or revised Security Parameters.

These exchanges are also masked for party privacy protection in the same way as above.

Here's the message flow in one diagram. The first three phases (cookie, exchange, and identification) must be carried out in their entirety before any Security Association can be used.

Initiator                            Responder
=========                            =========
Cookie_Request                 ->
                                   <-   Cookie_Response
                                           offer schemes
Value_Request                  ->
   pick scheme
   offer value
   offer attributes
                                   <-   Value_Response
                                           offer value
                                           offer attributes

          [generate shared-secret from exchanged values]


Identity_Request               ->
   make SPI
   pick SPI attribute(s)
   identify self
   authenticate
   make privacy key(s)
   mask/encrypt message
                                   <-   Identity_Response
                                           make SPI
                                           pick SPI attribute(s)
                                           identify self
                                           authenticate
                                           make privacy key(s)
                                           mask/encrypt message

            [make SPI session-keys in each direction]

SPI User                             SPI Owner
========                             =========
SPI_Needed                     ->
   list SPI attribute(s)
   make validity key
   authenticate
   make privacy key(s)
   mask/encrypt message
                                   <-   SPI_Update
                                           make SPI
                                           pick SPI attribute(s)
                                           make SPI session-key(s)
                                           make validity key
                                           authenticate
                                           make privacy key(s)
                                           mask/encrypt message

Either party may initiate an exchange at any time. For example, the Initiator need not be a "caller" in a telephony link. ๐Ÿ“ž

The Initiator is responsible for recovering from all message losses by retransmission. ๐Ÿ”


1.3. Security Parameters ๐Ÿ”‘

a Photuris exchange between two parties gives you a pair of SPI values, one in each direction. Each SPI is used to create separate session-key(s) in each direction. Two keys, one per direction, very clean ๐Ÿ’–

The SPI is assigned by the entity controlling the IP Destination, which is the SPI Owner (receiver). The parties use the combo of IP Destination, IP (Next Header) Protocol, and SPI to tell which Security Association is the correct one. ๐ŸŽฏ

When both parties start Photuris exchanges at the same time, or one party starts more than one, the Initiator Cookies (and UDP Ports) keep those exchanges separate. That means you end up with more than one initial SPI for each Destination. โœจ

To make multiple SPIs with different parameters, the parties may also send SPI_Updates. ๐Ÿฆ‹

There's no requirement that all of these outstanding SPIs get used. The SPI User (sender) picks an appropriate SPI for each datagram transmission. ๐ŸŒธ

Implementation Notes:

The method used for SPI assignment is implementation dependent. The only requirement is that the SPI be unique for the IP Destination and IP (Next Header) Protocol. However, picking a cryptographically random SPI value can help prevent attacks that depend on a predicatable sequence of values. The implementor MUST NOT expect SPI values to have a particular order or range. ๐Ÿ™ˆ

1.4. LifeTimes โณ

the Photuris exchange creates two kinds of state, and each one has its own LifeTimes.

  1. The Exchange LifeTime of the small amount of state tied to the Photuris exchange itself. This state may be viewed as between Internet nodes. ๐ŸŒ
  2. The SPI LifeTimes of the individual SPIs that get set up. This state may be viewed as between users and nodes. ๐Ÿ‘ฏ

The SPI LifeTimes may be shorter or longer than the Exchange LifeTime. These LifeTimes aren't required to be related to each other. ๐Ÿ’…

When an Exchange-Value expires (or gets replaced by a newer value), any unexpired derived SPIs are NOT affected. This matters a lot, because it keeps traffic flowing without interruption during new Photuris exchanges. ๐Ÿ”ฅ

1.4.1. Exchange LifeTimes โฐ

All retained exchange state of both parties has an associated Exchange LifeTime (ELT), and it's subject to periodic expiration. This depends on the physical and logistical security of the machine, and is typically somewhere between 10 minutes and one day (default 30 minutes). ๐Ÿ•ฐ๏ธ

During a Photuris exchange, there's also an Exchange TimeOut (ETO) that limits how long the exchange can take to finish. This timeout includes the packet round trips and the time for finishing the Identification Exchange calculations. The time is bounded by both the maximum calculation delay expected for the processing power of an unknown peer, and the minimum user expectation for results (default 30 seconds). ๐Ÿ™ƒ

These Exchange LifeTimes and TimeOuts are implementation dependent, and they're not disclosed in any Photuris message. The paranoid operator will have a fairly short Exchange LifeTime, but it MUST NOT be less than twice the ETO. ๐Ÿ˜ˆ

To stop Photuris exchanges from syncing up, the implementation SHOULD randomly vary each Exchange LifeTime within twice the range of seconds needed to calculate a new Exchange-Value. For example, if the Responder uses a base ELT of 30 minutes and takes 10 seconds to calculate the new Exchange-Value, the equation might be (in milliseconds):

1790000 + urandom(20000)

The Exchange-Scheme, Exchange-Values, and resulting shared-secret MAY be cached in short-term storage for the Exchange LifeTime. When repetitive Photuris exchanges happen between the same parties, and the Exchange-Values turn out to be unchanged, the previously calculated shared-secret can be used to rapidly generate new session-keys. โšก

1.4.2. SPI LifeTimes ๐Ÿ’–

okay so every SPI gets its own LifeTime, and the SPI owner (aka the receiver) is the one who sets it ๐ŸŽ€ this SPI LifeTime (SPILT) is usually tied to how fast the link is, like somewhere between 2 and 30 minutes, but it MUST NOT be less than thrice the ETO. no shorter, bestie ๐Ÿ™…โ€โ™€๏ธ

the SPI owner can also delete an SPI with an SPI_Update ๐Ÿ—‘๏ธ and once an SPI has expired or been deleted, both parties stop using it. done and dusted โœจ

to stop multiple Photuris exchanges from syncing up with each other (so chaotic ๐Ÿ’€), the implementation SHOULD randomly vary each SPI LifeTime. for example, if the Responder uses a base SPILT of 5 minutes and 30 seconds for the ETO, the equation might look like this (in milliseconds):

285000 + urandom(30000)

the SPI User doesn't have to accept a long LifeTime, though ๐Ÿ™ˆ they might never use an established SPI at all, or they might stop using it whenever they feel like it. not our problem, lol

when the SPI User has more than one unexpired SPI for the same function, a super common move is to pick the one with the greatest remaining LifeTime. but picking randomly from a big pile of SPIs might help defend against traffic analysis, so it's giving strategic ๐Ÿงš

to stop deleted or expired SPIs from coming back from the dead ๐ŸงŸโ€โ™€๏ธ, SPI Owners SHOULD remember those SPIs but mark them as unusable. they keep them that way until the Photuris exchange shared-secret that made them also expires and purges the state tied to it. no resurrection arc allowed ๐Ÿ’…

and if the SPI Owner sees an incoming SPI that has recently expired, but the related exchange state hasn't been purged yet, the implementation MAY accept it ๐Ÿฆ‹ how long that grace window is depends a lot on clock drift and how much packet round trip time wobbles around, so it's left up to each implementation. iykyk ๐Ÿ˜ญ


1.5. Random Number Generation ๐ŸŽฒ

the security of Photuris really depends on how good the secret random numbers are that each party makes. if one party has a bad random number generator, the shared-secret the algorithm produces is cooked ๐Ÿ’€

generating cryptographic-quality random numbers on a regular general-purpose computer with no hardware help is genuinely hard, ngl ๐Ÿ˜ญ the usual approach is to use a cryptographic hash function to "distill" the entropy out of a bunch of semi-random outside events, like the timing of your keystrokes. if you want a deep dive, check out [RFC-1750] ๐Ÿ“š it's a great read.


2. Protocol Details โœจ

the Initiator starts a Photuris exchange in a few different situations:

  • the Initiator has a datagram it wants to send with confidentiality, and it has no current Photuris exchange state with the IP Destination. that datagram gets thrown out, and a Cookie_Request gets sent instead ๐Ÿ—‘๏ธ
  • the Initiator gets the ICMP message [RFC-1812] Destination Unreachable: Communication Administratively Prohibited (Type 3, Code 13), and has no current Photuris exchange state with the ICMP Source.
  • the Initiator gets the ICMP message [RFC-2521] Security Failures: Bad SPI (Type 40, Code 0), that matches current Photuris exchange state with the ICMP Source.
  • the Initiator gets the ICMP message [RFC-2521] Security Failures: Need Authentication (Type 40, Code 4), and has no current Photuris exchange state with the ICMP Source.
  • the Initiator gets the ICMP message [RFC-2521] Security Failures: Need Authorization (Type 40, Code 5), that matches current Photuris exchange state with the ICMP Source.

when the trigger is an ICMP message, you MUST be extra careful that the ICMP message actually contains info matching an IP datagram you already sent. otherwise, attackers could use it to start new Photuris Exchanges over and over, which is a clogging attack ๐Ÿšซ not cute at all.


2.1. UDP ๐Ÿฆ‹

every Photuris message uses the User Datagram Protocol header [RFC-768]. the Initiator sends to UDP Destination Port 468 ๐Ÿ“ฎ

when the Responder replies to the Initiator, it swaps the IP Source and Destination, and it swaps the UDP Source and Destination Ports too ๐Ÿ”„

the UDP checksum MUST be correctly calculated when sent. if a message shows up with a bad UDP checksum, it gets silently discarded ๐Ÿคซ

Implementation Notes:

  • it's expected that installing Photuris will make sure UDP checksum calculations stay enabled on the computer's operating system, and that operators can't turn them off later. locked in ๐Ÿ”’
  • Internet Protocol version 4 [RFC-791] limits the maximum reassembled datagram to 576 bytes.
  • when processing datagrams with variable size values, you have to check the length against the overall datagram length. an invalid size (too long or too short) that makes a sloppy receiver crash could be used as a denial of service attack, so please don't skip this ๐Ÿ’€

2.2. Header Format ๐ŸŒธ

every message kind looks roughly like this, sent left to right in network order (most significant to least significant):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Initiator-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Responder-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Message    |
+-+-+-+-+-+-+-+-+

the Initiator-Cookie is 16 bytes, and so is the Responder-Cookie ๐Ÿช

the Message field is 1 byte, and every message type gets its own unique value. the initial values are assigned like this:

    0  Cookie_Request
    1  Cookie_Response
    2  Value_Request
    3  Value_Response
    4  Identity_Request
    5  Secret_Response (optional)
    6  Secret_Request (optional)
    7  Identity_Response
    8  SPI_Needed
    9  SPI_Update
   10  Bad_Cookie
   11  Resource_Limit
   12  Verification_Failure
   13  Message_Reject

the specific details and differences get spelled out in each individual message, so keep reading ๐Ÿ“–


2.3. Variable Precision Integers ๐Ÿ”ข

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             Size              |             Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

the Size field is 2, 4, or 8 bytes long. it's the number of significant bits used in the Value field, and it's always sent most significant byte first.

when the Size is zero, there's no Value field at all, and there are no significant bits. that means "missing" or "null". don't mix this up with the value zero, which still tells you how many significant bits there are ๐Ÿ™…โ€โ™€๏ธ

when the most significant byte is in the range 0 through 254 (0xfe), the field is 2 bytes. both bytes together show the size of the Value field, which goes from 1 to 65,279 significant bits (in 1 to 8,160 bytes).

when the most significant byte is 255 (0xff), the field is 4 bytes. the remaining 3 bytes get added to 65,280 to show the size of the Value field, which is capped at 16,776,959 significant bits (in 2,097,120 bytes).

when the most significant 2 bytes are 65,535 (0xffff), the field is 8 bytes. the remaining 6 bytes get added to 16,776,960 to show the size of the Value field.

the Value field is 0 or more bytes, always sent most significant byte first.

the bits used are right-justified within byte boundaries, so any unused bits sit in the most significant byte. if there are no unused bits, or the unused bits are zero-filled, the value is an unsigned positive integer ๐ŸŒŸ

if the leading unused bits are one-filled, the number is treated as a two's-complement negative integer. a negative integer always has at least one unused leading sign bit in its most significant byte.

shortened forms SHOULD NOT be used when the Value has leading zero significant bits. the Size SHOULD indicate the correct number of significant bits. be precise, bestie ๐Ÿ’…

Implementation Notes:

  • negative integers aren't required to be supported, but they're included for completeness.
  • no more than 65,279 significant bits are required to be supported. the other ranges are way too long for these UDP messages, but they're included for completeness too.

2.4. Exchange-Schemes ๐Ÿ”

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Scheme             |             Size              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

the Scheme field is 2 bytes, a unique value that identifies the Exchange-Scheme. check the "Basic Exchange-Schemes" for the details ๐Ÿ“‹

the Size field is 2 bytes, ranging from 0 to 65,279. see "Variable Precision Integer" for more.

the Value field is 0 or more bytes. see "Variable Precision Integer" for more.

the Size MUST NOT be assumed to stay constant for a particular Scheme. multiple kinds of the same Scheme with different Sizes MAY be present in any list of schemes.

however, each Scheme and Size combination shows up only once in any list of schemes โœจ


2.5. Attributes ๐ŸŽ€

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Attribute   |    Length     |  Value(s) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

the Attribute field is 1 byte, a unique value that tells you what kind of attribute it is. check the "Basic Attributes" for details ๐Ÿงฉ

when the Attribute value is zero (padding), there's no Length field, and it's always zero.

the Length field is 1 byte, and it's the size of the Value(s) field in bytes. when the Length is zero, there's no Value(s) field at all.

the Value(s) field is 0 or more bytes. see the "Basic Attributes" for details.

the Length MUST NOT be assumed to stay constant for a particular Attribute. multiple kinds of the same Attribute with different Lengths MAY be present in any list of attributes ๐ŸŒˆ


here's how the Cookie Exchange goes between the Initiator and the Responder:

Initiator                            Responder
=========                            =========
Cookie_Request                 ->
                                   <-   Cookie_Response
                                           offer schemes

Okay so the Initiator starts by setting up its local state and cooking up a unique "cookie" ๐Ÿช. The Initiator-Cookie MUST be different in each new Cookie_Request between the same parties. Check "Cookie Generation" for the details ๐Ÿซถ.

  • If any previous exchange between the peer IP nodes has not expired and this party was the Initiator, the Responder-Cookie is set to the most recent Responder-Cookie, and this Counter is set to the matching Counter.
    • Example: a brand new Virtual Private Network (VPN) tunnel is about to be set up with an existing partner. The Counter is the same value from the prior Cookie_Response, the Responder-Cookie stays the same, and a new Initiator-Cookie gets generated. Main character energy ๐ŸŒธ.
  • If the new Cookie_Request responds to a message from a previous exchange where this party was the Responder, the Responder-Cookie is set to the previous Initiator-Cookie, and this Counter is set to zero.
    • Example: a Bad_Cookie message came from the previous Initiator in response to SPI_Needed. The Responder-Cookie gets replaced with the Initiator-Cookie, and a new Initiator-Cookie is generated. This is bookkeeping that helps detect bogus Bad_Cookie messages ๐Ÿ•ต๏ธโ€โ™€๏ธ.
    • Also, this can be used for bi-directional User, Transport, and Process oriented keying. Those mechanisms are outside the scope of this document ๐Ÿ’….
  • Otherwise, the Responder-Cookie and Counter are both set to zero.
    • By default, the Initiator acts the same way it does when all of its previous exchange state has expired. The Responder will send a Resource_Limit when its own exchange state has not expired ๐Ÿ™ˆ.

The Initiator also starts a retransmission timer โฐ. If no valid Cookie_Response shows up before the time limit, the same Cookie_Request gets resent for the remaining number of Retransmissions. The Initiator-Cookie value MUST be the same in each such retransmission to the same IP Destination and UDP Port ๐Ÿ”.

When Retransmissions have been exceeded, and a Resource_Limit message was received during the exchange, the Initiator SHOULD begin the Photuris exchange again by sending a new Cookie_Request with updated values ๐Ÿฆ‹.

When a Cookie_Request arrives, the Responder checks whether it has enough resources to start another Photuris exchange ๐Ÿ‘€.

  • If too many SPI values are already in use for this particular peer, or too many concurrent exchanges are in progress, or some other resource limit has been hit, a Resource_Limit message gets sent ๐Ÿ˜ญ.
  • If any previous exchange started by this particular peer has not exceeded the Exchange TimeOut, and the Responder-Cookie doesn't point to one of those previous exchanges, a Resource_Limit message gets sent ๐Ÿ’€.

Otherwise, the Responder returns a Cookie_Response ๐Ÿ’–.

Note that the Responder doesn't create any additional state at this point ๐Ÿงš.

The IP Source for the Initiator gets checked. If any previous exchange between the peer IP nodes has not expired, the response Counter is set to the most recent exchange Counter plus one, which allows for out of order retransmissions. Otherwise, the response Counter is set to the request Counter plus one ๐Ÿ”ข.

If the new Counter value is zero (modulo 256) because the Counter rolled over, the value gets set to one ๐Ÿ”„.

If the new Counter value matches a previous exchange that this particular peer started and that has not yet exceeded the Exchange TimeOut, the Counter gets incremented again, over and over, until a unique Counter value shows up ๐Ÿ™ƒ.

Nota Bene: No more than 254 concurrent exchanges between the same two peers are supported โš ๏ธ.

The Responder generates a unique cookie. The Responder-Cookie value in each successive response SHOULD be different. Check "Cookie Generation" for details ๐ŸŒˆ.

The Exchange-Schemes available between the peers are listed in the Offered-Schemes ๐Ÿ“œ.

The Initiator checks the Initiator-Cookie and the Offered-Schemes ๐Ÿ”.

  • If the Initiator-Cookie is invalid or expired, the message gets silently discarded ๐Ÿซฅ.
  • If the variable length Offered-Schemes don't match the UDP Length, or every Offered-Scheme is obviously defective and/or not enough for the intended purposes, the message gets silently discarded. The implementation SHOULD log the occurance and notify an operator as appropriate ๐Ÿ“.
  • Once a valid message has been received, later Cookie_Responses with matching Initiator-Cookies also get silently discarded, until a new Cookie_Request is sent ๐Ÿ›‘.

When the message is valid, an Exchange-Scheme gets picked from the list of Offered-Schemes ๐ŸŽฏ.

This Scheme-Choice may affect the next Photuris message sent. By default, the next Photuris message is a Value_Request ๐Ÿ’ซ.

Implementation Notes:

Only the Initiator-Cookie is used to identify the exchange. The Counter and Responder-Cookie will both be different from the Cookie_Request ๐Ÿงฉ.

Various proposals for extensions use the Scheme-Choice to signal a different message sequence. Those mechanisms are outside the scope of this document ๐ŸŒŸ.

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Initiator-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Responder-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Message    |    Counter    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Initiator-Cookie โ€” 16 bytes. A randomized value that identifies the exchange. The value MUST NOT be zero. Check "Cookie Generation" for details ๐ŸŽฒ.
  • Responder-Cookie โ€” 16 bytes. Identifies a specific previous exchange. Copied from a previous Cookie_Response ๐Ÿ”—.
    • When zero, no previous exchange is specified.
    • When non-zero, and the Counter is zero, it contains the Initiator-Cookie of a previous exchange. The specified party is asked to be the Responder in this exchange, so the previous party pairings stay the same ๐Ÿค.
    • When non-zero, and the Counter is also non-zero, it contains the Responder-Cookie of a previous exchange. The specified party is asked to be the Responder in this exchange, so the previous party pairings stay the same ๐Ÿค.
  • Message โ€” 0 ๐Ÿ“จ
  • Counter โ€” 1 byte. Indicates the number of previous exchanges ๐Ÿ”ข.
    • When zero, the Responder-Cookie points to the Initiator of a previous exchange, or no previous exchange is specified.
    • When non-zero, the Responder-Cookie points to the Responder of a previous exchange. This value is set to the Counter from the matching Cookie_Response or from a Resource_Limit.
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Initiator-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Responder-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Message    |    Counter    |  Offered-Schemes ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Initiator-Cookie โ€” 16 bytes. Copied from the Cookie_Request ๐Ÿ“‹.
  • Responder-Cookie โ€” 16 bytes. A randomized value that identifies the exchange. The value MUST NOT be zero. Check "Cookie Generation" for details ๐ŸŽฒ.
  • Message โ€” 1 ๐Ÿ“ฌ.
  • Counter โ€” 1 byte. Indicates the number of the current exchange. Must be greater than zero ๐Ÿ”ข.
  • Offered-Schemes โ€” 4 or more bytes. A list of one or more Exchange-Schemes supported by the Responder, ordered from most to least preferable. Check the "Basic Exchange-Schemes" for details ๐Ÿ“š.
    • Only one Scheme (#2) is required to be supported, and it SHOULD be present in every Offered-Schemes list ๐Ÿซถ.
    • More than one of each kind of Scheme may be offered, but each one is told apart by its Size. The end of the list is marked by the UDP Length ๐Ÿ.

The exact technique a Photuris party uses to generate a cookie depends on the implementation. The method chosen has to meet some basic requirements:

  1. The cookie MUST depend on the specific parties. This stops an attacker from grabbing a cookie using a real IP address and UDP port, then using it to flood the victim with requests from randomly chosen IP addresses or ports ๐Ÿšซ.
  2. It MUST NOT be possible for anyone other than the issuing entity to generate cookies that will be accepted by that entity. This means the issuing entity uses local secret information when it generates and later verifies a cookie. It must not be possible to work out this secret information from any particular cookie ๐Ÿคซ.
  3. The cookie generation and verification methods MUST be fast, to thwart attacks meant to sabotage CPU resources ๐ŸŽ๏ธ.

A recommended technique is to use a cryptographic hashing function (such as MD5) ๐Ÿง.

An incoming cookie can be verified at any time by regenerating it locally from values in the incoming datagram and the local secret random value โœ….

The Initiator secret value that affects its cookie SHOULD change for each new Photuris exchange, and it is then cached internally on a per Responder basis. This gives better synchronization and protection against replay attacks ๐Ÿ›ก๏ธ.

Another option is to cache the cookie instead of the secret value. Incoming cookies can then be compared directly, without the computational cost of regeneration ๐Ÿ’จ.

It is recommended that the cookie be calculated over the secret value, the IP Source and Destination addresses, and the UDP Source and Destination ports ๐ŸŒ.

Implementation Notes:

Although the recommendation includes the UDP Source port, this is very implementation specific. For example, it might not be included when the value is constant ๐Ÿคทโ€โ™€๏ธ.

However, it is important that the implementation protects mutually suspicious users of the same machine from generating the same cookie ๐Ÿ‘‘.

Okay so the Responder's secret can stay the same across lots of different Initiators ๐Ÿซถ, but it SHOULD get changed regularly so its cookies don't live forever. The example they give is about every 60 seconds โฐ.

The Responder-Cookie SHOULD include the Initiator-Cookie. It MUST also include the Counter (the one that comes back in the Cookie_Response). That combo gives you better synchronization and protects you from replay attacks ๐Ÿ›ก๏ธโœจ.

It's recommended that the cookie gets calculated over a bunch of things: the secret value, the IP Source and Destination addresses, the Responder's own UDP Destination port, the Counter, the Initiator-Cookie, and the Offered-Schemes that are currently on offer ๐ŸŽ€.

The cookie is NOT cached per Initiator, because we don't want to save state during the initial Cookie Exchange ๐Ÿ™…โ€โ™€๏ธ. When a Value_Request shows up (more on that later), the Responder just regenerates its cookie to check it ๐Ÿ”.

Once the Value_Response goes out (also later, bestie ๐Ÿ’…), both the Initiator and Responder cookies get cached so the exchange can be identified ๐Ÿฆ‹.

Implementation Notes:

Okay the Initiator-side stuff is very implementation-specific, so don't take this as gospel ๐Ÿ™ˆ.
  • Although the recommendation doesn't include the UDP Source port, this is very implementation specific. It might be successfully included in some variants ๐ŸŒˆ.
  • However, it's important that the UDP Source port NOT be included when you're matching existing Photuris exchanges to figure out the right Counter ๐Ÿšซ.
  • The recommendation includes the Offered-Schemes so you can spot a dynamic change of scheme value between the Cookie_Response and the Value_Response ๐Ÿ‘€.
  • Some mechanism MAY be needed to catch a dynamic change of pre-calculated Responder Exchange-Value between the Value_Response and the Identity_Response ๐Ÿ˜ญ. For example, you could change the secret value so the cookie becomes invalid, or explicitly mark the Photuris exchange state as expired ๐Ÿ’€.

4. Value Exchange โœจ

Here's the vibe check of how it goes down ๐Ÿ’œ:

   Initiator                            Responder
   =========                            =========
   Value_Request                  ->
      pick scheme
      offer value
      offer attributes
                                   <-   Value_Response
                                           offer value
                                           offer attributes

             [generate shared-secret from exchanged values]

4.0.1. Send Value_Request ๐Ÿš€

The Initiator generates an appropriate Exchange-Value for the Scheme-Choice. This Exchange-Value may be pre-calculated and used for multiple Responders ๐Ÿงš.

The IP Destination for the Responder gets examined, and the attributes that are available between the two parties get listed in the Offered-Attributes ๐Ÿ“.

The Initiator also starts a retransmission timer โฑ๏ธ. If no valid Value_Response arrives within the time limit, the same Value_Request gets retransmitted for however many Retransmissions are left ๐Ÿ”.

When the Retransmissions have been exceeded, and a Bad_Cookie or Resource_Limit message was received during the exchange, the Initiator SHOULD begin the Photuris exchange again by sending a new Cookie_Request ๐Ÿ˜คโœจ.

4.0.2. Receive Value_Request ๐Ÿ‘‘

The Responder validates the Responder-Cookie, the Counter, the Scheme-Choice, the Exchange-Value, and the Offered-Attributes ๐Ÿ”.

  • When an invalid or expired Responder-Cookie is detected, a Bad_Cookie message gets sent ๐Ÿ™…โ€โ™€๏ธ.
  • When too many SPI values are already in use for this particular peer, or too many concurrent exchanges are in progress, or some other resource limit is hit, a Resource_Limit message gets sent ๐Ÿšง.
  • When an invalid Scheme-Choice is detected, or the Exchange-Value is obviously defective, or the variable length Offered-Attributes don't match the UDP Length, the message gets silently discarded ๐Ÿซฅ. The implementation SHOULD log the occurance and notify an operator as appropriate ๐Ÿ“ฃ.

When the message is valid, the Responder sets its Exchange timer to the Exchange TimeOut and returns a Value_Response ๐Ÿ’–.

The Responder keeps a copy of the incoming Value_Request cookie pair, along with its Value_Response ๐Ÿ“š. If a duplicate Value_Request shows up, it just resends its previous Value_Response and takes no further action ๐Ÿ˜Œ.

4.0.3. Send Value_Response ๐Ÿ’Œ

The Responder generates an appropriate Exchange-Value for the Scheme-Choice. This Exchange-Value may be pre-calculated and used for multiple Initiators ๐ŸŒธ.

The IP Source for the Initiator gets examined, and the attributes available between the two parties get listed in the Offered-Attributes ๐Ÿฆ‹.

Implementation Notes:

  • At this point, the Responder begins calculating the shared-secret. The calculation runs in parallel to minimize delay โšก.
  • This may take a substantial amount of time. The implementor should ensure that retransmission is not blocked by this calculation ๐Ÿ™. This is not usually a problem, since retransmission timeouts typically exceed calculation time โณ.

4.0.4. Receive Value_Response ๐ŸŽ€

The Initiator validates the pair of Cookies, the Exchange-Value, and the Offered-Attributes ๐Ÿ”Ž.

  • When an invalid or expired cookie is detected, the message is silently discarded ๐Ÿซ .
  • When the Exchange-Value is obviously defective, or the variable length Offered-Attributes don't match the UDP Length, the message gets silently discarded. The implementation SHOULD log the occurance and notify an operator as appropriate ๐Ÿ“ข.
  • Once a valid message has been received, later Value_Responses with both matching cookies are also silently discarded, until a new Cookie_Request is sent ๐Ÿšซ๐Ÿ’….

When the message is valid, the Initiator begins its parallel computation of the shared-secret ๐Ÿงฎ.

When the Initiator finishes the computation, it sends an Identity_Request to the Responder ๐Ÿฅณ.


4.1. Value_Request ๐ŸŒˆ

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Initiator-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Responder-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Message    |    Counter    |         Scheme-Choice         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                   Initiator-Exchange-Value                    ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Initiator-Offered-Attributes ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

Here's the breakdown, bestie ๐Ÿซถ:

  • Initiator-Cookie: 16 bytes. Copied from the Cookie_Response ๐Ÿ“.
  • Responder-Cookie: 16 bytes. Copied from the Cookie_Response ๐Ÿ“.
  • Message: 2.
  • Counter: 1 byte. Copied from the Cookie_Response ๐Ÿ”ข.
  • Scheme-Choice: 2 bytes. A value the Initiator picks from the list of Offered-Schemes in the Cookie_Response ๐Ÿ’œ.
    • Only the Scheme is specified. The Size will match the Initiator-Exchange-Value, and the Value(s) are implicit ๐Ÿคซ.
  • Initiator-Exchange-Value: Variable Precision Integer. The Initiator provides this for calculating a shared-secret between the parties ๐Ÿ”. The Value format is indicated by the Scheme-Choice.
    • The field can be any integral number of bytes in length, as indicated by its Size field. It doesn't require any particular alignment. The 32-bit alignment shown is just for convenience in the illustration ๐ŸŽจ.
  • Initiator-Offered-Attributes: 4 or more bytes. A list of Security Parameter attributes the Initiator supports ๐Ÿงพ. The contents and usage of this list are described further in "Offered Attributes List". The end of the list is indicated by the UDP Length โœจ.

4.2. Value_Response ๐Ÿฆ‹

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Initiator-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Responder-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Message    |                    Reserved                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                   Responder-Exchange-Value                    ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Responder-Offered-Attributes ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

The fields, no cap ๐Ÿ“‹:

  • Initiator-Cookie: 16 bytes. Copied from the Value_Request ๐Ÿ“.
  • Responder-Cookie: 16 bytes. Copied from the Value_Request ๐Ÿ“.
  • Message: 3.
  • Reserved: 3 bytes. This is for future use. It MUST be set to zero when transmitted, and it MUST be ignored when received ๐Ÿ™…โ€โ™€๏ธโœจ.
  • Responder-Exchange-Value: Variable Precision Integer. The Responder provides this for calculating a shared-secret between the parties ๐Ÿ”. The Value format is indicated by the current Scheme-Choice specified in the Value_Request.
    • The field can be any integral number of bytes in length, as indicated by its Size field. It doesn't require any particular alignment. The 32-bit alignment shown is just for convenience in the illustration ๐ŸŽจ.
  • Responder-Offered-Attributes: 4 or more bytes. A list of Security Parameter attributes the Responder supports ๐Ÿงพ. The contents and usage of this list are described further in "Offered Attributes List". The end of the list is indicated by the UDP Length ๐Ÿ‘‘.

4.3. Offered Attribute List ๐Ÿ“‹

okay so this list is basically the menu ๐Ÿ“ of everything one party supports that the other party is allowed to use. The attribute formats are spelled out in the "Basic Attributes" ๐Ÿ’…

The list has two or three sections: Identification-Attributes, Authentication-Attributes, and (optional) Encapsulation-Attributes. Inside each section, attributes go from most to least preferable โœจ

The first section is all about identification methods. An Identity-Choice gets picked from here ๐Ÿซถ

The second section kicks off with "AH-Attributes" (#1). It's for authentication and other operational types ๐Ÿ”

The third section kicks off with "ESP-Attributes" (#2). It covers authentication, compression, encryption, and other operational types ๐Ÿฆ‹ If no Encapsulation-Attributes are offered, the "ESP-Attributes" attribute itself gets left off the list, no drama ๐Ÿ™ˆ

Attribute-Choices are picked from the last two sections ๐Ÿ’œ

Now the big one ๐Ÿ‘‘ Support is required for the "MD5-IPMAC" (#5) attribute for both "Symmetric Identification" and "Authentication", and they SHOULD be present in every Offered-Attributes list.

Implementation notes, because we love a good tip ๐Ÿงš

For example:

"MD5-IPMAC" (Symmetric Identification),
"AH-Attributes",
"MD5-IPMAC" (Authentication).

The offer comes from the prospective SPI User (sender), so the order of preference probably reflects the capabilities and engineering tradeoffs of a particular implementation โญ

However, the critical processing bottlenecks are often on the receiver's side ๐Ÿ˜ญ The SPI Owner (receiver) can show what it needs by choosing a less preferable attribute ๐ŸŒธ

The order may also be affected by operational policy and by the services requested for an application. Those considerations are outside the scope of this document ๐Ÿ“Ž

The list may be split into more sections. These extra sections always come after the ESP-Attributes section, and they look the same as unrecognized attributes ๐ŸŽ€

The authentication, compression, encryption, and identification mechanisms chosen, plus the encapsulation modes (if any), don't have to match in both directions ๐Ÿ”„


5. Identification Exchange ๐Ÿ”

Here's the whole exchange at a glance ๐Ÿ‘€

   Initiator                            Responder
   =========                            =========
   Identity_Request               ->
      make SPI
      pick SPI attribute(s)
      identify self
      authenticate
      make privacy key(s)
      mask/encrypt message
                                   <-   Identity_Response
                                           make SPI
                                           pick SPI attribute(s)
                                           identify self
                                           authenticate
                                           make privacy key(s)
                                           mask/encrypt message

               [make SPI session-keys in each direction]

The messages go in order, but their formats and meanings are identical in each direction. The parties can tell them apart easily by looking at the Message and Identification fields ๐Ÿ’–

Implementation notes ๐Ÿง 

The time the calculation takes can depend on the value of particular bits in the secret values used to generate the shared-secret or the identity verification. To keep anyone from analysing those secret bits by timing the calculation, sending the Identity_Messages SHOULD be delayed until the time expected for the longest calculation. That time differs across processor speeds, algorithms, and variable lengths, so the method for estimating it is implementation dependent ๐Ÿ•ฐ๏ธ

Any authenticated and/or encrypted user datagrams that arrive before identity verification finishes can be put on a queue until this step completes. If verification succeeds, the queue is processed as though those datagrams had arrived after the verification. If verification fails, the queue is thrown away ๐Ÿ—‘๏ธ

5.0.1. Send Identity_Request ๐Ÿ“ค

The Initiator picks an appropriate Identification, the SPI and SPILT, and a set of Attributes for the SPI. It calculates the Verification and masks the message using the Privacy-Method indicated by the current Scheme-Choice ๐ŸŽ€

The Initiator also starts a retransmission timer. If no valid Identity_Response shows up before the time limit, the previous Identity_Request gets resent for the remaining number of Retransmissions ๐Ÿ”

Once the Retransmissions are used up, if a Bad_Cookie message was received during the exchange, the Initiator SHOULD begin the Photuris exchange again by sending a new Cookie_Request ๐Ÿ’Œ

5.0.2. Receive Identity_Request ๐Ÿ“ฅ

The Responder checks the pair of Cookies, the Padding, the Identification, the Verification, and the Attribute-Choices ๐Ÿ”

  • When an invalid or expired cookie is detected, a Bad_Cookie message is sent.
  • After unmasking, if invalid Padding is detected, if the variable length Attribute-Choices don't match the UDP Length, or if an attribute wasn't in the Offered-Attributes, the message is silently discarded ๐Ÿคซ
  • When an invalid Identification is detected, or the message verification fails, a Verification_Failure message is sent.
  • Whenever a problem like this is detected, the Security Association is not established. The implementation SHOULD log the occurance and notify an operator as appropriate ๐Ÿšจ

When the message is valid, the Responder sets its Exchange timer to the Exchange LifeTime (if that hasn't already been done for a previous exchange). Once its parallel computation of the shared-secret is complete, the Responder returns an Identity_Response โฑ๏ธ

The Responder keeps a copy of the incoming Identity_Request values and of its Identity_Response. If a duplicate Identity_Request shows up, it simply resends its previous Identity_Response and takes no further action ๐Ÿ™Œ

5.0.3. Send Identity_Response ๐Ÿ“จ

The Responder picks an appropriate Identification, the SPI and SPILT, and a set of Attributes for the SPI. It calculates the Verification and masks the message using the Privacy-Method indicated by the current Scheme-Choice ๐ŸŽ€

The Responder works out the SPI session-keys in both directions ๐Ÿ”‘

At this point, the Responder starts authenticating and/or encrypting user datagrams ๐Ÿ›ก๏ธ

5.0.4. Receive Identity_Response ๐Ÿ“ฌ

The Initiator checks the pair of Cookies, the Padding, the Identification, the Verification, and the Attribute-Choices ๐Ÿ”

  • When an invalid or expired cookie is detected, the message is silently discarded.
  • After unmasking, if invalid Padding is detected, if the variable length Attribute-Choices don't match the UDP Length, or if an attribute wasn't in the Offered-Attributes, the message is silently discarded ๐Ÿคซ
  • When an invalid Identification is detected, or the message verification fails, a Verification_Failure message is sent.
  • Whenever a problem like this is detected, the Security Association is not established. The implementation SHOULD log the occurance and notify an operator as appropriate ๐Ÿšจ
  • Once a valid message has been received, later Identity_Responses with both matching cookies are also silently discarded, until a new Cookie_Request is sent ๐Ÿšซ

When the message is valid, the Initiator sets its Exchange timer to the Exchange LifeTime (if that hasn't already been done for a previous exchange) โฑ๏ธ

The Initiator works out the SPI session-keys in both directions ๐Ÿ”‘

At this point, the Initiator starts authenticating and/or encrypting user datagrams ๐Ÿฆ‹

5.1. Identity_Messages

Okay so this is the layout for the Identity messages, and it is giving very precise ๐ŸŽ€ Here's the diagram, copied exactly:

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Initiator-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                       Responder-Cookie                        ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |    Message    |                    LifeTime                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                   Security-Parameters-Index                   |
   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
   |        Identity-Choice        |                               |
   + + + + + + + + + + + + + + + + +                               +
   |                                                               |
   ~                        Identification                         ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   ~                         Verification                          ~
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Attribute-Choices ...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                      ... Padding  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Now let's go field by field ๐Ÿ’…

  • Initiator-Cookie: 16 bytes, copied from the Value_Request. ๐Ÿงš
  • Responder-Cookie: 16 bytes, also copied from the Value_Request. ๐Ÿงš
  • Message: 4 (Request) or 7 (Response).
  • LifeTime: 3 bytes. This is the number of seconds left before the indicated SPI expires โณ. When the SPI is zero, this field MUST be filled with a random non-zero value. Yes, MUST, it's not optional bestie ๐Ÿซถ
  • Security-Parameters-Index (SPI): 4 bytes. This is the SPI to be used for incoming communications. When it's zero, that means no SPI is created in this direction ๐Ÿ™ˆ
  • Identity-Choice: 2 or more bytes. An identity attribute gets picked from the list of Offered-Attributes that the peer sent, and it's used to calculate the Verification. It can be any whole number of bytes long (the Length field tells you how long), and it doesn't need any particular alignment. The 16-bit alignment in the diagram is just there to make it easier to picture โœจ
  • Identification: a Variable Precision Integer, or some other format indicated by the Identity-Choice. Check out "Basic Attributes" for the details ๐ŸŒธ It can be any whole number of bytes, no particular alignment needed, and the 32-bit alignment is for the drawing only.
  • Verification: also a Variable Precision Integer, or an alternative format indicated by the Identity-Choice. Its calculation is described in "Identity Verification" ๐Ÿ”ฅ Same deal with the size and alignment, so no stress.
  • Attribute-Choices: 0 or more bytes. When the SPI is non-zero, this is a list of attributes picked from the Offered-Attributes that the peer supports. The details live in "Attribute Choices List" ๐Ÿ’œ The end of the list is marked by the UDP Length after you remove the Padding (UDP Length minus the last Padding value). Main character energy for sure ๐Ÿ‘‘
  • Padding: 8 to 255 bytes. It gets filled up to at least a 128 byte boundary, measured from the start of the message. The number of pad bytes is picked randomly ๐ŸŽฒ

On top of that, if the Privacy-Method from the current Scheme-Choice needs the plaintext to be a multiple of some number of bytes (the block size of a block cipher), this field gets adjusted to whatever size the algorithm wants ๐Ÿ“

Self-Describing-Padding starts with the value 1, and each byte holds its own index. So the last pad byte tells you how many pad bytes to strip off. For example, if the unpadded message is 120 bytes, the padding values might be 1, 2, 3, 4, 5, 6, 7, and 8 โœจ

Everything after the SPI field gets masked using the Privacy-Method from the current Scheme-Choice ๐Ÿ”’ The fields after the SPI are opaque, which basically means their values get set before masking (and optional encryption) and only looked at after unmasking (and optional decryption). No peeking, periodt ๐Ÿ™ˆ


5.2. Attribute Choices List

This list spells out the attributes of the SPI ๐ŸŽ€ The attribute formats are defined in "Basic Attributes".

The list is made of one or two sections: Authentication-Attributes, and/or Encapsulation-Attributes.

When you're sending from the SPI User to the SPI Owner, the attributes get processed in the order they're listed. For example:

"ESP-Attributes",
"Deflate" (Compression),
"XOR" (Encryption),
"DES-CBC" (Encryption),
"XOR" (Encryption),
"AH-Attributes",
"AH-Sequence",
"MD5-IPMAC" (Authentication),

This would give you ESP with compression and triple encryption on the inside ๐Ÿ’…, and then AH authentication with sequence numbers on the outside of the ESP payload. Layers upon layers, it's so iconic ๐Ÿง

The SPI Owner processes the datagram in the reverse order, obviously ๐Ÿ”„

The ordering also affects the order of key generation. Both the SPI Owner and the SPI User generate the keys in the order listed ๐Ÿ”‘

Implementation Notes:

  • When choices are made from the list of Offered-Attributes, it is not required that any Security Association include every kind of offered attribute in any single SPI, and it's not required that a separate SPI be created for every offered attribute either. Lowkey flexible ๐Ÿฆ‹
  • Some kinds of attributes may be included more than once in a single SPI. Which combinations are allowed depends on the implementation and operational policy. Those considerations are outside the scope of this document ๐ŸŒˆ
  • The list may be divided into additional sections. This can only happen when both parties recognize the affected attributes ๐Ÿซถ
  • The authentication, compression, encryption and identification mechanisms chosen, along with the encapsulation modes (if any), need not be the same in both directions. Asymmetry is valid bestie ๐Ÿ’œ

5.3. Shared-Secret

A shared-secret shows up in a bunch of calculations โœจ No matter how it's stored internally, when it gets used in a calculation it has to look like the Value part of a Variable Precision Integer:

  • most significant byte first.
  • bits used are right justified within byte boundaries.
  • any unused bits are in the most significant byte.
  • unused bits are zero filled.

The shared-secret does not include a Size field. Just the value, no extra baggage ๐Ÿงš


5.4. Identity Verification

These messages are authenticated using the Identity-Choice ๐Ÿ” The Verification value gets calculated before masking (and optional encryption), and it gets verified after unmasking (and optional decryption).

The Identity-Choice authentication function gets two input values:

  • the sender (SPI Owner) verification-key,
  • the data to be verified (as a concatenated sequence of bytes).

The output value that comes out is stored in the Verification field ๐Ÿ’–

The Identity-Choice verification data is made up of these concatenated values, in this order:

  • the Initiator Cookie,
  • the Responder Cookie,
  • the Message, LifeTime and SPI fields,
  • the Identity-Choice and Identification,
  • the SPI User Identity Verification (response only),
  • the Attribute-Choices following the Verification field,
  • the Padding,
  • the SPI Owner TBV,
  • the SPI Owner Exchange-Value,
  • the SPI Owner Offered-Attributes,
  • the SPI User TBV,
  • the SPI User Exchange-Value,
  • the SPI User Offered-Attributes,
  • the Responder Offered-Schemes.

The TBV (Three Byte Value) is made of the Counter and Scheme-Choice fields from the Value_Request, or the Reserved field from the Value_Response. It sits right before the matching Exchange-Value ๐ŸŽ€

Heads up, the order of the Exchange-Value and Offered-Attributes fields is different in each direction ๐Ÿ‘€ The Identification and SPI fields are also likely to differ in each direction. And the SPI User Identity Verification (from the Identity_Request) only shows up in the Identity_Response, so don't go looking for it anywhere else ๐Ÿ™ˆ

If the verification fails, the users get notified and a Verification_Failure message is sent, and no SPI gets added. On success, normal operation starts with the authentication and/or encryption of user datagrams ๐Ÿฆ‹

Implementation Notes:

  • This is separate from any authentication method specified for the SPI ๐Ÿ’…
  • The exact details of the Identification and verification-key used in the Verification calculation depend on the Identity-Choice, as described in "Basic Attributes" ๐ŸŒธ
  • Each party may want to keep their own trusted databases, like the Pretty Good Privacy (PGP) web of trust, and accept only the identities found there. If the Identification isn't found in either an internal or external database, you get the same Verification_Failure message as you would if the verification computation itself failed ๐Ÿšซ
  • The Exchange-Value data includes both the Size and Value fields. The Offered-Attributes and Attribute-Choices data includes the Attribute, Length and Value fields ๐Ÿง

5.5. Privacy-Key Computation ๐Ÿ”

Okay bestie, Identification Exchange messages get masked using whatever Privacy-Method the current Scheme-Choice points to ๐Ÿ’…. Masking starts at the next field after the SPI and keeps going until the end of the data the UDP Length says is there, Padding included โœจ.

The Scheme-Choice's Key-Generation-Function makes a special privacy-key for each message ๐Ÿ—๏ธ. It runs over these values, all concatenated together:

  • the SPI Owner Exchange-Value,
  • the SPI User Exchange-Value,
  • the Initiator Cookie,
  • the Responder Cookie,
  • the Message, LifeTime and SPI (or Reserved) fields,
  • the computed shared-secret.

The Exchange-Value fields come in a different order each direction, and the Message, LifeTime and SPI fields are different too, so the privacy-key is usually different in each direction ๐Ÿฆ‹.

If you need more keying-bits than one run of the function gives you, you duplicate the trailing shared-secret and run it again. So the first iteration has one trailing copy, the second has two, and so on ๐ŸŒˆ.

Implementation Notes:

  • This is distinct from any encryption method specified for the SPI.
  • The length of the Padding, and other details, are dependent on the Privacy-Method. See the "Basic Privacy-Method" list for details.
  • To avoid keeping the Exchange-Values in memory after the initial verification, it is often possible to pre-compute the function over the initial bytes of the concatenated data values for each direction, and append the trailing copies of the shared-secret.
  • The Exchange-Value data includes both the Size and Value fields.

5.6. Session-Key Computation ๐Ÿ—๏ธ

Each SPI has one or more session-keys, and they're generated based on the SPI's attributes. Check the "Basic Attributes" for the details ๐Ÿ“.

The Scheme-Choice's Key-Generation-Function makes the SPI session-key for that particular attribute. It runs over these concatenated values:

  • the Initiator Cookie,
  • the Responder Cookie,
  • the SPI Owner generation-key,
  • the SPI User generation-key,
  • the message Verification field,
  • the computed shared-secret.

The generation-keys are ordered differently in each direction, and the Verification field is likely different too, so the session-key will usually be different in each direction ๐Ÿ’œ.

Same deal as before: if you need more keying-bits than one iteration gives, you duplicate the trailing shared-secret and recalculate. First iteration gets one trailing copy, second gets two, and so forth โœจ.

Implementation Notes:

  • This is distinct from any privacy-key generated for the Photuris exchange. Different initialization data is used, and iterations are maintained separately.
  • The exact details of the Verification field and generation-keys that are included in the session-key calculation are dependent on the Identity-Choices, as described in the "Basic Attributes".
  • To avoid keeping the generation-keys in memory after the initial verification, it is often possible to pre-compute the function over the initial bytes of the concatenated data values for each direction, and append the trailing copies of the shared-secret.
  • When both authentication and encryption attributes are used for the same SPI, there may be multiple session-keys associated with the same SPI. These session-keys are generated in the order of the Attribute-Choices list.

6. SPI Messages ๐Ÿ“ฌ

Here's the vibe check, visually ๐Ÿ‘€:

   SPI User                             SPI Owner
   ========                             =========
   SPI_Needed                     ->
      list SPI attribute(s)
      make validity key
      authenticate
      make privacy key(s)
      mask/encrypt message
                                   <-   SPI_Update
                                           make SPI
                                           pick SPI attribute(s)
                                           make SPI session-key(s)
                                           make validity key
                                           authenticate
                                           make privacy key(s)
                                           mask/encrypt message

The exchange isn't tied to who the Initiator and Responder are. Either party can send one of these messages at any time, and the parties can easily tell them apart ๐Ÿซถ.

6.0.1. Send SPI_Needed ๐Ÿ™‹โ€โ™€๏ธ

At any time after the Identification Exchange is done, either party can send SPI_Needed. It gets sent when a prospective SPI User needs particular attributes for a datagram (like confidentiality), and no current SPI has them ๐Ÿ”ฅ.

The prospective SPI User picks from the attributes both parties have already offered, calculates the Verification, and masks the message using the Privacy-Method the current Scheme-Choice indicates ๐Ÿ’….

6.0.2. Receive SPI_Needed ๐Ÿ‘‚

The potential SPI Owner checks the pair of Cookies, the Padding, the Verification, and the Attributes-Needed ๐Ÿง.

  • When an invalid/expired cookie shows up, a Bad_Cookie message is sent.
  • When too many SPI values are already in use for this particular peer, or some other resource limit gets hit, a Resource_Limit message is sent.
  • After unmasking, if the Padding is invalid, the variable length Attributes-Needed don't match the UDP Length, or an attribute wasn't in the Offered-Attributes, the message is silently discarded ๐Ÿ™ˆ.
  • When the message verification fails, a Verification_Failure message is sent.
  • Whenever one of these problems is detected, the SPI isn't established. The implementation SHOULD log the occurance, and notify an operator as appropriate ๐Ÿ“‹.

When the message is valid, the party SHOULD send SPI_Update with the necessary attributes โœจ.

If an existing SPI already has those attributes, that SPI comes back in the SPI_Update with the remaining SPILT ๐Ÿ“.

6.0.3. Send SPI_Update ๐Ÿ“ค

At any time after the Identification Exchange is done, either party can send SPI_Update. This one only has effect in one direction: from the SPI Owner to the SPI User ๐Ÿฆ‹.

The SPI Owner picks the SPI and SPILT, a set of Attributes for the SPI, calculates the Verification, and masks the message using the Privacy-Method the current Scheme-Choice indicates ๐ŸŽ€.

6.0.4. Receive SPI_Update ๐Ÿ“ฅ

The prospective SPI User checks the pair of Cookies, the Padding, the Verification, and the Attributes-Needed ๐Ÿ”.

  • When an invalid/expired cookie is detected, a Bad_Cookie message is sent.
  • After unmasking, if the Padding is invalid, the variable length Attribute-Choices don't match the UDP Length, an attribute wasn't in the Offered-Attributes, or the message modifies an existing SPI, the message is silently discarded ๐Ÿ’€.
  • When the message verification fails, a Verification_Failure message is sent.
  • Whenever one of these problems is detected, the SPI isn't established. The implementation SHOULD log the occurance, and notify an operator as appropriate ๐Ÿ“‹.

When the message is valid, what happens next depends on the value of the LifeTime field, as described later ๐Ÿงš.

6.0.5. Automated SPI_Updates โฐ

Each SPI needs replacing under a few different circumstances ๐ŸŒธ:

  • the volume of data processed (inhibiting probability cryptanalysis),
  • exhaustion of available anti-replay Sequence Numbers,
  • and expiration of the LifeTime.

Generally, this gets decided when a datagram comes in. If the transform specific processing finds that refreshment is needed, an automated SPI_Update gets triggered ๐Ÿ‘‘.

Automated SPI_Updates also allow rapid SPI refreshment for high bandwidth applications in a high delay environment. The update messages flow in the opposite direction from the primary traffic, which saves bandwidth and avoids service interruption ๐Ÿš€.

When creating each SPI, the implementation MAY optionally set an Update TimeOut (UTO). By default, it's set to half the value of the LifeTime (SPILT/2). This time is highly dynamic and adjustable, so an automated SPI_Update can go out long before the transform specific processing kicks in ๐Ÿ˜ญ. If no new Photuris exchange happens within the time limit, and the current exchange state hasn't expired, an automated SPI_Update is sent ๐Ÿ’–.

6.1. SPI_Needed ๐Ÿฆ‹

Okay bestie, the SPI_Needed message is basically the "hey, I need an SPI, can you hook me up?" ๐Ÿ’… Here's how the bytes are laid out:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Initiator-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Responder-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Message    |                  Reserved-LT                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Reserved-SPI                          |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|                                                               |
~                         Verification                          ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Attributes-Needed ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                      ... Padding  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Here's the breakdown, lowkey the most important part ๐Ÿซถ

  • Initiator-Cookie: 16 bytes. Copied from the Value_Request. ๐ŸŒธ
  • Responder-Cookie: 16 bytes. Copied from the Value_Request. ๐ŸŒธ
  • Message: 8 โœจ
  • Reserved-LT: 3 bytes. This one's for future use. It MUST be filled with a random non-zero value when transmitted, and it MUST be ignored when received. ๐Ÿ™ˆ
  • Reserved-SPI: 4 bytes. Also for future use. It MUST be set to zero when transmitted, and it MUST be ignored when received. ๐Ÿ’€
  • Verification: A Variable Precision Integer, or whatever other format the current Scheme-Choice says to use. The calculation is described in "Validity Verification". The field can be any integral number of bytes long and doesn't need any particular alignment. The 32-bit alignment in the diagram is just there so it's easier to picture. ๐Ÿงš
  • Attributes-Needed: 4 or more bytes. It's a list of two or more attributes, picked from the Offered-Attributes the peer supports. The contents and usage are the same as what we covered in "Attribute Choices List". The end of the list is found by taking the UDP Length and subtracting the last Padding value (UDP Length - last Padding value). ๐Ÿ‘‘
  • Padding: 8 or more bytes. The message is padded the same way as Identification Exchange messages. ๐ŸŽ€

Everything after the SPI field gets masked using the Privacy-Method from the current Scheme-Choice. The fields after the SPI are opaque, meaning their values get set before masking (and optional encryption), and only looked at after unmasking (and optional decryption). Very mysterious, very iconic ๐Ÿ”ฎ

6.2. SPI_Update ๐Ÿ’œ

The SPI_Update is the message where you create, delete, or otherwise poke at your SPIs. Okay, look at this layout:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Initiator-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Responder-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Message    |                    LifeTime                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Security-Parameters-Index                   |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|                                                               |
~                         Verification                          ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Attribute-Choices ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                      ... Padding  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The fields, explained:

  • Initiator-Cookie: 16 bytes. Copied from the Value_Request. ๐ŸŒธ
  • Responder-Cookie: 16 bytes. Copied from the Value_Request. ๐ŸŒธ
  • Message: 9 ๐Ÿ“
  • LifeTime: 3 bytes. This is the number of seconds left before the indicated SPI expires. A value of zero means the indicated SPI gets deleted. ๐Ÿ’€
  • Security-Parameters-Index (SPI): 4 bytes. This is the SPI to be used for incoming communications. It can be a brand new SPI value (for creation) or an existing one (for deletion). The value zero triggers special processing. ๐Ÿ”ฅ
  • Verification: Same deal as before: a Variable Precision Integer, or the format the current Scheme-Choice indicates. The calculation is in "Validity Verification", and it can be any integral number of bytes with no particular alignment required. ๐Ÿงš
  • Attribute-Choices: 0 or more bytes. When the SPI and SPILT are non-zero, this is a list of attributes picked from the Offered-Attributes the peer supports. Same rules as "Attribute Choices List", and the end is found by UDP Length minus the last Padding value (UDP Length - last Padding value). ๐Ÿ‘‘
  • Padding: 8 or more bytes. Padded just like Identification Exchange messages. ๐ŸŽ€

Same masking rule applies: everything after the SPI field gets masked with the Privacy-Method from the current Scheme-Choice, and the fields after the SPI are opaque (set before masking and optional encryption, examined only after unmasking and optional decryption). ๐Ÿฆ‹

6.2.1. Creation ๐ŸŒฑ

When the LifeTime is non-zero and the SPI is also non-zero, the SPI_Update can be used to create a new SPI. If the SPI is zero, the SPI_Update is silently discarded. Bye bye ๐Ÿ‘‹

The new session-keys get calculated the same way as the Identity_Messages. Since the SPI value is always different from any previous SPI during the Exchange LifeTime of the shared-secret, the resulting session-keys will necessarily be different from all the others used in the same direction. Main character energy, no duplicates allowed โœจ

No retransmission timer is necessary. Success is indicated by the peer using the new SPI, so you'll just know when it works ๐Ÿ’–

If all the creation attempts fail, the peer will eventually find that all its existing SPIs have expired, and it'll start the Photuris exchange over by sending a new Cookie_Request. When it makes sense, this Cookie_Request MAY include a Responder-Cookie to keep the previous party pairings. Ooh, a little callback to the old friend group ๐Ÿซ‚

6.2.2. Deletion ๐Ÿ—‘๏ธ

When the LifeTime is zero, the SPI_Update can be used to delete one single existing SPI. When the SPI is also zero, the SPI_Update deletes all existing SPIs related to this Security Association and marks the Photuris exchange state as expired. This is especially useful when the application that needed them terminates. Clean house, babe ๐Ÿงน

No retransmission timer is necessary. This message is advisory, and its job is to cut down on the number of ICMP Security Failures messages. Less noise in the group chat ๐Ÿคซ

If any deletion attempts fail, the peer will find out the deleted SPIs are invalid through the normal ICMP Security Failures messages, and it'll start a Photuris exchange by sending a new Cookie_Request. The drama always finds its way back ๐Ÿ’…

6.2.3. Modification ๐Ÿšซ

The SPI_Update can't be used to modify existing SPIs. That means no lengthening an existing SPI LifeTime, no resurrecting an expired SPI, and no adding or removing an Attribute-Choice. Absolutely not, we don't do retcons here ๐Ÿ™…โ€โ™€๏ธ

If one of these otherwise valid messages comes in, it gets silently discarded. ๐Ÿ™ˆ

6.3. Validity Verification ๐Ÿ”

These messages are authenticated using the Validity-Method indicated by the current Scheme-Choice. The Verification value is calculated before masking (and optional encryption), and verified after unmasking (and optional decryption). The vibe check happens at the end, not the beginning ๐Ÿง

The Validity-Method authentication function gets fed two input values:

  • the sender (SPI Owner) verification-key,
  • the data to be verified (as a concatenated sequence of bytes).

The output value gets stored in the Verification field. ๐ŸŽ€

The Validity-Method verification data is made up of these concatenated values, in this order:

  • the Initiator Cookie,
  • the Responder Cookie,
  • the Message, LifeTime and SPI (or Reserved) fields,
  • the SPI Owner Identity Verification,
  • the SPI User Identity Verification,
  • the Attribute-Choices following the Verification field,
  • the Padding.

The Identity Verification fields (from the Identity_Messages) are in a different order in each direction, and the Message, LifeTime and SPI fields are also likely to differ in each direction. So no copy-pasting, the vibes have to match both ways ๐Ÿชž

If the verification fails, the users get notified and a Verification_Failure message gets sent, without adding or deleting any SPIs. Yikes. If it succeeds, normal operation begins with the authentication and/or encryption of user datagrams. Green light, let's gooo ๐Ÿšฆ

Implementation Notes:

This is distinct from any authentication method specified for the SPI. Two different security checks, don't mix them up ๐Ÿซฃ

The Identity Verification data includes both the Size and Value fields. The Attribute-Choices data includes the Attribute, Length and Value fields. Be thorough with your fields, bestie ๐Ÿ“


7. Error Messages ๐Ÿšจ

These messages get issued in response to Photuris state loss or other problems. A message only has effect in one direction, and no retransmission timer is necessary. Okay, quick and dirty ๐Ÿƒโ€โ™€๏ธ

These messages are not masked. Nothing to hide here ๐Ÿ˜Œ

The receiver checks the Cookies for validity. Special care MUST be taken that the Cookie pair in the Error Message actually matches a pair currently in use, and that the protocol is currently in a state where such an Error Message might be expected. If not, these messages could give an attacker an opportunity for a denial of service attack, so please be careful ๐Ÿ˜ญ Invalid messages are silently discarded. No mercy for the sus ones ๐Ÿ’€

okay so the 33 byte message follows the "Header Format" layout, and there are no extra fields ๐Ÿ’…

  • Initiator-Cookie: 16 bytes. Copied from the offending message.
  • Responder-Cookie: 16 bytes. Copied from the offending message.
  • Message: 10

this error gets sent when a Value_Request, Identity_Request, SPI_Needed, or SPI_Update arrives and the receiver-specific Cookie is invalid or the exchange state has expired ๐Ÿ™ˆ

during the Photuris exchange, getting this one has no immediate effect on the protocol phases. later, once Retransmissions have been exceeded and this error has been received, the Initiator SHOULD begin the Photuris exchange again by sending a new Cookie_Request with the Responder-Cookie and Counter updated appropriately โœจ

when this error comes back in response to SPI_Needed, the exchange state SHOULD NOT be marked as expired, but the party SHOULD initiate a Photuris exchange by sending a new Cookie_Request ๐Ÿฆ‹

when it comes back in response to SPI_Update, the exchange state SHOULD NOT be marked as expired, and no further action is taken. a new exchange gets started later, when the peer needs it to send authenticated and/or encrypted data ๐Ÿ’œ

existing SPIs are not deleted. they expire normally and get purged sometime later ๐Ÿงš

7.2. Resource_Limit ๐ŸŒธ

the 34 byte message follows the "Cookie_Request" format, and there are no additional fields ๐ŸŽ€

  • Initiator-Cookie: 16 bytes. Copied from the offending message.
  • Responder-Cookie: 16 bytes. Copied from the offending message.
    • special processing is applied to a Cookie_Request. when the offending message's Responder-Cookie and Counter were both zero, and an existing exchange has not yet been purged, this field is replaced with the Responder-Cookie from the existing exchange ๐Ÿ‘‘
  • Message: 11
  • Counter: 1 byte. Copied from the offending message.
    • when zero, the Responder-Cookie indicates the Initiator of a previous exchange, or no previous exchange is specified
    • when non-zero, the Responder-Cookie indicates the Responder to a previous exchange. this value is set to the Counter from the corresponding Cookie_Response

this error gets sent when a Cookie_Request, Value_Request, or SPI_Needed arrives and too many SPI values are already in use for that peer, or some other Photuris resource is unavailable ๐Ÿ˜ญ

during the Photuris exchange, when this error comes back in response to a Cookie_Request or Value_Request, the implementation SHOULD double the retransmission timeout (as usual) before sending another Cookie_Request or Value_Request. otherwise it has no immediate effect on the protocol phases. later, once Retransmissions have been exceeded and this error has been received, the Initiator SHOULD begin the Photuris exchange again by sending a new Cookie_Request with the Responder-Cookie and Counter updated appropriately ๐Ÿ”ฅ

when this error comes back in response to SPI_Needed, the implementation SHOULD NOT send another SPI_Needed until one of the existing SPIs associated with this exchange is deleted or has expired ๐Ÿซถ

7.3. Verification_Failure ๐ŸŒˆ

the 33 byte message follows the "Header Format" layout, and there are no additional fields ๐Ÿ“

  • Initiator-Cookie: 16 bytes. Copied from the offending message.
  • Responder-Cookie: 16 bytes. Copied from the offending message.
  • Message: 12

this error gets sent when an Identity_Message, SPI_Needed, or SPI_Update arrives and verification fails ๐Ÿ™…โ€โ™€๏ธ

when it's received, the implementation SHOULD log the occurance and notify an operator as appropriate. however, receiving it has no effect on the operation of the protocol ๐Ÿฆ‹

7.4. Message_Reject ๐Ÿ’–

here's the layout, bestie ๐Ÿ‘‡

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Initiator-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
~                       Responder-Cookie                        ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    Message    |  Bad-Message  |             Offset            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • Initiator-Cookie: 16 bytes. Copied from the offending message.
  • Responder-Cookie: 16 bytes. Copied from the offending message.
  • Message: 13
  • Bad-Message: 1 byte. Indicates the Message number of the offending message.
  • Offset: 2 bytes. The number of bytes from the beginning of the offending message where the unrecognized field starts. The minimum value is 32.

this error gets sent when an optional Message type is received that isn't supported, or when an optional format of a supported Message isn't recognized ๐Ÿงš

when it's received, the implementation SHOULD log the occurance and notify an operator as appropriate. however, receiving it has no effect on the operation of the protocol โœจ


8. Public Value Exchanges ๐Ÿฆ‹

okay this part is giving math class but make it iconic ๐Ÿ’… Photuris is based in principle on public-key cryptography, specifically Diffie-Hellman key exchange. swapping public D-H Exchange-Values that are based on private-secret values gives both parties a mutual shared-secret ๐Ÿ”ฅ that shared-secret can be used on its own, or to generate a series of session-keys for authenticating and encrypting later traffic ๐Ÿ‘‘

this doc assumes you already know the Diffie-Hellman public-key algorithm. a good description can be found in [Schneier95] ๐Ÿ“š

8.1. Modular Exponentiation Groups ๐ŸŒธ

the original Diffie-Hellman technique [DH76] specified modular exponentiation. a public-value is made by taking a generator (g), raising it to a private-secret exponent (x), and reducing modulo a prime (p) ๐ŸŽ€

(g**x) mod p.

when these public-values get exchanged, the parties can work out a shared-secret value between themselves ๐Ÿ’œ

(g**xy) mod p.

the generator (g) and modulus (p) are set up by the Scheme-Choice (check the "Basic Exchange-Schemes" for the details). they're offered in the Cookie_Response, and one pair gets picked in the Value_Request ๐Ÿ“

the private exponents (x) and (y) stay secret with the parties. only the public-value result of the modular exponentiation with (x) or (y) gets sent as the Initiator and Responder Exchange-Value ๐Ÿ™ˆ

these public-values are represented in single Variable Precision Integers. the Size of these Exchange-Values will match the Size of the modulus (p) ๐ŸŒˆ

8.2. Moduli Selection ๐Ÿซถ

each implementation proposes one or more moduli in its Offered-Schemes. every implementation MUST support up to 1024-bit moduli ๐Ÿ‘‘

for any particular Photuris node, these moduli don't need to change for significant periods of time, likely days or weeks. a background process can periodically generate new moduli ๐Ÿฆ‹

for 512-bit moduli, current estimates would provide 64 (pessimistic) bit-equivalents of cryptographic strength. for 1024-bit moduli, current estimates would range from 80 (pessimistic) through 98 (optimistic) bit-equivalents of cryptographic strength.

these estimates are used when picking moduli that suit the desired Security Parameter attributes ๐Ÿ’–

8.2.1. Bootstrap Moduli ๐Ÿงš

each implementation is likely to use a fixed modulus during its bootstrap, until it can generate another modulus in the background. since the bootstrap modulus gets widely distributed and reused whenever the machine reinitializes, it SHOULD be a "safe" prime (p = 2q+1) to give the greatest long-term protection ๐Ÿ”ฅ

implementors are encouraged to generate their own bootstrap moduli, and to change bootstrap moduli in successive implementation releases โœจ

8.2.2. Learning Moduli ๐Ÿ’œ

as Photuris exchanges get initiated, new moduli will be learned from the Responder Offered-Schemes. the Initiator MAY cache these moduli for its own use ๐Ÿ“

before offering any learned modulus, the implementation MUST perform at least one iteration of probable primality verification. this way, many processors can run verification in parallel as moduli get passed around ๐ŸŒธ

when primality verification failures are found, the failed moduli SHOULD be retained for some (implementation dependent) period of time, so they don't get re-learned and re-tested after subsequent exchanges ๐Ÿ™ˆ

8.3. Generator Selection ๐ŸŽ€

the generator (g) should be chosen so the private-secret exponents generate all possible public-values, evenly spread across the range of the modulus (p), without cycling through a smaller subset. a generator like that is called a "primitive root" (which is trivial to find when p is "safe") ๐ŸŒˆ

only one generator (2) is required to be supported ๐Ÿฆ‹

Implementation Notes:

one useful technique is to pick the generator first, then limit the modulus selection sieve to primes that work with that generator ๐Ÿ’…

2   when p (mod 24) = 11.
3   when p (mod 12) = 5.
5   when p (mod 10) = 3 or 7.

the required generator (2) boosts multiplication efficiency. it's still usable even when it isn't a primitive root, since it still covers half of the space of possible residues ๐Ÿ‘‘

8.4. Exponent Selection ๐Ÿซถ

each implementation generates a separate random private-secret exponent for each different modulus. then a D-H Exchange-Value gets calculated for the given modulus, generator, and exponent ๐Ÿ’–

this specification recommends that the exponent length be at least twice the desired cryptographic strength of the longest session-key needed by the strongest offered-attribute ๐Ÿงš

based on the estimates in "Moduli Selection" (above):

for 512-bit moduli, exponent lengths of 128 bits (or more) are recommended. for 1024-bit moduli, exponent lengths of 160 to 256 bits (or more) are recommended.

even though the same exponent and Exchange-Value can be used with several parties whenever the same modulus and generator are used, the exponent SHOULD be changed at random intervals. a background process can periodically destroy the old values, generate a new random private-secret exponent, and recalculate the Exchange-Value ๐Ÿ”ฅ

Implementation Notes:

the size of the exponent is entirely implementation dependent, is unknown to the other party, and can be easily changed ๐Ÿ“

since these operations involve several time-consuming modular exponentiations, moving them to the "background" substantially improves the apparent execution speed of the Photuris protocol โœจ it also reduces CPU loading enough to let a single public/private key-pair be used in several closely spaced Photuris executions, when creating Security Associations with several different nodes over a short period of time ๐ŸŒธ

other pre-computation suggestions are described in [BGMW93, LL94, Rooij94] ๐ŸŒˆ

8.5. Defective Exchange Values ๐Ÿซฃ

okay so some exponents are literally not secret at all ๐Ÿ˜ญ the exponent 0 gives you Exchange-Value 1, and the exponent 1 gives you Exchange-Value g ๐Ÿ’€ small exponents are super visible too, so they SHOULD be avoided whenever:

g**x < p

depending on how the moduli is structured, certain exponents can be used for sub-group confinement attacks ๐Ÿ‘€ for "safe" primes (p = 2q+1), the sneaky ones are p-1 and (p-1)/2, which generate Exchange-Values 1 and p-1 respectively. yikes ๐Ÿ™ˆ

when an implementation picks a random exponent, it checks the resulting Exchange-Value ๐Ÿ” if that value is represented in less than half the number of significant bits in the modulus, then a new random exponent MUST be chosen ๐Ÿ™…โ€โ™€๏ธ

For 512-bit moduli, Exchange-Values of 2**256 or greater are required.

For 1024-bit moduli, Exchange-Values of 2**512 or greater are required.

in addition, if the resulting Exchange-Value is p-1, then a new random exponent MUST be chosen too โœจ

upon receipt of an Exchange-Value that fails to meet the requirements, the Value Exchange message is silently discarded ๐Ÿคซ

Implementation Notes:

avoidance of small exponents can be assured by setting at least one bit in the most significant half of the exponent ๐Ÿง 


9. Basic Exchange-Schemes ๐Ÿฆ‹

initial values are assigned as follows:

  • (0) Reserved.
  • (1) Reserved.
  • (2) Implementation Required. Any modulus (p) with a recommended generator (g) of 2. When the Exchange-Scheme Size is non-zero, the modulus is contained in the Exchange-Scheme Value field in the list of Offered-Schemes.

an Exchange-Scheme Size of zero is invalid ๐Ÿšซ

Key-Generation-Function     "MD5 Hash"
Privacy-Method              "Simple Masking"
Validity-Method             "MD5-IPMAC Check"

this combo of features requires a modulus with at least 64-bits of cryptographic strength ๐Ÿ’ช

  • (3) Exchange-Schemes 3 to 255 are intended for future well-known published schemes ๐Ÿ”ฎ
  • (256) Exchange-Schemes 256 to 32767 are intended for vendor-specific unpublished schemes. Implementors wishing a number MUST request the number from the authors ๐Ÿ“ฉ
  • (32768) Exchange-Schemes 32768 to 65535 are available for cooperating parties to indicate private schemes, regardless of vendor implementation. these numbers are not reserved, and are subject to duplication ๐Ÿ™ƒ other criteria, such as the IP Source and Destination of the Cookie_Request, are used to differentiate the particular Exchange-Schemes available ๐Ÿงญ

10. Basic Key-Generation-Function ๐Ÿ”‘

10.1. MD5 Hash

MD5 [RFC-1321] is used as a pseudo-random-function for generating the key(s) ๐ŸŽ€ the key(s) begin with the most significant bits of the hash, and MD5 is iterated as needed to generate the requisite length of key material ๐Ÿ”

when an individual key does not use all 128-bits of the last hash, any remaining unused (least significant) bits of the last hash are discarded ๐Ÿ—‘๏ธ when combined with other uses of key generation for the same purpose, the next key will begin with a new hash iteration ๐ŸŒธ


11. Basic Privacy-Method ๐Ÿ™ˆ

11.1. Simple Masking

as described in "Privacy-Key Computation", sufficient privacy-key material is generated to match the message length, beginning with the next field after the SPI, and including the Padding ๐Ÿงฉ the message is masked by XOR with the privacy-key ๐Ÿซถ


12. Basic Validity-Method โœ…

12.1. MD5-IPMAC Check

as described in "Validity Verification", the Verification field value is the MD5 [RFC-1321] hash over the concatenation of:

MD5( key, keyfill, data, datafill, key, md5fill )

where the key is the computed verification-key ๐Ÿ—๏ธ

the keyfill and datafill use the same pad-with-length technique defined for md5fill ๐ŸŽ€ this padding and length is implicit, and does not appear in the datagram ๐Ÿซฅ

the resulting Verification field is a 128-bit Variable Precision Integer (18 bytes including Size) ๐Ÿ’œ when used in calculations, the Verification data includes both the Size and Value fields ๐Ÿงฎ


13. Basic Attributes ๐ŸŽ€

Implementors wishing a number MUST request the number from the authors ๐Ÿ“ฉ initial values are assigned as follows:

 Use    Type
  -       0* padding
  -       1* AH-Attributes
  -       2+ ESP-Attributes
 AEI      5* MD5-IPMAC
 AEIX   255+ Organizational

 A      AH Attribute-Choice
  E     ESP Attribute-Choice
   I    Identity-Choice
    X   dependent on list location
     +  feature must be recognized even when not supported
     *  feature must be supported (mandatory)

other attributes are specified in companion documents ๐Ÿ“š

13.1. Padding

+-+-+-+-+-+-+-+-+
|   Attribute   |
+-+-+-+-+-+-+-+-+


Attribute        0

each attribute may have value fields that are multiple bytes ๐Ÿง to facilitate processing efficiency, these fields are aligned on integral modulo 8 byte (64-bit) boundaries ๐Ÿ“

padding is accomplished by insertion of 1 to 7 Attribute 0 padding bytes before the attribute that needs alignment ๐Ÿชž

no padding is used after the final attribute in a list ๐Ÿ™…โ€โ™€๏ธ

13.2. AH-Attributes

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Attribute   |    Length     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Attribute        1

Length           0

when a list of Attributes is specified, this Attribute begins the section of the list which applies to the Authentication Header (AH) ๐Ÿ›ก๏ธ

13.3. ESP-Attributes

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Attribute   |    Length     |  PayloadType  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Attribute        2

Length           1

PayloadType is 1 byte ๐ŸŽŸ๏ธ it indicates the contents of the ESP Transform Data field, using the IP Next Header (Protocol) value. up-to-date values of the IP Next Header (Protocol) are specified in the most recent "Assigned Numbers" [RFC-1700] ๐Ÿ“–

for example, when encrypting an entire IP datagram, this field will contain the value 4, indicating IP-in-IP encapsulation ๐ŸŽ

when a list of Attributes is specified, this Attribute begins the section of the list which applies to the Encapsulating Security Payload (ESP) ๐Ÿ”

when listed as an Offered-Attribute, the PayloadType is set to 255 ๐ŸŒˆ

when selected as an Attribute-Choice, the PayloadType is set to the actual value to be used โœจ

13.4. MD5-IPMAC

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Attribute   |    Length     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Attribute        5

Length           0

13.4.1. Symmetric Identification

when selected as an Identity-Choice, the immediately following Identification field contains an unstructured Variable Precision Integer ๐Ÿชช valid Identifications and symmetric secret-keys are preconfigured by the parties ๐Ÿค

there is no required format or content for the Identification value ๐Ÿซง the value may be a number or string of any kind. see "Use of Identification and Secrets" for details ๐Ÿ‘€

the symmetric secret-key (as specified) is selected based on the contents of the Identification field ๐Ÿ”‘ all implementations MUST support at least 62 bytes ๐Ÿ™Œ the selected symmetric secret-key SHOULD provide at least 64-bits of cryptographic strength ๐Ÿ’ช

as described in "Identity Verification", the Verification field value is the MD5 [RFC-1321] hash over the concatenation of:

MD5( key, keyfill, data, datafill, key, md5fill )

where the key is the computed verification-key ๐Ÿ—๏ธ

the keyfill and datafill use the same pad-with-length technique defined for md5fill ๐ŸŽ€ this padding and length is implicit, and does not appear in the datagram ๐Ÿซฅ

the resulting Verification field is a 128-bit Variable Precision Integer (18 bytes including Size) ๐Ÿ’œ when used in calculations, the Verification data includes both the Size and Value fields ๐Ÿงฎ

for both "Identity Verification" and "Validity Verification", the verification-key is the MD5 [RFC-1321] hash of the following concatenated values:

  • the symmetric secret-key,
  • the computed shared-secret.

for "Session-Key Computation", the symmetric secret-key is used directly as the generation-key ๐ŸŒŠ

regardless of the internal representation of the symmetric secret-key, when used in calculations it is in the same form as the Value part of a Variable Precision Integer ๐Ÿง 

  • most significant byte first.
  • bits used are right justified within byte boundaries.
  • any unused bits are in the most significant byte.
  • unused bits are zero filled.

the symmetric secret-key does not include a Size field ๐Ÿ™ƒ

13.4.2. Authentication

may be selected as an AH or ESP Attribute-Choice, pursuant to [RFC-1828] et sequitur ๐Ÿ’… the selected Exchange-Scheme SHOULD provide at least 64-bits of cryptographic strength ๐Ÿ”ฅ

as described in "Session-Key Computation", the most significant 384-bits (48 bytes) of the Key-Generation-Function iterations are used for the key ๐Ÿ—๏ธ

Profile:

when negotiated with Photuris, the transform differs slightly from [RFC-1828] ๐Ÿฆ‹

the form of the authenticated message is:

MD5( key, keyfill, datagram, datafill, key, md5fill )

where the key is the SPI session-key ๐Ÿ”

the additional datafill protects against the (impractical) attack described in [PO96] ๐Ÿ›ก๏ธ the keyfill and datafill use the same pad-with-length technique defined for md5fill. this padding and length is implicit, and does not appear in the datagram ๐Ÿซถ

13.5. Organizational

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Attribute   |    Length     |              OUI
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       ...      |     Kind      |  Value(s) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Attribute        255

Length           >= 4

when the Length is four, no Value(s) field is present ๐ŸŒธ

  • OUI: 3 bytes. The vendor's Organizationally Unique Identifier, assigned by IEEE 802 or IANA (see [RFC-1700] for contact details). The bits within the byte are in canonical order, and the most significant byte is transmitted first ๐Ÿงพ
  • Kind: 1 byte. Indicates a sub-type for the OUI. There is no standardization for this field. Each OUI implements its own values ๐ŸŽจ
  • Value(s): 0 or more bytes. The details are implementation specific ๐Ÿงฉ

some implementors might not need nor want to publish their proprietary algorithms and attributes ๐Ÿคซ this OUI mechanism is available to specify these without encumbering the authors with proprietary number requests ๐Ÿ’–

A. Automaton โœจ

okay so this appendix is an example automaton that shows how the protocol moves around ๐Ÿ’… it's incomplete and non-deterministic, bestie, because a lot of the Good/Bad semantic calls are policy-based or just too messy to put in a table ๐Ÿ™ˆ if this example ever disagrees with the text, the text wins, no cap ๐Ÿ‘‘

The finite-state automaton is built out of events, actions and state transitions ๐Ÿฆ‹ events are things like outside commands (a timer expiring) and datagrams showing up from a peer, and actions are things like starting timers and sending datagrams to the peer ๐Ÿงš

Events

DU13 = Communication Administratively Prohibited
SF0  = Bad SPI
SF4  = Need Authentication
SF5  = Need Authorization
WC   = Want Confidentiality

RCQ+ = Receive Cookie_Request (Good)
RCQ- = Receive Cookie_Request (Bad)
RCR+ = Receive Cookie_Response (Good)
RCR- = Receive Cookie_Response (Bad)

RVQ+ = Receive Value_Request (Good)
RVQ- = Receive Value_Request (Bad)
RVR+ = Receive Value_Response (Good)
RVR- = Receive Value_Response (Bad)

RIQ+ = Receive Identity_Request (Good)
RIQ- = Receive Identity_Request (Bad)
RIR+ = Receive Identity_Response (Good)
RIR- = Receive Identity_Response (Bad)

RUN+ = Receive SPI_Needed (Good)
RUN- = Receive SPI_Needed (Bad)
RUM+ = Receive SPI_Update (Good)
RUM- = Receive SPI_Update (Bad)

RBC  = Receive Bad Cookie
RRL  = Receive Resource Limit
RVF  = Receive Verification Failure
RMR  = Receive Message Reject

TO+  = Timeout with counter > 0
TO-  = Timeout with counter expired
UTO  = Update TimeOut
XTO  = Exchange TimeOut

Actions

scq  = Send Cookie_Request
scr  = Send Cookie_Response

svq  = Send Value_Request
svr  = Send Value_Response

siq  = Send Identity_Request
sir  = Send Identity_Response

sum  = Send SPI_Update

se*  = Send error message (see text)
sbc  = Send Bad Cookie
srl  = Send Resource Limit
svf  = Send Verification Failure

brto = Backoff Retransmission TimeOut
buto = Backoff Update TimeOut
rto  = Set Retransmission TimeOut
uto  = Set Update TimeOut
xto  = Set Exchange TimeOut

log  = log operator message

A.1. State Transition Table

states go across the top and events go down the side ๐ŸŽ€ each cell is written as action/new-state, multiple actions are separated by commas (and can wrap onto the next line if they need the space), and the order of those actions is up to the implementer ๐Ÿ’– a letter after a state means there's an explanatory footnote, and a dash (-) means that transition is illegal ๐Ÿ™…โ€โ™€๏ธ

Initiator

      |    0         1         2         3         4
      | Initial    Cookie  CookieBad   Value    ValueBad
------+--------------------------------------------------
 DU13 |rto,scq/1 rto,scq/1 rto,scq/1     3         4
 SF0  |rto,scq/1     1         2         3         4
 SF4  |rto,scq/1     1         2         3         4
 SF5  |rto,scq/1     1         2         3         4
 WC   |rto,scq/1     1         2         3         4
      |
 RCR+ |    -     rto,svq/3 rto,svq/3     3         4
 RCR- |    0         1         2         3         4
 RVR+ |    -         -         -     rto,siq/5 rto,siq/5
 RVR- |    0         1         2         3         4
 RIR+ |    -         -         -         -         -
 RIR- |    0         1         2         3         4
      |
 RUN+ |    -         -         -         -         -
 RUN- |  sbc/0     sbc/1     sbc/2     sbc/3     sbc/4
 RUM+ |    -         -         -         -         -
 RUM- |  sbc/0     sbc/1     sbc/2     sbc/3     sbc/4
      |
 RBC  |    -         -         -         4         4
 RRL  |    -       brto/2    brto/2    brto/4    brto/4
 RVF  |    -         -         -         -         -
 RMR  |    -         -         -         -         -
      |
  TO+ |    -       scq/1     scq/2     svq/3     svq/4
  TO- |    -         0       scq/1       0       scq/1
 UTO  |    -         -         -         -         -
 XTO  |    -         0         0         0         0

Initiator

      |    5         6         8
      |Identity IdentityBad  Update
------+-----------------------------
 DU13 |    5         6         8
 SF0  |    5         6     rto,scq/1
 SF4  |    5         6     rto,scq/1
 SF5  |    5         6     rto,scq/1
 WC   |    5         6       sun/8
      |
 RCR+ |    5         6         8
 RCR- |    5         6         8
 RVR+ |    5         6         8
 RVR- |    5         6         8
 RIR+ |  uto/8     uto/8       8
 RIR- |  svf/5     svf/6       8
      |
 RUN+ |    -         -       sum/8
 RUN- |  sbc/5     sbc/6     se*/8
 RUM+ |    -         -         8
 RUM- |  sbc/5     sbc/6     se*/8
      |
 RBC  |    6         6     rto,scq/1
 RRL  |    5         6       buto/8
 RVF  |  log/5     log/6     log/8
 RMR  |  log/5     log/6     log/8
      |
  TO+ |  sim/5     sim/6       -
  TO- |    0       scq/1       -
 UTO  |    -         -       sum/8
 XTO  |    0         0         0

Responder

      |    0         7         8
      | Initial    Ready     Update
------+-----------------------------
 WC   |    -         7       sun/8
      |
 RCQ+ |  scr/0     scr/7     scr/8
 RCQ- |  srl/0     srl/7     srl/8
 RVQ+ |xto,svr/7   svr/7     svr/8
 RVQ- |  sbc/0     sbc/7     sbc/8
 RIQ+ |    -     uto,sir/8   sir/8
 RIQ- |  sbc/0     se*/7     se*/8
      |
 RUN+ |    -         -       sum/8
 RUN- |  sbc/0     sbc/7     se*/8
 RUM+ |    -         -         8
 RUM- |  sbc/0     sbc/7     se*/8
      |
 RBC  |    -         7     rto,scq/1
 RRL  |    -         -       buto/8
 RVF  |    -         -       log/8
 RMR  |    -         -       log/8
      |
 UTO  |    -         -       sum/8
 XTO  |    -         0         0

A.2. States

here's a closer look at each automaton state ๐ŸŒธ

the "Bad" version of a state just means the Bad_Cookie or Resource_Limit message has been received ๐Ÿ™ˆ

A.2.1. Initial

the Initial state is fictional, bestie, because there isn't really a state between the two parties yet ๐Ÿงš

in the Cookie state, the Initiator has sent a Cookie_Request and is waiting on a Cookie_Response ๐Ÿ“ both the Restart and Exchange timers are running

note that the Responder doesn't have a Cookie state at all ๐Ÿ’œ

A.2.3. Value

in the Value state, the Initiator has sent its Exchange-Value and is waiting for an Identity_Message โœจ both the Restart and Exchange timers are running

A.2.4. Identity

in the Identity state, the Initiator has sent an Identity_Request and is waiting for an Identity_Response to come back ๐Ÿฆ‹ both the Restart and Exchange timers are running

A.2.5. Ready

in the Ready state, the Responder has sent its Exchange-Value and is waiting for an Identity_Message ๐ŸŽ€ only the Exchange timer is running here

A.2.6. Update

in the Update state, each party has finished the Photuris exchange and is unilaterally updating expiring SPIs until the Exchange LifeTime runs out ๐ŸŒˆ both the Update and Exchange timers are running

B. Use of Identification and Secrets

okay this part is the lowkey most important bit for setting things up ๐Ÿ” implementing the base protocol means supporting operator configuration of participant identities and their symmetric secret-keys ๐Ÿ’…

the Identification and Secret fields don't have to be readable strings ๐Ÿซถ on top of the simple quoted-string config, an implementation MUST allow configuration of an arbitrary stream of bytes โœจ

B.1. Identification

usually the Identification is a user name, a site name, a Fully Qualified Domain Name, or an email address with a user name and a domain name in it ๐Ÿ’– examples include:

user
node.site.
user@node.site.
rcmd@node.site.
"Mundane Name" <user@node.site>

there's no requirement that the domain name match any of the particular IP addresses the parties are using ๐Ÿ™ƒ

B.2. Group Identity With Group Secret

a simple setup could use one Identity and one Secret, handed out to everyone in the trusted group ๐ŸŽ€ this might make sense between routers under one administration that form a Virtual Private Network over the Internet ๐ŸŒ

Nota Bene: the passwords in these examples don't meet the "MD5-IPMAC Symmetric Identification" recommendation for at least 64-bits of cryptographic strength ๐Ÿ˜ญ

the administrator configures each router with the same username and password:

identity local "Tiny VPN 1995 November" "abracadabra"
identity remote "Tiny VPN 1995 November" "abracadabra"

when the Initiator sends its Identity_Request, the SPI Owner Identification field is "Tiny VPN 1995 November" and the SPI Owner secret-key is "abracadabra" ๐Ÿ“

when the Responder sends its Identity_Response, the SPI Owner Identification field is "Tiny VPN 1995 November" and the SPI Owner secret-key is "abracadabra" ๐Ÿ’œ the SPI User Identification is "Tiny VPN 1995 November" (taken from the request), and the SPI User secret-key is "abracadabra" ๐Ÿงš

now here's the iconic part ๐Ÿ‘‘ even if the implementations have really bad random number generation and both parties end up with the same random numbers at every step, with this totally identical config, adding the SPI User Verification field to the response calculation is highly likely to produce a different Verification value (see "Identity Verification") ๐Ÿ”ฅ and those different Verification values change the SPI session-keys, which are highly likely to differ in each direction (see "Session-Key Computation") ๐Ÿ’…โœจ

B.3. Multiple Identities With Group Secrets

a more robust setup could give every party its own Identity and Secret, distributed to the participants in the trusted group ๐Ÿ›ก๏ธ this might be a good fit for authenticated firewall traversal ๐ŸŒธ

an administrator has one or more networks and a bunch of mobile users ๐Ÿฆ‹ it's desirable to restrict access to authorized external users ๐Ÿ™…โ€โ™€๏ธ the example boundary router is 10.0.0.1 ๐Ÿงš

the administrator gives each user a different username and password, plus a group username and password for the router ๐ŸŽ€

the administrator configures (in part):

identity local "199511@router.site" "FalDaRah"
identity remote "Happy_Wanderer@router.site" "FalDaRee"

each mobile user adds commands to tunnel and authenticate ๐Ÿ’–

route addprivate 10.0.0.0/8 tunnel 10.0.0.1
secure 10.0.0.1 authenticate-only
identity local "Happy_Wanderer@router.site" "FalDaRee"
identity remote "199511@router.site" "FalDaRah"
identity remote "199512@router.site" "FalDaHaHaHaHaHaHa"

when the mobile Initiator sends its Identity_Request, the SPI Owner Identification field is "Happy_Wanderer@router.site" and the SPI Owner secret-key is "FalDaRee" ๐ŸŒˆ

when the firewall Responder sends its Identity_Response, the SPI Owner Identification field is "199511@router.site" and the SPI Owner secret-key is "FalDaRah" โญ the SPI User Identification field is "Happy_Wanderer@router.site" (taken from the request), and the SPI User secret-key is "FalDaRee" ๐Ÿซถ

in this example, the mobile user is already set up for a monthly password changeover, where the router might identify itself as "199512@router.site" ๐Ÿฅนโœจ

B.4. Multiple Identities With Multiple Secrets

Okay, bestie, so greater security might be achieved by setting up a pair of secrets between each party ๐Ÿ”โœจ One secret handles the initial contact with any member of the group, and a second one is used between specific parties. If one secret (or one pair) gets compromised, no other member of the group is affected ๐Ÿ›ก๏ธ This setup might be a good fit between the routers forming a boundary between cooperating Virtual Private Networks, where each side sets local policy for each VPN member's access ๐ŸŒ๐Ÿ’…

One administrator configures:

   identity local "Apple" "all for one"
   identity local "Apple-Baker" "Apple to Baker" "Baker"
   identity remote "Baker" "one for all"
   identity remote "Baker-Apple" "Baker to Apple"

Another configures:

   identity local "Baker" "one for all"
   identity local "Baker-Apple" "Baker to Apple" "Apple"
   identity remote "Apple" "all for one"
   identity remote "Apple-Baker" "Apple to Baker"

When the Initiator sends its Identity_Request, the SPI Owner Identification field is "Apple" and the SPI Owner secret-key is "all for one" ๐ŸŽ๐Ÿ”‘

When the Responder sends its Identity_Response, it finds that the special pairing exists for "Apple" (in this example, that's shown by a third field) ๐Ÿ‘€ So the SPI Owner Identification field is "Baker-Apple" and the SPI Owner secret-key is "Baker to Apple". The SPI User Identification is "Apple" (taken from the request), and the SPI User secret-key is "all for one" ๐Ÿ’–


Operational Considerations โœจ

Okay, so the specification only gives you a few configurable parameters, and the defaults should handle most situations ๐Ÿงš

  • Retransmissions
    • Default: 3.
  • Initial Retransmission TimeOut (IRTO)
    • Default: 5 seconds.
  • Exchange TimeOut (ETO)
    • Default: 30 seconds. Minimum: Retransmissions * IRTO.
  • Exchange LifeTime (ELT)
    • Default: 30 minutes. Minimum: 2 * ETO.
  • SPI LifeTime (SPILT)
    • Default: 5 minutes. Minimum: 3 * ETO.

Each party configures a list of known identities and symmetric secret-keys ๐Ÿ—๏ธ

On top of that, each party configures local policy that decides what access (if any) gets granted to the holder of a particular identity ๐Ÿ’โ€โ™€๏ธ For example, a party might allow anonymous FTP but prohibit Telnet ๐Ÿ™…โ€โ™€๏ธ Those considerations are outside the scope of this document ๐Ÿ“


Security Considerations ๐Ÿ”

Photuris was built on currently available tools by experienced network protocol designers who are into cryptography, rather than by cryptographers who are into network protocols ๐Ÿค“ This specification is meant to be readily implementable without needing an extensive background in cryptology ๐Ÿ’œ

So only minimal background cryptologic discussion and rationale is included in this document ๐Ÿ“š Some review has come from the general cryptologic community, but it's expected that design decisions and tradeoffs will be thoroughly analysed in later dissertations and debated for many years to come ๐Ÿฟ

The cryptologic details live in separate documents that can be updated more easily and quickly with new analysis ๐Ÿฆ‹


History ๐ŸŒˆ

The initial specification of Photuris, now called version 1 (December 1994 to March 1995), was based on a short list of design requirements and some simple experimental code by Phil Karn ๐Ÿงช Only one modular exponentiation form was used, with a single byte index of pre-specified group parameters. The transform attributes were selected during the public value exchange. Party privacy was protected in the identification signature exchange with standard ESP transforms ๐ŸŽ€

Then it got submitted for review to the IP Security Working Group, and a large number of features were demanded ๐Ÿ˜ญ A mere 254 future group choices weren't deemed enough, so the field was expanded to two bytes (and renamed schemes), and then expanded again to carry variable parameters. The transform attributes were made variable length to accomodate optional parameters. Every other possible parameter was made negotiable. Some participants couldn't switch modes on the UDP sockets to use standard ESP transforms for only some messages, so party privacy got integrated into the protocol. The message headers were reorganized, and selection of transform attributes was delayed until the identification exchange. An additional update message phase was added ๐Ÿซ 

Version 2 (July 1995 to December 1995) reached specification stability in November 1995 ๐ŸŽ‰ That happened by moving most parameters into separate documents for later discussion and leaving only a few mandatory features in the base specification. Within a month, multiple interoperable implementations were produced ๐Ÿ™Œ

Unfortunately, in a fit of demagoguery, the IP Security Working Group decided in a straw poll to remove party privacy protection, and the Working Group chair ended the meeting without allowing further discussion ๐Ÿ’€ Because the identification exchange messages needed privacy to function correctly, the messages were reorganized again. Party privacy and other optional schemes were split into a separate document ๐Ÿ™ƒ

The implementors set up a separate discussion group. Version 3 (April 1996 to June 1997) enjoyed a long stretch of specification stability and multiple implementations on half a dozen platforms ๐Ÿ“

Meanwhile, the IP Security Working Group developed a competing specification with large numbers of negotiable parameters. Also, the PPP Extensions Working Group deployed link security transforms ๐Ÿ‘€

Version 4 (July 1997 onward) tries to keep a semblance of interface compatibility with these other efforts โœจ Minor changes are specified in transform padding format and key generation. More than one value is permitted per scheme, which gives greater latitude in choice for future extensions ๐ŸŒธ The opportunity was also taken to return party privacy to the base document, and to make small semantic changes in automated updates and error recovery. All ESP transform attributes were moved to separate documents, to (hopefully) avoid future incompatible changes to the base document ๐Ÿคž


Acknowledgements ๐Ÿซถ

Thou shalt make no law restricting the size of integers that may be multiplied together, nor the number of times that an integer may be multiplied by itself, nor the modulus by which an integer may be reduced. [Prime Commandment]

Phil Karn was principally responsible for the design of the protocol phases, especially the "cookie" anti-clogging defense ๐Ÿช He also developed the initial testing implementation and provided much of the design rationale text (now removed to a separate document) ๐Ÿ‘‘

William Simpson was responsible for the packet formats and attributes, additional message types, and editing and formatting. All such mistakes are his responsibility ๐Ÿ™ˆ

This protocol was later discovered to have many elements in common with the Station-To-Station authentication protocol [DOW92] ๐Ÿคฏ

Angelos Keromytis developed the first completely independent implementation (circa October 1995). He also suggested the cookie exchange rate limitation counter ๐Ÿ”ฅ

Paul C van Oorschot suggested signing both the public exponents and the shared-secret, to provide an authentication-only version of identity verification. He also provided text regarding moduli, generator, and exponent selection (now removed to a separate document) ๐Ÿ’œ

Hilarie Orman suggested adding secret "nonces" to session-key generation for asymmetric public/private-key identity methods (now removed to a separate document), and provided extensive review of the protocol details ๐Ÿง

Bart Preneel and Paul C van Oorschot in [PO96] recommended padding between the data and trailing key when hashing for authentication ๐ŸŒท

Niels Provos developed another independent implementation (circa May 1997), ported to AIX, Linux, OpenBSD, and Solaris. He also made suggestions regarding automated update, and listing multiple moduli per scheme ๐Ÿง

Bill Sommerfeld suggested including the authentication symmetric secret-keys in the session-key generation, and using the Cookie values on successive exchanges to provide bi-directional user-oriented keying (now removed to a separate document) ๐Ÿ”‘

Oliver Spatscheck developed the second independent implementation (circa December 1995) for the Xkernel ๐ŸŽฏ

International interoperability testing between early implementors inspired many of the implementation notes herein, and led to numerous refinements in the semantics of the protocol messages ๐ŸŒ

Randall Atkinson, Steven Bellovin, Wataru Hamada, James Hughes, Brian LaMacchia, Cheryl Madson, Lewis McCarthy, Perry Metzger, Bob Quinn, Ron Rivest, Rich Schroeppel, and Norman Shulman provided useful critiques of earlier versions of this document ๐Ÿ’–

Special thanks to the Center for Information Technology Integration (CITI) for providing computing resources ๐Ÿ™โœจ

References โœจ

Okay bestie, here are all the sources this RFC leans on, the whole crew, no cap ๐Ÿ“š

  • [BGMW93] E. Brickell, D. Gordon, K. McCurley, and D. Wilson, "Fast Exponentiation with Precomputation (Extended Abstract)", Advances in Cryptology -- Eurocrypt '92, Lecture Notes in Computer Science 658 (1993), Springer-Verlag, 200-207.
    • Also U.S. Patent #5,299,262, E.F. Brickell, D.M. Gordon, K.S. McCurley, "Method for exponentiating in cryptographic systems", 29 Mar 1994. ๐Ÿ’œ
  • [DH76] Diffie, W., and Hellman, H.E., "New Directions in Cryptography", IEEE Transactions on Information Theory, v IT-22 n 6 pp 644-654, November 1976. ๐Ÿ‘‘
  • [DOW92] Whitfield Diffie, Paul C van Oorshot, and Michael J Wiener, "Authentication and Authenticated Key Exchanges", Designs, Codes and Cryptography, v 2 pp 107-125, Kluwer Academic Publishers, 1992. ๐Ÿฆ‹
  • [Firefly] "Photuris" is the latin name for the firefly. "Firefly" is in turn the name for the USA National Security Administration's (classified) key exchange protocol for the STU-III secure telephone. Informed speculation has it that Firefly is based on very similar design principles. ๐Ÿงš ngl this one is giving spy movie
  • [LL94] Lim, C.H., Lee, P.J., "More flexible exponentiation with precomputation", Advances in Cryptology -- Crypto '94, Lecture Notes in Computer Science 839 (1994), Springer-Verlag, pages 95-107. ๐ŸŒธ
  • [Prime Commandment] A derivation of an apocryphal quote from the usenet list sci.crypt. ๐Ÿ™ˆ
  • [PO96] Bart Preneel, and Paul C van Oorshot, "On the security of two MAC algorithms", Advances in Cryptology -- Eurocrypt '96, Lecture Notes in Computer Science 1070 (May 1996), Springer-Verlag, pages 19-32. ๐Ÿ“
  • [RFC-768] Postel, J., "User Datagram Protocol", STD 6, USC/Information Sciences Institute, August 1980. ๐ŸŽ€
  • [RFC-791] Postel, J., "Internet Protocol", STD 5, USC/Information Sciences Institute, September 1981. ๐ŸŒˆ
  • [RFC-1321] Rivest, R., "The MD5 Message-Digest Algorithm", MIT Laboratory for Computer Science, April 1992. โญ
  • [RFC-1700] Reynolds, J., and Postel, J., "Assigned Numbers", STD 2, USC/Information Sciences Institute, October 1994. ๐Ÿ’…
  • [RFC-1812] Baker, F., Editor, "Requirements for IP Version 4 Routers", Cisco Systems, June 1995. ๐Ÿซถ
  • [RFC-1828] Metzger, P., Simpson, W., "IP Authentication using Keyed MD5", July 1995. ๐Ÿ”ฅ
  • [RFC-1829] Karn, P., Metzger, P., Simpson, W., "The ESP DES-CBC Transform", July 1995. ๐Ÿ’–
  • [RFC-2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, Harvard University, March 1997. ๐Ÿงš
  • [RFC-2521] Karn, P., and Simpson, W., "ICMP Security Failures Messages", March 1999. ๐Ÿ’€
  • [Rooij94] P. de Rooij, "Efficient exponentiation using precomputation and vector addition chains", Advances in Cryptology -- Eurocrypt '94, Lecture Notes in Computer Science, Springer-Verlag, pages 403-415. โœจ
  • [Schneier95] Schneier, B., "Applied Cryptography Second Edition", John Wiley & Sons, New York, NY, 1995. ISBN 0-471-12845-7. ๐Ÿ“–

Contacts ๐Ÿ’Œ

Comments about this document should be discussed on the photuris@adk.gr mailing list. That's the group chat for all the RFC feedback, bestie ๐Ÿซถ

Questions about this document can also be directed to:

  • Phil Karn
    • Qualcomm, Inc.
    • 6455 Lusk Blvd.
    • San Diego, California 92121-2779
    • karn@qualcomm.com
    • karn@unix.ka9q.ampr.org (preferred) ๐Ÿ’œ
  • William Allen Simpson
    • DayDreamer
    • Computer Systems Consulting Services
    • 1384 Fontaine
    • Madison Heights, Michigan 48071
    • wsimpson@UMich.edu
    • wsimpson@GreenDragon.com (preferred) ๐Ÿฆ‹

Copyright (C) The Internet Society (1999). Copyright (C) Philip Karn and William Allen Simpson (1994-1999). All Rights Reserved.

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards (in which case the procedures for copyrights defined in the Internet Standards process must be followed), or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING (BUT NOT LIMITED TO) ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐ŸŒธ
๐Ÿ“ฆ where this page comes from