Skip to main content

3. Header Parameters

  1. Header Parameters

The structure of COSE has been designed to have two buckets of information that are not considered to be part of the payload itself, but are used for holding information about content, algorithms, keys, or evaluation hints for the processing of the layer. These two buckets are available for use in all of the structures except for keys. While these buckets are present, they may not always be usable in all instances. For example, while the protected bucket is defined as part of the recipient structure, some of the algorithms used for recipient structures do not provide for authenticated data. If this is the case, the protected bucket is left empty.

Both buckets are implemented as CBOR maps. The map key is a "label" (Section 1.5). The value portion is dependent on the definition for the label. Both maps use the same set of label/value pairs. The integer and text-string values for labels have been divided into several sections, including a standard range, a private use range, and a range that is dependent on the algorithm selected. The defined labels can be found in the "COSE Header Parameters" IANA registry (Section 11.1).

The two buckets are:

protected: Contains parameters about the current layer that are cryptographically protected. This bucket MUST be empty if it is not going to be included in a cryptographic computation. This bucket is encoded in the message as a binary object. This value is obtained by CBOR encoding the protected map and wrapping it in a bstr object. Senders SHOULD encode a zero-length map as a zero- length byte string rather than as a zero-length map (encoded as h'a0'). The zero-length byte string encoding is preferred, because it is both shorter and the version used in the serialization structures for cryptographic computation. Recipients MUST accept both a zero-length byte string and a zero- length map encoded in a byte string.

  Wrapping the encoding with a byte string allows the protected map
to be transported with a greater chance that it will not be
altered accidentally in transit. (Badly behaved intermediates
could decode and re-encode, but this will result in a failure to
verify unless the re-encoded byte string is identical to the
decoded byte string.) This avoids the problem of all parties
needing to be able to do a common canonical encoding of the map
for input to cryptographic operations.

unprotected: Contains parameters about the current layer that are not cryptographically protected.

Only header parameters that deal with the current layer are to be placed at that layer. As an example of this, the header parameter "content type" describes the content of the message being carried in the message. As such, this header parameter is placed only in the content layer and is not placed in the recipient or signature layers. In principle, one should be able to process any given layer without reference to any other layer. With the exception of the COSE_Sign structure, the only data that needs to cross layers is the cryptographic key.

The buckets are present in all of the security objects defined in this document. The fields, in order, are the "protected" bucket (as a CBOR "bstr" type) and then the "unprotected" bucket (as a CBOR "map" type). The presence of both buckets is required. The header parameters that go into the buckets come from the IANA "COSE Header Parameters" registry (Section 11.1). Some header parameters are defined in the next section.

Labels in each of the maps MUST be unique. When processing messages, if a label appears multiple times, the message MUST be rejected as malformed. Applications SHOULD verify that the same label does not occur in both the protected and unprotected header parameters. If the message is not rejected as malformed, attributes MUST be obtained from the protected bucket, and only if an attribute is not found in the protected bucket can that attribute be obtained from the unprotected bucket.

The following CDDL fragment represents the two header-parameter buckets. A group "Headers" is defined in CDDL that represents the two buckets in which attributes are placed. This group is used to provide these two fields consistently in all locations. A type is also defined that represents the map of common header parameters.

Headers = (
protected : empty_or_serialized_map,
unprotected : header_map
)

header_map = {
Generic_Headers,
* label => values
}

empty_or_serialized_map = bstr .cbor header_map / bstr .size 0

3.1. Common COSE Header Parameters

This section defines a set of common header parameters. A summary of these header parameters can be found in Table 3. This table should be consulted to determine the value of the label and the type of the value.

The set of header parameters defined in this section is as follows:

alg: This header parameter is used to indicate the algorithm used for the security processing. This header parameter MUST be authenticated where the ability to do so exists. This support is provided by AEAD algorithms or construction (e.g., COSE_Sign and COSE_Mac0). This authentication can be done either by placing the header parameter in the protected-header-parameters bucket or as part of the externally supplied data (Section 4.3). The value is taken from the "COSE Algorithms" registry (see [COSE.Algorithms]).

crit: This header parameter is used to indicate which protected header parameters an application that is processing a message is required to understand. Header parameters defined in this document do not need to be included, as they should be understood by all implementations. Additionally, the header parameter "counter signature" (label 7) defined by [RFC8152] must be understood by new implementations, to remain compatible with senders that adhere to that document and assume all implementations will understand it. When present, the "crit" header parameter MUST be placed in the protected-header-parameters bucket. The array MUST have at least one value in it.

  Not all header-parameter labels need to be included in the "crit"
header parameter. The rules for deciding which header parameters
are placed in the array are:

* Integer labels in the range of 0 to 7 SHOULD be omitted.

* Integer labels in the range -1 to -128 can be omitted.
Algorithms can assign labels in this range where the ability to
process the content of the label is considered to be core to
implementing the algorithm. Algorithms can assign labels
outside of this range and include them in the "crit" header
parameter when the ability to process the content of the label
is not considered to be core functionality of the algorithm but
does need to be understood to correctly process this instance.
Integer labels in the range -129 to -65536 SHOULD be included,
as these would be less common header parameters that might not
be generally supported.

* Labels for header parameters required for an application MAY be
omitted. Applications should have a statement declaring
whether or not the label can be omitted.

The header parameters indicated by "crit" can be processed by
either the security-library code or an application using a
security library; the only requirement is that the header
parameter is processed. If the "crit" value list includes a label
for which the header parameter is not in the protected-header-
parameters bucket, this is a fatal error in processing the
message.

content type: This header parameter is used to indicate the content type of the data in the "payload" or "ciphertext" field. Integers are from the "CoAP Content-Formats" IANA registry table [COAP.Formats]. Text values follow the syntax of "<type- name>/<subtype-name>", where <type-name> and <subtype-name> are defined in Section 4.2 of [RFC6838]. Leading and trailing whitespace is not permitted. Textual content type values, along with parameters and subparameters, can be located using the IANA "Media Types" registry. Applications SHOULD provide this header parameter if the content structure is potentially ambiguous.

kid: This header parameter identifies one piece of data that can be used as input to find the needed cryptographic key. The value of this header parameter can be matched against the "kid" member in a COSE_Key structure. Other methods of key distribution can define an equivalent field to be matched. Applications MUST NOT assume that "kid" values are unique. There may be more than one key with the same "kid" value, so all of the keys associated with this "kid" may need to be checked. The internal structure of "kid" values is not defined and cannot be relied on by applications. Key identifier values are hints about which key to use. This is not a security-critical field. For this reason, it can be placed in the unprotected-header-parameters bucket.

IV: This header parameter holds the Initialization Vector (IV) value. For some symmetric encryption algorithms, this may be referred to as a nonce. The IV can be placed in the unprotected bucket, since for AE and AEAD algorithms, modifying the IV will cause the decryption to fail.

Partial IV: This header parameter holds a part of the IV value. When using the COSE_Encrypt0 structure, a portion of the IV can be part of the context associated with the key (Context IV), while a portion can be changed with each message (Partial IV). This field is used to carry a value that causes the IV to be changed for each message. The Partial IV can be placed in the unprotected bucket, as modifying the value will cause the decryption to yield plaintext that is readily detectable as garbled. The "Initialization Vector" and "Partial Initialization Vector" header parameters MUST NOT both be present in the same security layer.

  The message IV is generated by the following steps:

1. Left-pad the Partial IV with zeros to the length of IV
(determined by the algorithm).

2. XOR the padded Partial IV with the Context IV.

+=========+=======+========+=====================+==================+ | Name | Label | Value | Value Registry | Description | | | | Type | | | +=========+=======+========+=====================+==================+ | alg | 1 | int / | COSE Algorithms | Cryptographic | | | | tstr | registry | algorithm to use | +---------+-------+--------+---------------------+------------------+ | crit | 2 | [+ | COSE Header | Critical header | | | | label] | Parameters | parameters to be | | | | | registry | understood | +---------+-------+--------+---------------------+------------------+ | content | 3 | tstr / | CoAP Content- | Content type of | | type | | uint | Formats or Media | the payload | | | | | Types registries | | +---------+-------+--------+---------------------+------------------+ | kid | 4 | bstr | | Key identifier | +---------+-------+--------+---------------------+------------------+ | IV | 5 | bstr | | Full | | | | | | Initialization | | | | | | Vector | +---------+-------+--------+---------------------+------------------+ | Partial | 6 | bstr | | Partial | | IV | | | | Initialization | | | | | | Vector | +---------+-------+--------+---------------------+------------------+

                 Table 3: Common Header Parameters

The CDDL fragment that represents the set of header parameters defined in this section is given below. Each of the header parameters is tagged as optional, because they do not need to be in every map; header parameters required in specific maps are discussed above.

Generic_Headers = ( ? 1 => int / tstr, ; algorithm identifier ? 2 => [+label], ; criticality ? 3 => tstr / int, ; content type ? 4 => bstr, ; key identifier ? ( 5 => bstr // ; IV 6 => bstr ) ; Partial IV )