RFC 2522
Photuris: Session-Key Management Protocol
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 ๐ฆ.
Copyright Notice ๐
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 ๐ญ
- 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.
- 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.
- 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. ๐ซถ
- 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.
- The Exchange LifeTime of the small amount of state tied to the Photuris exchange itself. This state may be viewed as between Internet nodes. ๐
- 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 ๐
3. Cookie Exchange ๐ช
here's how the Cookie Exchange goes between the Initiator and the Responder:
Initiator Responder
========= =========
Cookie_Request ->
<- Cookie_Response
offer schemes
3.0.1. Send Cookie_Request โจ
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 ๐ฆ.
3.0.2. Receive Cookie_Request ๐
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 ๐ง.
3.0.3. Send Cookie_Response ๐
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 ๐.
3.0.4. Receive Cookie_Response ๐
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 ๐.
3.1. Cookie_Request ๐
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
~ 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.
3.2. Cookie_Response ๐ท
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
~ 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 ๐.
3.3. Cookie Generation ๐
The exact technique a Photuris party uses to generate a cookie depends on the implementation. The method chosen has to meet some basic requirements:
- 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 ๐ซ.
- 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 ๐คซ.
- 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 โ .
3.3.1. Initiator Cookie ๐ฌ
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 ๐.
3.3.2. Responder 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 ๐
7.1. Bad_Cookie ๐
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: 11Counter: 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: 13Bad-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) of2. 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 ๐ง
A.2.2. Cookie
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) ๐ฆ
Full Copyright Statement ๐
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
- ietf: rfc2522 1999-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms