tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Gloss.     Arch.     IMS     UICC    |    Misc.    |    search     info

RFC 7425

Informational
Pages: 49
Top     in Index     Prev     Next
in Group Index     Prev in Group     No Next: Highest Number in Group     Group: ~adobe

Adobe's RTMFP Profile for Flash Communication

Part 1 of 2, p. 1 to 31
None       Next RFC Part

 


Top       ToC       Page 1 
Independent Submission                                     M. Thornburgh
Request for Comments: 7425                                         Adobe
Category: Informational                                    December 2014
ISSN: 2070-1721


             Adobe's RTMFP Profile for Flash Communication

Abstract

   This memo describes how to use Adobe's Secure Real-Time Media Flow
   Protocol (RTMFP) to transport the video, audio, and data messages of
   Adobe Flash platform communications.  Aspects of this application
   profile include cryptographic methods and data formats, flow metadata
   formats, and protocol details for client-server and peer-to-peer
   communication.

Status of This Memo

   This document is not an Internet Standards Track specification; it is
   published for informational purposes.

   This is a contribution to the RFC Series, independently of any other
   RFC stream.  The RFC Editor has chosen to publish this document at
   its discretion and makes no statement about its value for
   implementation or deployment.  Documents approved for publication by
   the RFC Editor are not a candidate for any level of Internet
   Standard; see Section 2 of RFC 5741.

   Information about the current status of this document, any errata,
   and how to provide feedback on it may be obtained at
   http://www.rfc-editor.org/info/rfc7425.

Copyright Notice

   Copyright (c) 2014 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

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

   This document may not be modified, and derivative works of it may not
   be created, except to format it for publication as an RFC or to
   translate it into languages other than English.

Top       Page 2 
Table of Contents

   1. Introduction ....................................................3
   2. Terminology .....................................................4
   3. Common Syntax Elements ..........................................4
   4. Cryptography Profile ............................................5
      4.1. Default Session Key ........................................5
      4.2. Diffie-Hellman Groups ......................................6
      4.3. Certificates ...............................................6
           4.3.1. Format ..............................................6
           4.3.2. Fingerprint .........................................7
           4.3.3. Options .............................................7
                  4.3.3.1. Hostname ...................................8
                  4.3.3.2. Accepts Ancillary Data .....................8
                  4.3.3.3. Extra Randomness ...........................8
                  4.3.3.4. Supported Ephemeral Diffie-Hellman Group ...9
                  4.3.3.5. Static Diffie-Hellman Public Key ...........9
           4.3.4. Authenticity .......................................10
           4.3.5. Signing and Verifying Messages .....................10
                  4.3.5.1. Options ...................................11
                           4.3.5.1.1. Simple Password ................11
           4.3.6. Glare Resolution ...................................13
           4.3.7. Session Override ...................................13
      4.4. Endpoint Discriminators ...................................13
           4.4.1. Format .............................................14
           4.4.2. Options ............................................14
                  4.4.2.1. Required Hostname .........................15
                  4.4.2.2. Ancillary Data ............................15
                  4.4.2.3. Fingerprint ...............................16
           4.4.3. Certificate Selection ..............................16
           4.4.4. Canonical Endpoint Discriminator ...................17
      4.5. Session Keying Components .................................18
           4.5.1. Format .............................................19
           4.5.2. Options ............................................19
                  4.5.2.1. Ephemeral Diffie-Hellman Public Key .......20
                  4.5.2.2. Extra Randomness ..........................20
                  4.5.2.3. Diffie-Hellman Group Select ...............21
                  4.5.2.4. HMAC Negotiation ..........................21
                  4.5.2.5. Session Sequence Number Negotiation .......22
      4.6. Session Key Computation ...................................23
           4.6.1. Public Key Selection ...............................23
                  4.6.1.1. Initiator and Responder Ephemeral .........23
                  4.6.1.2. Initiator Ephemeral and Responder Static ..23
                  4.6.1.3. Initiator Static and Responder Ephemeral ..24
                  4.6.1.4. Initiator and Responder Static ............24
           4.6.2. Diffie-Hellman Shared Secret .......................24
           4.6.3. Packet Encrypt/Decrypt Keys ........................25
           4.6.4. Packet HMAC Send/Receive Keys ......................25

Top      ToC       Page 3 
           4.6.5. Session Nonces .....................................26
           4.6.6. Session Sequence Number ............................26
      4.7. Packet Encryption .........................................27
           4.7.1. Cipher .............................................27
           4.7.2. Format .............................................27
           4.7.3. Verification .......................................29
                  4.7.3.1. Simple Checksum ...........................30
                  4.7.3.2. HMAC ......................................30
                  4.7.3.3. Session Sequence Number ...................31
   5. Flash Communication ............................................31
      5.1. RTMP Messages .............................................31
           5.1.1. Flow Metadata ......................................32
           5.1.2. Message Mapping ....................................34
      5.2. Flow Synchronization ......................................35
      5.3. Client-to-Server Connection ...............................36
           5.3.1. Connecting .........................................36
           5.3.2. Server-to-Client Return Control Flow ...............37
           5.3.3. setPeerInfo Command ................................37
           5.3.4. Set Keepalive Timers Command .......................39
           5.3.5. Additional Flows for Streams .......................40
                  5.3.5.1. To Server .................................40
                  5.3.5.2. From Server ...............................40
                  5.3.5.3. Closing Stream Flows ......................41
           5.3.6. Closing the Connection .............................41
           5.3.7. Example ............................................42
      5.4. Direct Peer-to-Peer Streams ...............................43
           5.4.1. Connecting .........................................43
           5.4.2. Return Flows for Stream ............................43
           5.4.3. Closing the Connection .............................44
   6. IANA Considerations ............................................44
      6.1. RTMFP URI Scheme Registration .............................44
   7. Security Considerations ........................................46
   8. References .....................................................47
      8.1. Normative References ......................................47
      8.2. Informative References ....................................49
   Acknowledgements ..................................................49
   Author's Address ..................................................49

1.  Introduction

   Adobe's Secure Real-Time Media Flow Protocol (RTMFP) [RFC7016] is a
   general-purpose transport service for real-time media and bulk data
   in IP networks, and it is suited to client-server and peer-to-peer
   (P2P) communication.  RTMFP provides a generalized framework for
   securing its communications according to the needs of its
   application.

Top      ToC       Page 4 
   The Flash platform comprises the Flash runtime (including Flash
   Player) from Adobe Systems Incorporated, communication servers such
   as Adobe Media Server, and interoperable clients and servers provided
   by other parties.

   Real-time streaming network communication for the Flash platform of
   video, audio, and data typically uses Adobe's Real-Time Messaging
   Protocol (RTMP) [RTMP] messages.  RTMP messages were originally
   designed to be transported over RTMP Chunk Stream in TCP [RTMP];
   however, other transports (such as the one described in this memo)
   are possible.

   This memo specifies the syntax and semantics for transporting RTMP
   messages over RTMFP, and it extends Flash communication semantics to
   include direct P2P communication.  This memo further specifies a
   concrete Cryptography Profile for RTMFP tailored to the application
   and cryptographic needs of Flash platform client-server and P2P
   communications.

   These protocols and profiles were developed by Adobe Systems
   Incorporated and are not the product of an IETF activity.

2.  Terminology

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
   "OPTIONAL" in this document are to be interpreted as described in
   [RFC2119].

   "HMAC" means the Keyed-Hash Message Authentication Code (HMAC)
   algorithm [RFC2104].

   "HMAC-SHA256" means HMAC using the SHA-256 Secure Hash Algorithm
   [SHA256] [RFC6234].

   "HMAC-SHA256(K, M)" means the calculation of the HMAC-SHA256 of
   message M using key K.

3.  Common Syntax Elements

   Definitions of types and structures in this specification use
   traditional text diagrams paired with procedural descriptions using a
   C-like syntax.  The C-like procedural descriptions SHALL be construed
   as definitive.

Top      ToC       Page 5 
   Structures are packed to take only as many bytes as explicitly
   indicated.  There is no 32-bit alignment constraint, and fields are
   not padded for alignment unless explicitly indicated or described.
   Text diagrams may include a bit ruler across the top; this is a
   convenience for counting bits in individual fields and does not
   necessarily imply field alignment on a multiple of the ruler width.

   Unless specified otherwise, reserved fields SHOULD be set to 0 by a
   sender and MUST be ignored by a receiver.

   The procedural syntax of this specification defines correct and
   error-free encoded inputs to a parser.  The procedural syntax does
   not describe a fully featured parser, including error detection and
   handling.  Implementations MUST include means to identify error
   circumstances, including truncations causing elementary or composed
   types not to fit inside containing structures, fields, or elements.
   Unless specified otherwise, an error circumstance SHALL abort the
   parsing and processing of an element and its enclosing elements.

   This memo uses the elementary and composed types described in
   Section 2.1 of RFC 7016.  The definitions of that section are
   incorporated by reference as though fully set forth here.

4.  Cryptography Profile

   RTMFP defines a general security framework but delegates specifics,
   such as packet encryption ciphers and key agreement algorithms, to an
   application-defined Cryptography Profile.

   This section defines the RTMFP Cryptography Profile for Flash
   platform communication.

4.1.  Default Session Key

   RTMFP uses a Default Session Key and associated default cipher
   configuration during session startup handshaking, where session-
   specific keys and ciphers are negotiated.

   The default cipher is the Advanced Encryption Standard [AES] with
   128-bit keys operating in Cipher Block Chaining [CBC] mode, as
   described in Section 4.7.1.  The Default Session Key is the 16 bytes
   of the string "Adobe Systems 02" encoded in UTF-8 [RFC3629]:

           Hex: 41 64 6F 62 65 20 53 79 73 74 65 6D 73 20 30 32

   The Default Session Key uses checksum mode for packet verification
   and does not use session sequence numbers (Section 4.7.3).

Top      ToC       Page 6 
4.2.  Diffie-Hellman Groups

   Implementations conforming to this profile MUST support Diffie-
   Hellman [DH] modular exponentiation (MODP) group 2 (1024 bits) as
   defined in [RFC7296], and SHOULD support Diffie-Hellman MODP group 5
   (1536 bits) and group 14 (2048 bits) as defined in [RFC3526].
   Implementations MAY support additional groups.

4.3.  Certificates

   This section defines the certificate format for this Cryptography
   Profile, and the mapping to the abstract properties and semantics for
   RTMFP endpoint identities.

4.3.1.  Format

   A certificate in this profile is encoded as a sequence of zero or
   more RTMFP Options and Markers (Section 2.1.3 of RFC 7016).  The
   first marker (if any) in the certificate separates the canonical
   section of the certificate from the remainder.  Some options are
   ignored if they occur outside of the canonical section (that is,
   after the first marker).

Top      ToC       Page 7 
   +~~~/~~~/~~~+   +~~~/~~~/~~~+~~~~~+~~~/~~~/~~~+   +~~~/~~~/~~~+
   | L \ T \ V |...| L \ T \ V |  0  | L \ T \ V |...| L \ T \ V |
   +~~~/~~~/~~~+   +~~~/~~~/~~~+~~~~~+~~~/~~~/~~~+   +~~~/~~~/~~~+
   ^                           ^  ^  ^                           ^
   |  Zero or more non-empty   |  |  |   Zero or more Options    |
   |         Options           |  |  +------  or Markers  -------+
   |                           |  |
   +---  Canonical Section  ---+  +---- First Marker
                                        (if present)

   struct certificate_t
   {
       canonicalStart = remainder();
       canonicalEnd = remainder();
       markerFound = false;

       while(remainder() > 0)
       {
           option_t option :variable*8;

           if(0 == option.length)
               markerFound = true;
           else if(!markerFound)
               canonicalEnd = remainder();
       };

       canonicalSectionLength = canonicalStart - canonicalEnd;
   } :variable*8;

4.3.2.  Fingerprint

   A certificate's fingerprint is the SHA-256 hash [SHA256] of the
   canonical section of the certificate (that is, the hash of the first
   canonicalSectionLength bytes of the certificate).

   The certificate's fingerprint is also called the "peer ID".

4.3.3.  Options

   This section lists options that can appear in a certificate.  The
   following option type codes are defined:

   0x00:    Hostname (must be in canonical section) (Section 4.3.3.1)

   0x0a:    Accepts Ancillary Data (must be in canonical section)
            (Section 4.3.3.2)

   0x0e:    Extra Randomness (Section 4.3.3.3)

Top      ToC       Page 8 
   0x15:    Supported Ephemeral Diffie-Hellman Group (must be in
            canonical section) (Section 4.3.3.4)

   0x1d:    Static Diffie-Hellman Public Key (must be in canonical
            section) (Section 4.3.3.5)

   An implementation MUST ignore a certificate option type that is not
   understood.

4.3.3.1.  Hostname

   This option gives an optional hostname for the endpoint.  This option
   MUST be ignored if is not in the canonical section.  This option MUST
   NOT occur more than once in a certificate.

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x00    \ |         hostname              |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct hostnameCertOptionValue_t
   {
       uint8_t hostname[remainder()];
   } :remainder()*8;

4.3.3.2.  Accepts Ancillary Data

   This option indicates that the endpoint will accept an Endpoint
   Discriminator encoding an Ancillary Data option (Section 4.4.2.2).
   This option MUST be ignored if it is not in the canonical section.

   +-------------/-+-------------/-+
   |   length    \ |     0x0a    \ |
   +-------------/-+-------------/-+

4.3.3.3.  Extra Randomness

   This option can be used to add extra entropy or randomness to a
   certificate that doesn't have any other cryptographic pseudorandom
   members (such as a public key).  This option is typically used so
   that endpoints using ephemeral Diffie-Hellman keying can have a
   unique certificate fingerprint.

Top      ToC       Page 9 
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0e    \ |       extra randomness        |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct extraRandomnessCertOptionValue_t
   {
       uint_t extraRandomness[remainder()];
   } :remainder()*8;

4.3.3.4.  Supported Ephemeral Diffie-Hellman Group

   This option specifies a Diffie-Hellman group ID that is supported for
   ephemeral keying.  This option MUST be ignored if it is not in the
   canonical section.  This option may occur more than once in the
   certificate; each instance indicates an additional group that is
   supported for key agreement.

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x15    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+

   struct ephemeralDHGroupCertOptionValue_t
   {
       vlu_t groupID :variable*8;
   } :variable*8;

   The presence of this option means that the certificate uses ephemeral
   Diffie-Hellman public keys only.  The certificate MUST NOT contain a
   Static Diffie-Hellman public key (Section 4.3.3.5).

4.3.3.5.  Static Diffie-Hellman Public Key

   This option specifies a Diffie-Hellman group ID and static public key
   in that group.  This option MUST be ignored if it is not in the
   canonical section.  This option MAY occur more than once in the
   certificate; however, this option SHOULD NOT occur more than once for
   each group ID.  The behavior for specifying more than one public key
   per group ID is not defined.

Top      ToC       Page 10 
   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
   +------------------------------------------------------------------+
   |                  Diffie-Hellman Public Key                       |
   +------------------------------------------------------------------/

   struct staticDHPublicKeyCertOptionValue_t
   {
       vlu_t   groupID :variable*8;
       uintn_t publicKey :remainder()*8; // network byte order
   } :remainder()*8;

   The presence of this option means that the certificate uses static
   Diffie-Hellman public keys only.  The certificate MUST NOT contain
   any Supported Ephemeral Diffie-Hellman Group options
   (Section 4.3.3.4).

4.3.4.  Authenticity

   This profile does not use a public key infrastructure, nor are there
   signing keys present in certificates.  Therefore, any properly
   encoded certificate is considered authentic according to Section 3.2
   of RFC 7016.

   A certificate containing a static public key can only be used
   successfully for session communication if the holder of the
   certificate actually holds the private key associated with the public
   key.  Authenticity of an identity and its peer ID (Section 4.3.2)
   having a certificate containing a static public key is implied by
   successful encrypted communication with the associated endpoint
   (Section 4.6).

   See Section 7 for further discussion of security issues related to
   identities.

4.3.5.  Signing and Verifying Messages

   RTMFP Initiator Initial Keying and Responder Initial Keying messages
   have a field for the sender's digital signature of the keying
   parameters (Sections 2.3.7 and 2.3.8 of RFC 7016).  In this profile,
   the signature field of those messages is encoded as a sequence of
   zero or more RTMFP Options.

Top      ToC       Page 11 
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+

   struct initialKeyingSignature_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;

   If a signer has no signature options to send, it MAY encode a
   signature as a UTF-8 capital "X" (hex 58) or as empty.  A verifier
   MUST interpret a malformed signature field or a signature field
   consisting only of a UTF-8 capital "X" as though it was empty.

   If a verifier does not require a signature, it SHALL consider any
   signature field (including an empty or malformed one) to be valid.  A
   verifier MAY require a signature comprising one or more non-empty
   options that are valid according to their respective types.

   This profile does not use a public key infrastructure, nor are there
   signing keys present in certificates.  Section 4.3.5.1.1 defines a
   simple ID/password credential system.

4.3.5.1.  Options

   This section lists options that can appear in an RTMFP Initial Keying
   signature field.  The following option type code is defined:

   0x1d:  Simple Password (Section 4.3.5.1.1)

   Future or derived profiles may define additional signature field
   options and semantics; therefore, a verifier SHOULD ignore option
   types that are not understood.

4.3.5.1.1.  Simple Password

   This option encodes a password identifier (such as a user name, or an
   application-specific or implementation-specific selector) and an HMAC
   over the signed parameters using the identified password as the HMAC
   key.  This option can occur more than once (for example, to allow
   interoperation between a current and a previous version of an
   implementation using implementation-specific passwords).

Top      ToC       Page 12 
   To support the versioning use case, a verifier SHOULD ignore a Simple
   Password option encoding an unrecognized password identifier.  A
   verifier SHOULD treat the entire signature as invalid if any Simple
   Password option encodes a recognized password identifier with an
   invalid password HMAC.

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |
   +-------------/-+-------------/-+
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                           hmacSHA256                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                           passwordID                          |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct simplePasswordSignatureOptionValue_t
   {
       uint8_t hmacSHA256[32];
       uint8_t passwordID[remainder()];
   } :remainder()*8;

   hmacSHA256:  HMAC-SHA256(K, M), where K is the password associated
      with passwordID, and M is the signed parameters.

   passwordID:  The identifier (such as a user name) for the password
      used as the HMAC key.

Top      ToC       Page 13 
4.3.6.  Glare Resolution

   Glare occurs when two endpoints initiate a session each to the other
   concurrently.

   Compare the near end's certificate to the far end's with a binary
   lexicographic comparison, one byte at a time, up to the length of the
   shorter certificate.  At the first corresponding byte from each
   certificate that is different, the certificate having the differing
   byte (treated as an unsigned 8-bit integer) with the lower value is
   ordered before the other certificate.  If the certificates are not
   the same length and they are identical up to the length of the
   shorter certificate, then the shorter certificate is ordered before
   the longer.

   The near end prevails as the Initiator in case of glare if its
   certificate is ordered before, or is identical to, the certificate of
   the far end.  Otherwise, the near end's certificate is ordered after
   the far end's certificate, and the near end assumes the role of
   Responder.

4.3.7.  Session Override

   A new incoming session overrides an existing session only if the
   certificate for the new session is identical to the certificate for
   the existing session.

4.4.  Endpoint Discriminators

   This section describes the Endpoint Discriminator (EPD) (Section 3.2
   of RFC 7016) format and semantics for this Cryptography Profile, and
   the mapping to RTMFP's abstract certificate and identity selection
   semantics.

Top      ToC       Page 14 
4.4.1.  Format

   An EPD in this profile is encoded as a sequence of zero or more RTMFP
   Options.

   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+

   struct endpointDiscriminator_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;

4.4.2.  Options

   This section lists options that can appear in an EPD.  The following
   option type codes are defined:

   0x00:  Required Hostname (Section 4.4.2.1)

   0x0a:  Ancillary Data (Section 4.4.2.2)

   0x0f:  Fingerprint (Section 4.4.2.3)

   The use of these options for selecting certificates is described in
   Section 4.4.3.

   An implementation MUST ignore EPD option types that are not
   understood.

Top      ToC       Page 15 
4.4.2.1.  Required Hostname

   This option indicates the hostname to match against the certificate's
   Hostname option (Section 4.3.3.1).

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x00    \ |         hostname              |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct hostnameEPDOptionValue_t
   {
       uint8_t hostname[remainder()];
   } :remainder()*8;

   This option MUST NOT occur more than once in an EPD.

4.4.2.2.  Ancillary Data

   In this profile, this option indicates the server Uniform Resource
   Identifier (URI) [RFC3986] encoded in UTF-8 to which a client is
   connecting on this session, for example,
   "rtmfp://server.example.com/app/instance".

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0a    \ |       ancillary data          |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct ancillaryDataEPDOptionValue_t
   {
       uint8_t ancillaryData[remainder()];
   } :remainder()*8;

   This option MUST NOT occur more than once in an EPD.

Top      ToC       Page 16 
4.4.2.3.  Fingerprint

   This option indicates the 256-bit (32-byte) fingerprint
   (Section 4.3.2) of a certificate.

    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-------------/-+-------------/-+
   |   length    \ |     0x0f    \ |
   +-------------/-+-------------/-+
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                          fingerprint                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   struct fingerprintEPDOptionValue_t
   {
       uint8_t fingerprint[32];
   } :256;

   This option MUST NOT occur more than once in an EPD.

4.4.3.  Certificate Selection

   This section describes the REQUIRED method of determining whether an
   EPD selects a certificate.

   An EPD MUST contain at least one of Fingerprint, Required Hostname,
   or Ancillary Data options to select any certificate.

   A Fingerprint EPD option selects or rejects a certificate no matter
   what other options are present.

   Without a Fingerprint option, a Required Hostname EPD option, if
   present, REQUIRES an identical Hostname option in the certificate.

Top      ToC       Page 17 
   Without a Fingerprint option, an Ancillary Data EPD option, if
   present, REQUIRES that the certificate has an Accepts Ancillary Data
   option.

   if EPD contains a Fingerprint option:
       if certificate.fingerprint == option.fingerprint:
           certificate is selected. stop.
       else:
           certificate is not selected. stop.
   else:
       if EPD contains a Required Hostname option:
           if certificate contains a Hostname option:
               if certificate.hostname != option.hostname:
                   certificate is not selected. stop.
           else:
               certificate is not selected. stop.
       if EPD contains an Ancillary Data option:
           if certificate doesn't have an Accepts Ancillary Data option:
               certificate is not selected. stop.
       else if EPD does not contain a Required Hostname option:
           certificate is not selected. stop.
       certificate is selected. stop.

     Figure 1: Algorithm to Test Whether an EPD Selects a Certificate

4.4.4.  Canonical Endpoint Discriminator

   In this profile, a Canonical Endpoint Discriminator (Section 3.2 of
   RFC 7016) contains only a Fingerprint option (Section 4.4.2.3) and no
   other options.  The option length and type code MUST be encoded as
   1-byte VLUs, even though VLU encoding allows those fields to be
   encoded in an arbitrary number of bytes.  That is, the Canonical
   Endpoint Discriminator MUST be exactly 34 bytes long, with a length
   field of 0x21 encoded as one byte, a type code of 0x0f encoded as one
   byte, and 32 bytes of fingerprint.

Top      ToC       Page 18 
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     0x21      |     0x0f      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                          fingerprint                          |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   + - - - - - - - + - - - - - - - + - - - - - - - + - - - - - - - +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   struct canonicalEndpointDiscriminator_t
   {
       uint8_t length = 0x21;
       uint8_t type = 0x0f;
       uint8_t fingerprint[32];
   } :272;

4.5.  Session Keying Components

   This section describes the format of the Session Key Initiator
   Component of the Initiator Initial Keying RTMFP chunk and the Session
   Key Responder Component of the Responder Initial Keying RTMFP chunk
   (Sections 2.3.7 and 2.3.8 of RFC 7016).  The Initiator and Responder
   Session Keying Components have the same format.

Top      ToC       Page 19 
4.5.1.  Format

   A Session Keying Component in this profile is encoded as a sequence
   of zero or more RTMFP Options.

   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   | L \ T \   V   |...............| L \ T \   V   |
   +~~~/~~~/~~~~~~~+               +~~~/~~~/~~~~~~~+
   ^                                               ^
   +-------------  Zero or more Options  ----------+

   struct sessionKeyingComponent_t
   {
       while(remainder() > 0)
           option_t option :variable*8;
   } :remainder()*8;

4.5.2.  Options

   This section lists options that can appear in a Session Keying
   Component.  The following option type codes are defined:

   0x0d:  Ephemeral Diffie-Hellman Public Key (Section 4.5.2.1)

   0x0e:  Extra Randomness (Section 4.5.2.2)

   0x1d:  Diffie-Hellman Group Select (Section 4.5.2.3)

   0x1a:  HMAC Negotiation (Section 4.5.2.4)

   0x1e:  Session Sequence Number Negotiation (Section 4.5.2.5)

   An implementation MUST ignore a session keying component option type
   that is not understood.

Top      ToC       Page 20 
4.5.2.1.  Ephemeral Diffie-Hellman Public Key

   This option specifies a Diffie-Hellman group ID and public key in
   that group.  This option MUST NOT be sent if the sender's certificate
   has a static Diffie-Hellman public key.  This option MUST be sent if
   the sender's certificate does not have a static Diffie-Hellman public
   key.  This option MUST NOT be sent more than once.

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x0d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+
   +------------------------------------------------------------------+
   |                  Diffie-Hellman Public Key                       |
   +------------------------------------------------------------------/

   struct ephemeralDHPublicKeyKeyingOptionValue_t
   {
       vlu_t   groupID :variable*8;
       uintn_t publicKey :remainder()*8; // network byte order
   } :remainder()*8;

4.5.2.2.  Extra Randomness

   This option can be used to add extra entropy or randomness to a
   keying component, particularly when the sender uses a static public
   key.  When used for that purpose, the extra randomness SHOULD be
   cryptographically strong pseudorandom bytes not less than 16 bytes
   (for cryptographically significant entropy) and not more than 64
   bytes (the length of a SHA-256 input block) in length.  The extra
   randomness serves as a salt when computing the session keys
   (Section 4.6).

   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |   length    \ |     0x0e    \ |       extra randomness        |
   +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct extraRandomnessKeyingOptionValue_t
   {
       uint_t extraRandomness[remainder()];
   } :remainder()*8;

Top      ToC       Page 21 
4.5.2.3.  Diffie-Hellman Group Select

   This option is sent by the Initiator to specify which Diffie-Hellman
   group to use for key agreement.  The Initiator MUST send this option
   when it advertises a static Diffie-Hellman public key in its
   certificate and MUST NOT send this option if it sends an ephemeral
   Diffie-Hellman public key.  This option MUST NOT be sent more than
   once.

   +-------------/-+-------------/-+-------------/-+
   |   length    \ |     0x1d    \ |   group ID  \ |
   +-------------/-+-------------/-+-------------/-+

   struct staticDHGroupSelectKeyingOptionValue_t
   {
       vlu_t   groupID :variable*8;
   } :variable*8;

4.5.2.4.  HMAC Negotiation

   This option is used to negotiate sending and receiving of an HMAC
   field for packet verification.

                                   |0 1 2 3 4 5 6 7|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+-------------/-+
   |             \ |             \ |         |S|S|R|             \ |
   |   length    / |     0x1a    / |   rsv   |N|O|E|  hmacLength / |
   |             \ |             \ |         |D|R|Q|             \ |
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+-------------/-+

   struct hmacNegotiationKeyingOptionValue_t
   {
       uintn_t reserved :5;          // rsv
       bool_t  willSendAlways :1;    // SND
       bool_t  willSendOnRequest :1; // SOR
       bool_t  request :1;           // REQ
       vlu_t   hmacLength :variable*8;
   } :variable*8;

   willSendAlways:  If set, the sender will send an HMAC on packets in
      this session.

   willSendOnRequest:  If set, the sender will send an HMAC on packets
      in this session if the other end sets the request flag in its HMAC
      Negotiation.

Top      ToC       Page 22 
   request:  If set, the sender would very much like the receiver to
      send an HMAC on its packets.  If the other end doesn't send an
      HMAC on its packets, the session can fail.

   hmacLength:  If the sender negotiates to send an HMAC on its packets,
      the HMAC field will be this many bytes long.  This value MUST be
      between 4 and 32 inclusive, or 0 if and only if willSendAlways and
      willSendOnRequest are clear.

   The handshake operational semantics for this option are described in
   Section 4.6.4.

4.5.2.5.  Session Sequence Number Negotiation

   This option is used to negotiate sending and receiving of the Session
   Sequence Number field for packet verification.

                                   |0 1 2 3 4 5 6 7|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+
   |             \ |             \ |         |S|S|R|
   |   length    / |     0x1e    / |   rsv   |N|O|E|
   |             \ |             \ |         |D|R|Q|
   +-------------/-+-------------/-+-+-+-+-+-+-+-+-+

   struct sseqNegotiationKeyingOptionValue_t
   {
       uintn_t reserved :5;          // rsv
       bool_t  willSendAlways :1;    // SND
       bool_t  willSendOnRequest :1; // SOR
       bool_t  request :1;           // REQ
   } :8;

   willSendAlways:  If set, the sender will send a session sequence
      number in packets in this session.

   willSendOnRequest:  If set, the sender will send a session sequence
      number in packets in this session if the other end sets the
      request flag in its Session Sequence Number Negotiation.

   request:  If set, the sender would very much like the receiver to
      send a session sequence number in its packets.  If the other end
      doesn't send a session sequence number in its packets, the session
      can fail.

   The handshake operational semantics for this option are described in
   Section 4.6.6.

Top      ToC       Page 23 
4.6.  Session Key Computation

   This section describes how to compute the cryptographic keys and
   other settings for packet encryption and verification.

   The Session Key Near Component (SKNC) means the keying component sent
   by the near end of the session; that is, it is the Session Key
   Initiator Component at the Initiator and the Session Key Responder
   Component at the Responder.

   The Session Key Far Component (SKFC) means the keying component sent
   by the far end of the session; that is, it is the Session Key
   Responder Component at the Initiator and the Session Key Initiator
   Component at the Responder.

4.6.1.  Public Key Selection

   This section enumerates the public key selection methods for all
   possible combinations of static or ephemeral public key modes for
   each endpoint according to their certificate options (Section 4.3.3).

4.6.1.1.  Initiator and Responder Ephemeral

   The Initiator and Responder list one or more Supported Ephemeral
   Diffie-Hellman Group options (Section 4.3.3.4) in their certificates.
   The Initiator sends exactly one Ephemeral Diffie-Hellman Public Key
   option (Section 4.5.2.1) in its Session Key Initiator Component,
   which selects one group from among those supported by the Responder
   and Initiator.  Responder sends exactly one Ephemeral Diffie-Hellman
   Public Key option in its Session Key Responder Component, in the same
   group as indicated by the Initiator.

4.6.1.2.  Initiator Ephemeral and Responder Static

   The Responder lists one or more Static Diffie-Hellman Public Key
   options (Section 4.3.3.5) in its certificate.  The Initiator lists
   one or more Supported Ephemeral Diffie-Hellman Group options in its
   certificate.  The Initiator sends exactly one Ephemeral Diffie-
   Hellman Public Key option in its Session Key Initiator Component,
   which selects one group from among those supported by the Responder
   and Initiator and the corresponding public key for the Responder.
   Responder uses its public key from the indicated group, and sends
   only an Extra Randomness option (Section 4.5.2.2) in its Session Key
   Responder Component to salt the session keys.

Top      ToC       Page 24 
4.6.1.3.  Initiator Static and Responder Ephemeral

   The Responder lists one or more Supported Ephemeral Diffie-Hellman
   Group options in its certificate.  The Initiator lists one or more
   Static Diffie-Hellman Public Key options in its certificate.  The
   Initiator sends exactly one Diffie-Hellman Group Select option
   (Section 4.5.2.3) in its Session Key Initiator Component, which
   selects one group from among those supported by the Responder and
   Initiator and the corresponding public key for the Initiator, plus an
   Extra Randomness option to salt the session keys.  The Responder
   sends an Ephemeral Diffie-Hellman Public Key option in its Session
   Key Responder Component in the same group as indicated by the
   Initiator.

4.6.1.4.  Initiator and Responder Static

   The Initiator and Responder each list one or more Static Diffie-
   Hellman Public Key options in their certificates.  The Initiator
   sends exactly one Diffie-Hellman Group Select option in its Session
   Key Initiator Component, which selects one group and corresponding
   public keys from among those supported by the Responder and
   Initiator, and an Extra Randomness option to salt the session keys.
   The Responder sends an Extra Randomness option in its Session Key
   Responder Component to add its own salt to the session keys.

4.6.2.  Diffie-Hellman Shared Secret

   To be acceptable, a Diffie-Hellman public key MUST have all of the
   following properties:

   o  Be at least 16777216 (2^24);

   o  Be at most the group's prime modulus minus 16777216;

   o  Have at least 16 "1" bits;

   o  Have at least 16 "0" bits, not including leading zeros.

   An endpoint MUST NOT complete to an S_OPEN session with a far
   endpoint using a public key that is not acceptable according to these
   criteria.

   Once the group and corresponding public key of the far end is
   determined, the far end's public key and the near end's private key
   are combined according to Diffie-Hellman [DH] to compute the Diffie-
   Hellman Shared Secret, an integer.

Top      ToC       Page 25 
   In the following sections, DH_SECRET means the Diffie-Hellman Shared
   Secret encoded as a byte-aligned unsigned integer in network byte
   order with no leading zero bytes.  For example, if the shared secret
   is 4886718345, DH_SECRET would be the five bytes:

                            Hex: 01 23 45 67 89

4.6.3.  Packet Encrypt/Decrypt Keys

   Packets are encrypted using a symmetric cipher, such as the Advanced
   Encryption Standard [AES].  Distinct keys are used for sending and
   receiving packets.  Each end's sending (encrypt) key is the other
   end's receiving (decrypt) key.

   The raw keys computed in this section for encryption and decryption
   are transformed in a manner specific to the cipher with which they
   are to be used.  In this profile, AES-128 is the only currently
   defined cipher.  For this cipher, the first 128 bits (16 bytes) of
   the 256-bit output of the calculation are taken to be the AES-128
   key.

      Set ENCRYPT_KEY = HMAC-SHA256(DH_SECRET, HMAC-SHA256(SKFC, SKNC));

      Set DECRYPT_KEY = HMAC-SHA256(DH_SECRET, HMAC-SHA256(SKNC, SKFC));

   The full 256 bits of ENCRYPT_KEY and DECRYPT_KEY are used in the
   computations in the following sections.

4.6.4.  Packet HMAC Send/Receive Keys

   Packets can be verified that they were not corrupted or modified by
   appending an HMAC to the packet.  Whether to use an HMAC or a simple
   checksum is determined during the initial keying phase using the HMAC
   Negotiation option (Section 4.5.2.4).  Distinct HMAC keys are used
   for sending and receiving packets.  Each end's sending key is the
   other end's receiving key, and vice versa.

      Set HMAC_SEND_KEY = HMAC_SHA256(DH_SECRET, ENCRYPT_KEY);

      Set HMAC_RECV_KEY = HMAC_SHA256(DH_SECRET, DECRYPT_KEY);

   If an endpoint sets the willSendAlways flag in its HMAC Negotiation
   option, then it MUST send an HMAC on packets it sends with this
   session key.

Top      ToC       Page 26 
   If an endpoint's willSendAlways flag is clear but its
   willSendOnRequest flag is set, then it MUST send an HMAC on packets
   it sends with this session key if and only if the other endpoint's
   request flag is set.

   If a sending endpoint's willSendAlways and willSendOnRequest flags
   are clear, then the receiving endpoint SHOULD reject that keying
   component if the receiving endpoint is configured to require the
   sending endpoint to send HMAC.

   If HMAC is negotiated to be used, the corresponding hmacLength MUST
   be between 4 and 32 inclusive.

   If HMAC is negotiated not to be used, a simple checksum is used for
   packet verification.

   The Default Session Key uses the simple checksum and does not use
   HMAC.

4.6.5.  Session Nonces

   Session nonces are per-session, cryptographically strong secret
   values known only to the two endpoints of the session.  They can be
   used for application-layer cryptographic challenges (such as signing
   or password verification).  These nonces are a convenience being pre-
   shared and pre-agreed-upon in a secure manner during the initial
   keying handshake.

   Each end's near nonce is the other end's far nonce, and vice versa.

      Set NEAR_NONCE = HMAC_SHA256(DH_SECRET, SKNC);

      Set FAR_NONCE = HMAC_SHA256(DH_SECRET, SKFC);

4.6.6.  Session Sequence Number

   Duplicate packets can be detected and rejected by using an optional
   session sequence number inside the encrypted packets.  The session
   sequence number is a monotonically increasing unbounded integer and
   does not wrap.  Session sequence numbers SHOULD start at zero and
   SHOULD increment by one for each packet sent using that session key.
   Implementations MUST handle session sequence numbers with no less
   than 64 bits of range.

   If an endpoint's willSendAlways flag in its Session Sequence Number
   Negotiation option (Section 4.5.2.5) is set, then it MUST send a
   session sequence number in packets it sends with this session key.

Top      ToC       Page 27 
   If an endpoint's willSendAlways flag is clear but its
   willSendOnRequest flag is set, then it MUST send a session sequence
   number on packets it sends with this session key if and only if the
   other endpoint's request flag is set.

   If a sending endpoint's willSendAlways and willSendOnRequest flags
   are clear, then the receiving endpoint SHOULD reject that keying
   component if the receiving endpoint is configured to require the
   sending endpoint to send session sequence numbers.

   The Default Session Key does not use session sequence numbers.

4.7.  Packet Encryption

   This section describes the concrete syntax and operational semantics
   of RTMFP packet encryption for this Cryptography Profile.

4.7.1.  Cipher

   This profile defines AES-128 [AES] in CBC [CBC] mode as the only
   cipher.  Extensions to this profile can specify and negotiate
   additional ciphers and modes by defining certificate and keying
   component options and associated semantics.

   For AES-128-CBC, the initialization vector (IV) for each packet is 16
   zero bytes.  The IV is not included in the packet.

4.7.2.  Format

   The Encrypted Packet is the encryptedPacket field of an RTMFP
   Multiplex packet (Section 2.2.2 of RFC 7016); that is, the portion of
   the Multiplex packet following the scrambled session ID.  The
   Encrypted Packet has the following format:

Top      ToC       Page 28 
   +----------------+     +----------------+~~~~~~~~~~~~~~~~~~~~~~~+
   |  CBC Block 1   | ... |  CBC Block N   |     truncatedHMAC     |
   +----------------+     +----------------+~~~~~~~~~~~~~~~~~~~~~~~+
   ^                                       ^                       ^
   |     Zero or more AES-128 chained      | hmacLength bytes long |
   +--------    cipher blocks   -----------+---  (may be zero)  ---+

   struct flashProfileEncryptedPacket_t
   {
       if(HMAC is being used)
           hmacLength = negotiated length;
       else
           hmacLength = 0;

       struct
       {
           iv[16 bytes] = { 0 };
           blockCount = 0;
           while((remainder() > hmacLength) && (remainder() >= 16))
           {
               uint8_t cbcBlock[16];
               blockCount++;
           }
       } chainedCipherBlocks :variable*16*8;

       if(HMAC is being used)
       {
           if(remainder() == hmacLength)
               uint8_t truncatedHMAC[hmacLength];
           else
               packetVerificationFailed();
       }
       else if(remainder() > 0)
           packetVerificationFailed();
   } :encryptedPacket.length*8;

   cbcBlock:  The next AES-128-CBC block.

   chainedCipherBlocks:  The concatenation of every cipher block in the
      packet (over which the HMAC is computed).

   truncatedHMAC:  If HMAC was negotiated to be used (Section 4.5.2.4),
      this field is set to the first negotiated hmacLength bytes of the
      HMAC of the chainedCipherBlocks.

   The plaintext data before encryption or after decryption has the
   following format:

Top      ToC       Page 29 
    0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
   +~~~~~~~~~~~~~/~+
   | SSEQ (opt.) \ |
   +~~~~~~~~~~~~~/~+
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   |        Checksum (opt.)        |
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                        Plain RTMFP Packet                     |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct flashProfilePlainPacket_t
   {
       if(session sequence numbers being used)
           vlu_t sessionSequenceNumber :variable*8; // SSEQ
       if(HMAC not being used)
           uint16_t checksum;
       packet_t plainRTMFPPacket :variable*8;
   } :chainedCipherBlocks.blockCount*16*8;

   sessionSequenceNumber:  If session sequence numbers were negotiated
      to be used (Section 4.6.6), this field is present and is the VLU
      session sequence number of this packet.

   checksum:  If HMAC was not negotiated to be used, this field is
      present and is the simple checksum (Section 4.7.3.1) of the
      remaining bytes of this structure.

   plainRTMFPPacket:  The (plain, unencrypted) RTMFP Packet
      (Section 2.2.4 of RFC 7016) plus any necessary padding.

   When assembling this structure and prior to calculating the checksum
   (if present), if the structure's total length is not an integer
   multiple of 16 bytes (the AES cipher block size), pad the end of
   plainRTMFPPacket with as many bytes having a value of 0xff as are
   needed to bring the structure's total length to an integer multiple
   of 16 bytes.  The receiver's RTMFP Packet parser (Section 2.2.4 of
   RFC 7016) will consume this padding.

4.7.3.  Verification

   In RTMFP, the Cryptography Profile is responsible for packet
   verification.  In this profile, packets are verified with an HMAC or
   a simple checksum, depending on the configuration of the endpoints,
   and optionally verified against replay or duplication using session
   sequence numbers.  The simple checksum is inside the encrypted
   packet, so it becomes essentially a 16-bit cryptographic checksum.

Top      ToC       Page 30 
4.7.3.1.  Simple Checksum

   The simple checksum is the 16-bit ones' complement of the 16-bit
   ones' complement sum of all 16-bit (2 bytes in network byte order)
   words to be checked.  If there are an odd number of bytes to be
   checked, then for purposes of this checksum, treat the last byte as
   the lower 8 bits of a 16-bit word whose upper 8 bits are 0.  This is
   also known as the "Internet Checksum" [RFC1071].

   When present, the checksum is calculated over all bytes of the
   plaintext packet starting after the checksum field through the end of
   the plain packet.  It cannot be calculated until the plain packet is
   padded, if necessary, to bring its length to an integer multiple of
   16 bytes (the AES cipher block size).  The session sequence number
   field, if present, and the checksum field itself are not included in
   the checksum.

   On receiving a packet being verified with a checksum: calculate the
   checksum over all the bytes of the plaintext packet following the
   checksum field and compare the checksum to the value in the checksum
   field.  If they match, the packet is verified; if they do not match,
   the packet is corrupt and MUST be discarded as though it was never
   received.

4.7.3.2.  HMAC

   When present, the HMAC field is the last hmacLength bytes of the
   packet and is calculated over all of the encrypted cipher blocks of
   the packet preceding the HMAC field.  The value of the HMAC field is
   the first hmacLength bytes of the HMAC-SHA256 of the checked data,
   using the computed HMAC keys (Section 4.6.4) and negotiated
   hmacLength (Section 4.5.2.4).  Note each endpoint independently
   specifies the length of the HMAC it will send via its hmacLength
   field.

   When an endpoint has negotiated to send an HMAC, it encrypts the data
   blocks, computes the HMAC over the encrypted data blocks using its
   HMAC_SEND_KEY, and appends the first hmacLength bytes of that hash
   after the final encrypted data block.

   When an endpoint has negotiated to receive an HMAC, the endpoint
   computes the HMAC over the encrypted data blocks using its
   HMAC_RECV_KEY and then compares the first receive hmacLength bytes of
   the computed HMAC to the HMAC field in the packet.  If they are
   identical, the packet is verified; if they are not identical, the
   packet is corrupt and MUST be discarded as though it was never
   received.

Top      ToC       Page 31 
   HMAC and simple checksum verification are mutually exclusive.

4.7.3.3.  Session Sequence Number

   Session sequence numbers are used to detect and reject a packet that
   was duplicated in the network or replayed by an attacker and to
   ensure the first chained cipher block of every packet is unique, in
   lieu of a full-block initialization vector.  Sequence numbers start
   at zero, increase by one for each packet sent in the session, do not
   wrap, and do not repeat.

   When session sequence numbers are negotiated to be used, the receiver
   MUST allow for packets to be reordered in the network by up to at
   least 32 sequence numbers; note, however, that reordering by more
   than three packets can trigger loss detection and retransmission by
   negative acknowledgement, just as with TCP, and is therefore not
   likely to occur in the real Internet.

   [RFC4302], [RFC4303], and [RFC6479] describe Anti-Replay Window
   methods that can be employed to detect duplicate sequence numbers.
   Other methods are possible.

   Any packet received having a session sequence number that was already
   seen in that session, either directly or by being less than the
   lowest sequence number in the Anti-Replay Window, is a duplicate and
   MUST be discarded as though never received.



(page 31 continued on part 2)

Next RFC Part