tech-invite   World Map
3GPP     Specs     Glossaries     UICC       T+       IETF     RFCs     Groups     SIP     ABNFs       Search     Home

RFC 8152

 
 
 

CBOR Object Signing and Encryption (COSE)

Part 2 of 6, p. 16 to 33
Prev Section       Next Section

 


prevText      Top      ToC       Page 16 
4.  Signing Objects

   COSE supports two different signature structures.  COSE_Sign allows
   for one or more signatures to be applied to the same content.
   COSE_Sign1 is restricted to a single signer.  The structures cannot
   be converted between each other; as the signature computation
   includes a parameter identifying which structure is being used, the
   converted structure will fail signature validation.

4.1.  Signing with One or More Signers

   The COSE_Sign structure allows for one or more signatures to be
   applied to a message payload.  Parameters relating to the content and
   parameters relating to the signature are carried along with the
   signature itself.  These parameters may be authenticated by the
   signature, or just present.  An example of a parameter about the
   content is the content type.  Examples of parameters about the
   signature would be the algorithm and key used to create the signature
   and counter signatures.

   RFC 5652 indicates that:

      When more than one signature is present, the successful validation
      of one signature associated with a given signer is usually treated
      as a successful signature by that signer.  However, there are some
      application environments where other rules are needed.  An
      application that employs a rule other than one valid signature for
      each signer must specify those rules.  Also, where simple matching
      of the signer identifier is not sufficient to determine whether
      the signatures were generated by the same signer, the application
      specification must describe how to determine which signatures were
      generated by the same signer.  Support for different communities
      of recipients is the primary reason that signers choose to include
      more than one signature.

   For example, the COSE_Sign structure might include signatures
   generated with the Edwards-curve Digital Signature Algorithm (EdDSA)
   [RFC8032] and with the Elliptic Curve Digital Signature Algorithm
   (ECDSA) [DSS].  This allows recipients to verify the signature
   associated with one algorithm or the other.  More-detailed
   information on multiple signature evaluations can be found in
   [RFC5752].

Top      Up      ToC       Page 17 
   The signature structure can be encoded as either tagged or untagged
   depending on the context it will be used in.  A tagged COSE_Sign
   structure is identified by the CBOR tag 98.  The CDDL fragment that
   represents this is:

   COSE_Sign_Tagged = #6.98(COSE_Sign)

   A COSE Signed Message is defined in two parts.  The CBOR object that
   carries the body and information about the body is called the
   COSE_Sign structure.  The CBOR object that carries the signature and
   information about the signature is called the COSE_Signature
   structure.  Examples of COSE Signed Messages can be found in
   Appendix C.1.

   The COSE_Sign structure is a CBOR array.  The fields of the array in
   order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   payload:  This field contains the serialized content to be signed.
      If the payload is not present in the message, the application is
      required to supply the payload separately.  The payload is wrapped
      in a bstr to ensure that it is transported without changes.  If
      the payload is transported separately ("detached content"), then a
      nil CBOR object is placed in this location, and it is the
      responsibility of the application to ensure that it will be
      transported without changes.

      Note: When a signature with a message recovery algorithm is used
      (Section 8), the maximum number of bytes that can be recovered is
      the length of the payload.  The size of the payload is reduced by
      the number of bytes that will be recovered.  If all of the bytes
      of the payload are consumed, then the payload is encoded as a
      zero-length binary string rather than as being absent.

   signatures:  This field is an array of signatures.  Each signature is
      represented as a COSE_Signature structure.

Top      Up      ToC       Page 18 
   The CDDL fragment that represents the above text for COSE_Sign
   follows.

   COSE_Sign = [
       Headers,
       payload : bstr / nil,
       signatures : [+ COSE_Signature]
   ]

   The COSE_Signature structure is a CBOR array.  The fields of the
   array in order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   signature:  This field contains the computed signature value.  The
      type of the field is a bstr.  Algorithms MUST specify padding if
      the signature value is not a multiple of 8 bits.

   The CDDL fragment that represents the above text for COSE_Signature
   follows.

   COSE_Signature =  [
       Headers,
       signature : bstr
   ]

4.2.  Signing with One Signer

   The COSE_Sign1 signature structure is used when only one signature is
   going to be placed on a message.  The parameters dealing with the
   content and the signature are placed in the same pair of buckets
   rather than having the separation of COSE_Sign.

   The structure can be encoded as either tagged or untagged depending
   on the context it will be used in.  A tagged COSE_Sign1 structure is
   identified by the CBOR tag 18.  The CDDL fragment that represents
   this is:

   COSE_Sign1_Tagged = #6.18(COSE_Sign1)

   The CBOR object that carries the body, the signature, and the
   information about the body and signature is called the COSE_Sign1
   structure.  Examples of COSE_Sign1 messages can be found in
   Appendix C.2.

Top      Up      ToC       Page 19 
   The COSE_Sign1 structure is a CBOR array.  The fields of the array in
   order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   payload:  This is as described in Section 4.1.

   signature:  This field contains the computed signature value.  The
      type of the field is a bstr.

   The CDDL fragment that represents the above text for COSE_Sign1
   follows.

   COSE_Sign1 = [
       Headers,
       payload : bstr / nil,
       signature : bstr
   ]

4.3.  Externally Supplied Data

   One of the features offered in the COSE document is the ability for
   applications to provide additional data to be authenticated, but that
   is not carried as part of the COSE object.  The primary reason for
   supporting this can be seen by looking at the CoAP message structure
   [RFC7252], where the facility exists for options to be carried before
   the payload.  Examples of data that can be placed in this location
   would be the CoAP code or CoAP options.  If the data is in the header
   section, then it is available for proxies to help in performing its
   operations.  For example, the Accept Option can be used by a proxy to
   determine if an appropriate value is in the proxy's cache.  But the
   sender can prevent a proxy from changing the set of values that it
   will accept by including that value in the resulting authentication
   tag.  However, it may also be desired to protect these values so that
   if they are modified in transit, it can be detected.

   This document describes the process for using a byte array of
   externally supplied authenticated data; however, the method of
   constructing the byte array is a function of the application.
   Applications that use this feature need to define how the externally
   supplied authenticated data is to be constructed.  Such a
   construction needs to take into account the following issues:

   o  If multiple items are included, applications need to ensure that
      the same byte string is not produced if there are different
      inputs.  This could occur by appending the strings 'AB' and 'CDE'

Top      Up      ToC       Page 20 
      or by appending the strings 'ABC' and 'DE'.  This is usually
      addressed by making fields a fixed width and/or encoding the
      length of the field as part of the output.  Using options from
      CoAP [RFC7252] as an example, these fields use a TLV structure so
      they can be concatenated without any problems.

   o  If multiple items are included, an order for the items needs to be
      defined.  Using options from CoAP as an example, an application
      could state that the fields are to be ordered by the option
      number.

   o  Applications need to ensure that the byte stream is going to be
      the same on both sides.  Using options from CoAP might give a
      problem if the same relative numbering is kept.  An intermediate
      node could insert or remove an option, changing how the relative
      number is done.  An application would need to specify that the
      relative number must be re-encoded to be relative only to the
      options that are in the external data.

4.4.  Signing and Verification Process

   In order to create a signature, a well-defined byte stream is needed.
   The Sig_structure is used to create the canonical form.  This signing
   and verification process takes in the body information (COSE_Sign or
   COSE_Sign1), the signer information (COSE_Signature), and the
   application data (external source).  A Sig_structure is a CBOR array.
   The fields of the Sig_structure in order are:

   1.  A text string identifying the context of the signature.  The
       context string is:

          "Signature" for signatures using the COSE_Signature structure.

          "Signature1" for signatures using the COSE_Sign1 structure.

          "CounterSignature" for signatures used as counter signature
          attributes.

   2.  The protected attributes from the body structure encoded in a
       bstr type.  If there are no protected attributes, a bstr of
       length zero is used.

   3.  The protected attributes from the signer structure encoded in a
       bstr type.  If there are no protected attributes, a bstr of
       length zero is used.  This field is omitted for the COSE_Sign1
       signature structure.

Top      Up      ToC       Page 21 
   4.  The protected attributes from the application encoded in a bstr
       type.  If this field is not supplied, it defaults to a zero-
       length binary string.  (See Section 4.3 for application guidance
       on constructing this field.)

   5.  The payload to be signed encoded in a bstr type.  The payload is
       placed here independent of how it is transported.

   The CDDL fragment that describes the above text is:

   Sig_structure = [
       context : "Signature" / "Signature1" / "CounterSignature",
       body_protected : empty_or_serialized_map,
       ? sign_protected : empty_or_serialized_map,
       external_aad : bstr,
       payload : bstr
   ]

   How to compute a signature:

   1.  Create a Sig_structure and populate it with the appropriate
       fields.

   2.  Create the value ToBeSigned by encoding the Sig_structure to a
       byte string, using the encoding described in Section 14.

   3.  Call the signature creation algorithm passing in K (the key to
       sign with), alg (the algorithm to sign with), and ToBeSigned (the
       value to sign).

   4.  Place the resulting signature value in the 'signature' field of
       the array.

   The steps for verifying a signature are:

   1.  Create a Sig_structure object and populate it with the
       appropriate fields.

   2.  Create the value ToBeSigned by encoding the Sig_structure to a
       byte string, using the encoding described in Section 14.

   3.  Call the signature verification algorithm passing in K (the key
       to verify with), alg (the algorithm used sign with), ToBeSigned
       (the value to sign), and sig (the signature to be verified).

Top      Up      ToC       Page 22 
   In addition to performing the signature verification, the application
   may also perform the appropriate checks to ensure that the key is
   correctly paired with the signing identity and that the signing
   identity is authorized before performing actions.

4.5.  Computing Counter Signatures

   Counter signatures provide a method of associating a different
   signature generated by different signers with some piece of content.
   This is normally used to provide a signature on a signature allowing
   for a proof that a signature existed at a given time (i.e., a
   Timestamp).  In this document, we allow for counter signatures to
   exist in a greater number of environments.  As an example, it is
   possible to place a counter signature in the unprotected attributes
   of a COSE_Encrypt object.  This would allow for an intermediary to
   either verify that the encrypted byte stream has not been modified,
   without being able to decrypt it, or assert that an encrypted byte
   stream either existed at a given time or passed through it in terms
   of routing (i.e., a proxy signature).

   An example of a counter signature on a signature can be found in
   Appendix C.1.3.  An example of a counter signature in an encryption
   object can be found in Appendix C.3.3.

   The creation and validation of counter signatures over the different
   items relies on the fact that the objects have the same structure.
   The elements are a set of protected attributes, a set of unprotected
   attributes, and a body, in that order.  This means that the
   Sig_structure can be used in a uniform manner to get the byte stream
   for processing a signature.  If the counter signature is going to be
   computed over a COSE_Encrypt structure, the body_protected and
   payload items can be mapped into the Sig_structure in the same manner
   as from the COSE_Sign structure.

   It should be noted that only a signature algorithm with appendix (see
   Section 8) can be used for counter signatures.  This is because the
   body should be able to be processed without having to evaluate the
   counter signature, and this is not possible for signature schemes
   with message recovery.

5.  Encryption Objects

   COSE supports two different encryption structures.  COSE_Encrypt0 is
   used when a recipient structure is not needed because the key to be
   used is known implicitly.  COSE_Encrypt is used the rest of the time.
   This includes cases where there are multiple recipients or a
   recipient algorithm other than direct is used.

Top      Up      ToC       Page 23 
5.1.  Enveloped COSE Structure

   The enveloped structure allows for one or more recipients of a
   message.  There are provisions for parameters about the content and
   parameters about the recipient information to be carried in the
   message.  The protected parameters associated with the content are
   authenticated by the content encryption algorithm.  The protected
   parameters associated with the recipient are authenticated by the
   recipient algorithm (when the algorithm supports it).  Examples of
   parameters about the content are the type of the content and the
   content encryption algorithm.  Examples of parameters about the
   recipient are the recipient's key identifier and the recipient's
   encryption algorithm.

   The same techniques and structures are used for encrypting both the
   plaintext and the keys.  This is different from the approach used by
   both "Cryptographic Message Syntax (CMS)" [RFC5652] and "JSON Web
   Encryption (JWE)" [RFC7516] where different structures are used for
   the content layer and for the recipient layer.  Two structures are
   defined: COSE_Encrypt to hold the encrypted content and
   COSE_recipient to hold the encrypted keys for recipients.  Examples
   of encrypted messages can be found in Appendix C.3.

   The COSE_Encrypt structure can be encoded as either tagged or
   untagged depending on the context it will be used in.  A tagged
   COSE_Encrypt structure is identified by the CBOR tag 96.  The CDDL
   fragment that represents this is:

   COSE_Encrypt_Tagged = #6.96(COSE_Encrypt)

   The COSE_Encrypt structure is a CBOR array.  The fields of the array
   in order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   ciphertext:  This field contains the ciphertext encoded as a bstr.
      If the ciphertext is to be transported independently of the
      control information about the encryption process (i.e., detached
      content), then the field is encoded as a nil value.

   recipients:  This field contains an array of recipient information
      structures.  The type for the recipient information structure is a
      COSE_recipient.

Top      Up      ToC       Page 24 
   The CDDL fragment that corresponds to the above text is:

   COSE_Encrypt = [
       Headers,
       ciphertext : bstr / nil,
       recipients : [+COSE_recipient]
   ]

   The COSE_recipient structure is a CBOR array.  The fields of the
   array in order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   ciphertext:  This field contains the encrypted key encoded as a bstr.
      All encoded keys are symmetric keys; the binary value of the key
      is the content.  If there is not an encrypted key, then this field
      is encoded as a nil value.

   recipients:  This field contains an array of recipient information
      structures.  The type for the recipient information structure is a
      COSE_recipient (an example of this can be found in Appendix B).
      If there are no recipient information structures, this element is
      absent.

   The CDDL fragment that corresponds to the above text for
   COSE_recipient is:

   COSE_recipient = [
       Headers,
       ciphertext : bstr / nil,
       ? recipients : [+COSE_recipient]
   ]

5.1.1.  Content Key Distribution Methods

   An encrypted message consists of an encrypted content and an
   encrypted CEK for one or more recipients.  The CEK is encrypted for
   each recipient, using a key specific to that recipient.  The details
   of this encryption depend on which class the recipient algorithm
   falls into.  Specific details on each of the classes can be found in
   Section 12.  A short summary of the five content key distribution
   methods is:

   direct:  The CEK is the same as the identified previously distributed
      symmetric key or is derived from a previously distributed secret.
      No CEK is transported in the message.

Top      Up      ToC       Page 25 
   symmetric key-encryption keys (KEK):  The CEK is encrypted using a
      previously distributed symmetric KEK.  Also known as key wrap.

   key agreement:  The recipient's public key and a sender's private key
      are used to generate a pairwise secret, a Key Derivation Function
      (KDF) is applied to derive a key, and then the CEK is either the
      derived key or encrypted by the derived key.

   key transport:  The CEK is encrypted with the recipient's public key.
      No key transport algorithms are defined in this document.

   passwords:  The CEK is encrypted in a KEK that is derived from a
      password.  No password algorithms are defined in this document.

5.2.  Single Recipient Encrypted

   The COSE_Encrypt0 encrypted structure does not have the ability to
   specify recipients of the message.  The structure assumes that the
   recipient of the object will already know the identity of the key to
   be used in order to decrypt the message.  If a key needs to be
   identified to the recipient, the enveloped structure ought to be
   used.

   Examples of encrypted messages can be found in Appendix C.3.

   The COSE_Encrypt0 structure can be encoded as either tagged or
   untagged depending on the context it will be used in.  A tagged
   COSE_Encrypt0 structure is identified by the CBOR tag 16.  The CDDL
   fragment that represents this is:

   COSE_Encrypt0_Tagged = #6.16(COSE_Encrypt0)

   The COSE_Encrypt0 structure is a CBOR array.  The fields of the array
   in order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   ciphertext:  This is as described in Section 5.1.

   The CDDL fragment for COSE_Encrypt0 that corresponds to the above
   text is:

   COSE_Encrypt0 = [
       Headers,
       ciphertext : bstr / nil,
   ]

Top      Up      ToC       Page 26 
5.3.  How to Encrypt and Decrypt for AEAD Algorithms

   The encryption algorithm for AEAD algorithms is fairly simple.  The
   first step is to create a consistent byte stream for the
   authenticated data structure.  For this purpose, we use an
   Enc_structure.  The Enc_structure is a CBOR array.  The fields of the
   Enc_structure in order are:

   1.  A text string identifying the context of the authenticated data
       structure.  The context string is:

          "Encrypt0" for the content encryption of a COSE_Encrypt0 data
          structure.

          "Encrypt" for the first layer of a COSE_Encrypt data structure
          (i.e., for content encryption).

          "Enc_Recipient" for a recipient encoding to be placed in an
          COSE_Encrypt data structure.

          "Mac_Recipient" for a recipient encoding to be placed in a
          MACed message structure.

          "Rec_Recipient" for a recipient encoding to be placed in a
          recipient structure.

   2.  The protected attributes from the body structure encoded in a
       bstr type.  If there are no protected attributes, a bstr of
       length zero is used.

   3.  The protected attributes from the application encoded in a bstr
       type.  If this field is not supplied, it defaults to a zero-
       length bstr.  (See Section 4.3 for application guidance on
       constructing this field.)

   The CDDL fragment that describes the above text is:

   Enc_structure = [
       context : "Encrypt" / "Encrypt0" / "Enc_Recipient" /
           "Mac_Recipient" / "Rec_Recipient",
       protected : empty_or_serialized_map,
       external_aad : bstr
   ]

   How to encrypt a message:

   1.  Create an Enc_structure and populate it with the appropriate
       fields.

Top      Up      ToC       Page 27 
   2.  Encode the Enc_structure to a byte stream (Additional
       Authenticated Data (AAD)), using the encoding described in
       Section 14.

   3.  Determine the encryption key (K).  This step is dependent on the
       class of recipient algorithm being used.  For:

       No Recipients:  The key to be used is determined by the algorithm
          and key at the current layer.  Examples are key transport keys
          (Section 12.3), key wrap keys (Section 12.2.1), or pre-shared
          secrets.

       Direct Encryption and Direct Key Agreement:  The key is
          determined by the key and algorithm in the recipient
          structure.  The encryption algorithm and size of the key to be
          used are inputs into the KDF used for the recipient.  (For
          direct, the KDF can be thought of as the identity operation.)
          Examples of these algorithms are found in Sections 12.1.2 and
          12.4.1.

       Other:  The key is randomly or pseudorandomly generated.

   4.  Call the encryption algorithm with K (the encryption key), P (the
       plaintext), and AAD.  Place the returned ciphertext into the
       'ciphertext' field of the structure.

   5.  For recipients of the message, recursively perform the encryption
       algorithm for that recipient, using K (the encryption key) as the
       plaintext.

   How to decrypt a message:

   1.  Create an Enc_structure and populate it with the appropriate
       fields.

   2.  Encode the Enc_structure to a byte stream (AAD), using the
       encoding described in Section 14.

   3.  Determine the decryption key.  This step is dependent on the
       class of recipient algorithm being used.  For:

       No Recipients:  The key to be used is determined by the algorithm
          and key at the current layer.  Examples are key transport keys
          (Section 12.3), key wrap keys (Section 12.2.1), or pre-shared
          secrets.

Top      Up      ToC       Page 28 
       Direct Encryption and Direct Key Agreement:  The key is
          determined by the key and algorithm in the recipient
          structure.  The encryption algorithm and size of the key to be
          used are inputs into the KDF used for the recipient.  (For
          direct, the KDF can be thought of as the identity operation.)
          Examples of these algorithms are found in Sections 12.1.2 and
          12.4.1.

       Other:  The key is determined by decoding and decrypting one of
          the recipient structures.

   4.  Call the decryption algorithm with K (the decryption key to use),
       C (the ciphertext), and AAD.

5.4.  How to Encrypt and Decrypt for AE Algorithms

   How to encrypt a message:

   1.  Verify that the 'protected' field is empty.

   2.  Verify that there was no external additional authenticated data
       supplied for this operation.

   3.  Determine the encryption key.  This step is dependent on the
       class of recipient algorithm being used.  For:

       No Recipients:  The key to be used is determined by the algorithm
          and key at the current layer.  Examples are key transport keys
          (Section 12.3), key wrap keys (Section 12.2.1), or pre-shared
          secrets.

       Direct Encryption and Direct Key Agreement:  The key is
          determined by the key and algorithm in the recipient
          structure.  The encryption algorithm and size of the key to be
          used are inputs into the KDF used for the recipient.  (For
          direct, the KDF can be thought of as the identity operation.)
          Examples of these algorithms are found in Sections 12.1.2 and
          12.4.1.

       Other:  The key is randomly generated.

   4.  Call the encryption algorithm with K (the encryption key to use)
       and P (the plaintext).  Place the returned ciphertext into the
       'ciphertext' field of the structure.

   5.  For recipients of the message, recursively perform the encryption
       algorithm for that recipient, using K (the encryption key) as the
       plaintext.

Top      Up      ToC       Page 29 
   How to decrypt a message:

   1.  Verify that the 'protected' field is empty.

   2.  Verify that there was no external additional authenticated data
       supplied for this operation.

   3.  Determine the decryption key.  This step is dependent on the
       class of recipient algorithm being used.  For:

       No Recipients:  The key to be used is determined by the algorithm
          and key at the current layer.  Examples are key transport keys
          (Section 12.3), key wrap keys (Section 12.2.1), or pre-shared
          secrets.

       Direct Encryption and Direct Key Agreement:  The key is
          determined by the key and algorithm in the recipient
          structure.  The encryption algorithm and size of the key to be
          used are inputs into the KDF used for the recipient.  (For
          direct, the KDF can be thought of as the identity operation.)
          Examples of these algorithms are found in Sections 12.1.2 and
          12.4.1.

       Other:  The key is determined by decoding and decrypting one of
          the recipient structures.

   4.  Call the decryption algorithm with K (the decryption key to use)
       and C (the ciphertext).

6.  MAC Objects

   COSE supports two different MAC structures.  COSE_MAC0 is used when a
   recipient structure is not needed because the key to be used is
   implicitly known.  COSE_MAC is used for all other cases.  These
   include a requirement for multiple recipients, the key being unknown,
   and a recipient algorithm of other than direct.

   In this section, we describe the structure and methods to be used
   when doing MAC authentication in COSE.  This document allows for the
   use of all of the same classes of recipient algorithms as are allowed
   for encryption.

   When using MAC operations, there are two modes in which they can be
   used.  The first is just a check that the content has not been
   changed since the MAC was computed.  Any class of recipient algorithm
   can be used for this purpose.  The second mode is to both check that
   the content has not been changed since the MAC was computed and to
   use the recipient algorithm to verify who sent it.  The classes of

Top      Up      ToC       Page 30 
   recipient algorithms that support this are those that use a pre-
   shared secret or do static-static (SS) key agreement (without the key
   wrap step).  In both of these cases, the entity that created and sent
   the message MAC can be validated.  (This knowledge of the sender
   assumes that there are only two parties involved and that you did not
   send the message to yourself.)  The origination property can be
   obtained with both of the MAC message structures.

6.1.  MACed Message with Recipients

   The multiple recipient MACed message uses two structures: the
   COSE_Mac structure defined in this section for carrying the body and
   the COSE_recipient structure (Section 5.1) to hold the key used for
   the MAC computation.  Examples of MACed messages can be found in
   Appendix C.5.

   The MAC structure can be encoded as either tagged or untagged
   depending on the context it will be used in.  A tagged COSE_Mac
   structure is identified by the CBOR tag 97.  The CDDL fragment that
   represents this is:

   COSE_Mac_Tagged = #6.97(COSE_Mac)

   The COSE_Mac structure is a CBOR array.  The fields of the array in
   order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   payload:  This field contains the serialized content to be MACed.  If
      the payload is not present in the message, the application is
      required to supply the payload separately.  The payload is wrapped
      in a bstr to ensure that it is transported without changes.  If
      the payload is transported separately (i.e., detached content),
      then a nil CBOR value is placed in this location, and it is the
      responsibility of the application to ensure that it will be
      transported without changes.

   tag:  This field contains the MAC value.

   recipients:  This is as described in Section 5.1.

Top      Up      ToC       Page 31 
   The CDDL fragment that represents the above text for COSE_Mac
   follows.

   COSE_Mac = [
      Headers,
      payload : bstr / nil,
      tag : bstr,
      recipients :[+COSE_recipient]
   ]

6.2.  MACed Messages with Implicit Key

   In this section, we describe the structure and methods to be used
   when doing MAC authentication for those cases where the recipient is
   implicitly known.

   The MACed message uses the COSE_Mac0 structure defined in this
   section for carrying the body.  Examples of MACed messages with an
   implicit key can be found in Appendix C.6.

   The MAC structure can be encoded as either tagged or untagged
   depending on the context it will be used in.  A tagged COSE_Mac0
   structure is identified by the CBOR tag 17.  The CDDL fragment that
   represents this is:


   COSE_Mac0_Tagged = #6.17(COSE_Mac0)

   The COSE_Mac0 structure is a CBOR array.  The fields of the array in
   order are:

   protected:  This is as described in Section 3.

   unprotected:  This is as described in Section 3.

   payload:  This is as described in Section 6.1.

   tag:  This field contains the MAC value.

   The CDDL fragment that corresponds to the above text is:

   COSE_Mac0 = [
      Headers,
      payload : bstr / nil,
      tag : bstr,
   ]

Top      Up      ToC       Page 32 
6.3.  How to Compute and Verify a MAC

   In order to get a consistent encoding of the data to be
   authenticated, the MAC_structure is used to have a canonical form.
   The MAC_structure is a CBOR array.  The fields of the MAC_structure
   in order are:

   1.  A text string that identifies the structure that is being
       encoded.  This string is "MAC" for the COSE_Mac structure.  This
       string is "MAC0" for the COSE_Mac0 structure.

   2.  The protected attributes from the COSE_MAC structure.  If there
       are no protected attributes, a zero-length bstr is used.

   3.  The protected attributes from the application encoded as a bstr
       type.  If this field is not supplied, it defaults to a zero-
       length binary string.  (See Section 4.3 for application guidance
       on constructing this field.)

   4.  The payload to be MACed encoded in a bstr type.  The payload is
       placed here independent of how it is transported.

   The CDDL fragment that corresponds to the above text is:

   MAC_structure = [
        context : "MAC" / "MAC0",
        protected : empty_or_serialized_map,
        external_aad : bstr,
        payload : bstr
   ]

   The steps to compute a MAC are:

   1.  Create a MAC_structure and populate it with the appropriate
       fields.

   2.  Create the value ToBeMaced by encoding the MAC_structure to a
       byte stream, using the encoding described in Section 14.

   3.  Call the MAC creation algorithm passing in K (the key to use),
       alg (the algorithm to MAC with), and ToBeMaced (the value to
       compute the MAC on).

   4.  Place the resulting MAC in the 'tag' field of the COSE_Mac or
       COSE_Mac0 structure.

   5.  Encrypt and encode the MAC key for each recipient of the message.

Top      Up      ToC       Page 33 
   The steps to verify a MAC are:

   1.  Create a MAC_structure object and populate it with the
       appropriate fields.

   2.  Create the value ToBeMaced by encoding the MAC_structure to a
       byte stream, using the encoding described in Section 14.

   3.  Obtain the cryptographic key from one of the recipients of the
       message.

   4.  Call the MAC creation algorithm passing in K (the key to use),
       alg (the algorithm to MAC with), and ToBeMaced (the value to
       compute the MAC on).

   5.  Compare the MAC value to the 'tag' field of the COSE_Mac or
       COSE_Mac0 structure.



(page 33 continued on part 3)

Next Section