![]() |
TF-M Reference Manual
1.2.0
TrustedFirmware-M
|
Attestation Token Decoding Interface. More...
#include "q_useful_buf.h"
#include <stdbool.h>
#include "attest_token.h"
#include "attest_eat_defines.h"
Go to the source code of this file.
Data Structures | |
struct | attest_token_decode_context |
struct | attest_token_iat_simple_t |
struct | attest_token_sw_component_t |
Macros | |
#define | IS_ITEM_FLAG_SET(item_index, item_flags) (((0x01U << (item_index))) & (item_flags)) |
Enumerations | |
enum | attest_token_item_index_t { NONCE_FLAG = 0, UEID_FLAG = 1, BOOT_SEED_FLAG = 2, HW_VERSION_FLAG = 3, IMPLEMENTATION_ID_FLAG = 4, CLIENT_ID_FLAG = 5, SECURITY_LIFECYCLE_FLAG = 6, PROFILE_DEFINITION_FLAG = 7, ORIGINATION_FLAG = 8, NUMBER_OF_ITEMS = 9 } |
enum | attest_token_sw_index_t { SW_MEASUREMENT_TYPE_FLAG = 0, SW_MEASURMENT_VAL_FLAG = 1, SW_VERSION_FLAG = 3, SW_SIGNER_ID_FLAG = 5, SW_MEASUREMENT_DESC_FLAG = 6 } |
Functions | |
void | attest_token_decode_init (struct attest_token_decode_context *me, uint32_t options) |
Initialize token decoder. More... | |
enum attest_token_err_t | attest_token_decode_set_cose_pub_key (struct attest_token_decode_context *me, struct q_useful_buf cose_pub_key) |
Set specific public key to use for verification. More... | |
enum attest_token_err_t | attest_token_decode_set_pub_key_select (struct attest_token_decode_context *me, int32_t key_select) |
Set specific public key to use for verification. More... | |
enum attest_token_err_t | attest_token_decode_validate_token (struct attest_token_decode_context *me, struct q_useful_buf_c token) |
Set the token to work on and validate its signature. More... | |
enum attest_token_err_t | attest_token_decode_get_payload (struct attest_token_decode_context *me, struct q_useful_buf_c *payload) |
Get undecoded CBOR payload from the token. More... | |
enum attest_token_err_t | attest_token_decode_get_iat_simple (struct attest_token_decode_context *me, struct attest_token_iat_simple_t *items) |
Batch fetch of all simple data items in a token. More... | |
enum attest_token_err_t | attest_token_get_num_sw_components (struct attest_token_decode_context *me, uint32_t *num_sw_components) |
Get the number of SW components in the token. More... | |
enum attest_token_err_t | attest_token_get_sw_component (struct attest_token_decode_context *me, uint32_t requested_index, struct attest_token_sw_component_t *sw_components) |
Get the nth SW component. More... | |
enum attest_token_err_t | attest_token_decode_get_bstr (struct attest_token_decode_context *me, int32_t label, struct q_useful_buf_c *claim) |
Get a top-level claim, by integer label that is a byte string. More... | |
enum attest_token_err_t | attest_token_decode_get_tstr (struct attest_token_decode_context *me, int32_t label, struct q_useful_buf_c *claim) |
Get a top-level claim, by integer label that is a text string. More... | |
enum attest_token_err_t | attest_token_decode_get_int (struct attest_token_decode_context *me, int32_t label, int64_t *claim) |
Get a top-level claim by integer label who's value is a signed integer. More... | |
enum attest_token_err_t | attest_token_decode_get_uint (struct attest_token_decode_context *me, int32_t label, uint64_t *claim) |
Get a top-level claim by integer label who's value is an unsigned integer. More... | |
Attestation Token Decoding Interface.
The context and functions here are used to decode an attestation token as follows:
attest_token_get_xxx()
methods in any order. The strings returned by the these functions will point into the token passed to attest_token_decode_validate_token(). A copy is NOT made.The entire token is validated and decoded in place. No copies are made internally. The data returned by the attest_token_get_xxx()
methods is not a copy so the lifetime of the struct
q_useful_buf_c
containing the token must be maintained.
Aside from the cryptographic functions, this allocates no memory. It works entirely off the stack. It makes use of t_cose to validate the signature and QCBOR for CBOR decoding.
This decoder only works with labels (keys) that are integers even though labels can be any data type in CBOR. The presumption is that this is for small embedded use cases where space is a premium and only integer labels will be used.
All claims are optional in tokens. This decoder will ignore all CBOR encoded data that it doesn't understand without error.
This interface is primarily for the claims defined by Arm for TF-M. It includes only some of the claims from the EAT IETF draft, https://tools.ietf.org/html/draft-mandyam-eat-01.
The claims are not described in detail here. That is left to the definition documents and eventually an IETF standard.
If a method to get the claim you are interested in doesn't exist, there are several methods where you can give the label (the key) for the claim and have it returned. This only works for simple claims (strings and integers).
The entire payload can be retrieved unparsed. Then you can use a separate CBOR parser to decode the claims out of it. Future work may include more general facilities for handling claims with complex structures made up of maps and arrays.
This should not yet be considered a real commercial implementation of token decoding. It is close, but not there yet. It's purpose is to test token encoding. The main thing this needs to become a real commercial implementation is code that tests this. It is a parser / decoder, so a proper test involves a lot of hostile input.
Definition in file attest_token_decode.h.
#define IS_ITEM_FLAG_SET | ( | item_index, | |
item_flags | |||
) | (((0x01U << (item_index))) & (item_flags)) |
Macro to determine if data item is present in attest_token_iat_simple_t
Definition at line 293 of file attest_token_decode.h.
Label for bits in item_flags
in attest_token_iat_simple_t
Enumerator | |
---|---|
NONCE_FLAG | |
UEID_FLAG | |
BOOT_SEED_FLAG | |
HW_VERSION_FLAG | |
IMPLEMENTATION_ID_FLAG | |
CLIENT_ID_FLAG | |
SECURITY_LIFECYCLE_FLAG | |
PROFILE_DEFINITION_FLAG | |
ORIGINATION_FLAG | |
NUMBER_OF_ITEMS |
Definition at line 255 of file attest_token_decode.h.
Use IS_ITEM_FLAG_SET macro with these values and attest_token_sw_component_t.item_flags
to find out if the data item is filled in in the attest_token_sw_component_t structure.
Items that are of type struct
q_useful_buf_c
will also be NULL_Q_USEFUL_BUF_C
when they are absent.
Enumerator | |
---|---|
SW_MEASUREMENT_TYPE_FLAG | |
SW_MEASURMENT_VAL_FLAG | |
SW_VERSION_FLAG | |
SW_SIGNER_ID_FLAG | |
SW_MEASUREMENT_DESC_FLAG |
Definition at line 486 of file attest_token_decode.h.
enum attest_token_err_t attest_token_decode_get_bstr | ( | struct attest_token_decode_context * | me, |
int32_t | label, | ||
struct q_useful_buf_c * | claim | ||
) |
Get a top-level claim, by integer label that is a byte string.
[in] | me | The token decoder context. |
[in] | label | The integer label identifying the claim. |
[out] | claim | The byte string or NULL_Q_USEFUL_BUF_C . |
ATTEST_TOKEN_ERR_CBOR_STRUCTURE | General structure of the token is incorrect, for example the top level is not a map or some map wasn't closed. |
ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED | CBOR syntax is wrong and it is not decodable. |
ATTEST_TOKEN_ERR_CBOR_TYPE | Returned if the claim is not a byte string. |
ATTEST_TOKEN_ERR_NOT_FOUND | Data item for label was not found in token. |
If an error occurs, the claim will be set to NULL_Q_USEFUL_BUF_C
and the error state inside attest_token_decode_context
will be set.
Definition at line 64 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_decode_get_iat_simple | ( | struct attest_token_decode_context * | me, |
struct attest_token_iat_simple_t * | items | ||
) |
Batch fetch of all simple data items in a token.
[in] | me | The token decoder context. |
[out] | items | Structure into which all found items are placed. |
ATTEST_TOKEN_ERR_SUCCESS | Indicates that the token was successfully searched. It could mean that all the data item were found, only some were found, or even none were found. |
This searches the token for the simple unstructured data items all at once. It can be a little more efficient than getting them one by one.
Use IS_ITEM_FLAG_SET on item_flags
in attest_token_iat_simple_t
to determine if the data item was found or not and whether the corresponding member in the structure is valid.
Definition at line 252 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_decode_get_int | ( | struct attest_token_decode_context * | me, |
int32_t | label, | ||
int64_t * | claim | ||
) |
Get a top-level claim by integer label who's value is a signed integer.
[in] | me | The token decoder context. |
[in] | label | The integer label identifying the claim. |
[out] | claim | The signed integer or 0. |
ATTEST_TOKEN_ERR_CBOR_STRUCTURE | General structure of the token is incorrect, for example the top level is not a map or some map wasn't closed. |
ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED | CBOR syntax is wrong and it is not decodable. |
ATTEST_TOKEN_ERR_CBOR_TYPE | Returned if the claim is not a byte string. |
ATTEST_TOKEN_ERR_NOT_FOUND | Data item for label was not found in token. |
ATTEST_TOKEN_ERR_INTEGER_VALUE | Returned if the integer value is larger than INT64_MAX . |
This will succeed if the CBOR type of the claim is either a positive or negative integer as long as the value is between INT64_MIN
and INT64_MAX
.
See also attest_token_decode_get_uint().
If an error occurs the value 0 will be returned and the error inside the attest_token_decode_context
will be set.
Definition at line 128 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_decode_get_payload | ( | struct attest_token_decode_context * | me, |
struct q_useful_buf_c * | payload | ||
) |
Get undecoded CBOR payload from the token.
[in] | me | The token decoder context. |
[out] | payload | The returned, verified token payload. |
This will return an error if the signature over the payload did not validate.
This allows the caller to parse the payload with any CBOR decoder they wish to use. It also an "escape hatch" to get to claims in the token not supported by decoding in this implementation, for example claims that have non-integer labels.
Definition at line 224 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_decode_get_tstr | ( | struct attest_token_decode_context * | me, |
int32_t | label, | ||
struct q_useful_buf_c * | claim | ||
) |
Get a top-level claim, by integer label that is a text string.
[in] | me | The token decoder context. |
[in] | label | The integer label identifying the claim. |
[out] | claim | The byte string or NULL_Q_USEFUL_BUF_C . |
ATTEST_TOKEN_ERR_CBOR_STRUCTURE | General structure of the token is incorrect, for example the top level is not a map or some map wasn't closed. |
ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED | CBOR syntax is wrong and it is not decodable. |
ATTEST_TOKEN_ERR_CBOR_TYPE | Returned if the claim is not a byte string. |
ATTEST_TOKEN_ERR_NOT_FOUND | Data item for label was not found in token. |
Even though this is a text string, it is not NULL-terminated.
If an error occurs, the claim will be set to NULL_Q_USEFUL_BUF_C
and the error state inside attest_token_decode_context
will be set.
Definition at line 96 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_decode_get_uint | ( | struct attest_token_decode_context * | me, |
int32_t | label, | ||
uint64_t * | claim | ||
) |
Get a top-level claim by integer label who's value is an unsigned integer.
[in] | me | The token decoder context. |
[in] | label | The integer label identifying the claim. |
[out] | claim | The unsigned integer or 0. |
ATTEST_TOKEN_ERR_CBOR_STRUCTURE | General structure of the token is incorrect, for example the top level is not a map or some map wasn't closed. |
ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED | CBOR syntax is wrong and it is not decodable. |
ATTEST_TOKEN_ERR_CBOR_TYPE | Returned if the claim is not a byte string. |
ATTEST_TOKEN_ERR_NOT_FOUND | Data item for label was not found in token. |
ATTEST_TOKEN_ERR_INTEGER_VALUE | Returned if the integer value is negative. |
This will succeed if the CBOR type of the claim is either a positive or negative integer as long as the value is between 0 and MAX_UINT64
.
See also attest_token_decode_get_int().
If an error occurs the value 0 will be returned and the error inside the attest_token_decode_context
will be set.
Definition at line 176 of file attest_token_decode_common.c.
void attest_token_decode_init | ( | struct attest_token_decode_context * | me, |
uint32_t | options | ||
) |
Initialize token decoder.
[in] | me | The token decoder context to be initialized. |
[in] | options | Decoding options. |
Must be called on a attest_token_decode_context before use. An instance of attest_token_decode_context can be used again by calling this on it again.
Definition at line 52 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_decode_set_cose_pub_key | ( | struct attest_token_decode_context * | me, |
struct q_useful_buf | cose_pub_key | ||
) |
Set specific public key to use for verification.
[in] | me | The token decoder context to configure. |
[in] | cose_pub_key | A CBOR-encoded COSE_Key containing the public key to use for signature verification. |
(This has not been implemented yet)
The key type must work with the signing algorithm in the token being verified.
The kid
in the COSE_Key
must match the one in the token.
If there is no kid in the COSE_Key
it will be used no matter what kid is indicated in the token.
Once set, a key can be used for multiple verifications.
Calling this again will replace the previous key that was configured. It will also replace the key set by attest_token_decode_set_pub_key_select().
enum attest_token_err_t attest_token_decode_set_pub_key_select | ( | struct attest_token_decode_context * | me, |
int32_t | key_select | ||
) |
Set specific public key to use for verification.
[in] | me | The token decoder context to configure. |
[in] | key_select | Selects the key to verify. |
(This has not been implemented yet)
The key type must work with the signing algorithm in the token being verified.
The meaning of key_select depends on the platform this is running on.
Once set, a key can be used for multiple verifications.
Calling this again will replace the previous key that was configured. It will also replace the key set by attest_token_decode_set_cose_pub_key().
enum attest_token_err_t attest_token_decode_validate_token | ( | struct attest_token_decode_context * | me, |
struct q_useful_buf_c | token | ||
) |
Set the token to work on and validate its signature.
[in] | me | The token decoder context to validate with. |
[in] | token | The CBOR-encoded token to validate and decode. |
The signature on the token is validated. If it is successful the token and its payload is remembered in the attest_token_decode_context me
so the attest_token_decode_get_xxx()
functions can be called to get the various claims out of it.
Generally, a public key has to be configured for this to work. It can however validate short-circuit signatures even if one is not set.
The code for any error that occurs during validation is remembered in decode context. The attest_token_decode_get_xxx()
functions can be called and they will just return this error. The attest_token_decode_get_xxx()
functions will generally return 0 or NULL
if the token is in error.
It is thus possible to call attest_token_decode_validate_token() and all the attest_token_decode_get_xxx()
functions to parse the token and ignore the error codes as long as attest_token_decode_get_error() is called before any of the claim data returned is used.
Definition at line 30 of file attest_token_decode_asymmetric.c.
enum attest_token_err_t attest_token_get_num_sw_components | ( | struct attest_token_decode_context * | me, |
uint32_t * | num_sw_components | ||
) |
Get the number of SW components in the token.
[in] | me | The token decoder context. |
[out] | num_sw_components | The number of SW components in the token. |
If there are explicitly no SW components, this will return successfully and the num_sw_components
will be zero.
Per Arm's IAT specification the only two ways this will succeed are.
Definition at line 358 of file attest_token_decode_common.c.
enum attest_token_err_t attest_token_get_sw_component | ( | struct attest_token_decode_context * | me, |
uint32_t | requested_index, | ||
struct attest_token_sw_component_t * | sw_components | ||
) |
Get the nth SW component.
[in] | me | The token decoder context. |
[in] | requested_index | Index, from 0 to num_sw_components, of request component. |
[out] | sw_components | Place to return the details of the SW component |
ATTEST_TOKEN_ERR_NOT_FOUND | There were not requested_index in the token. |
ATTEST_TOKEN_ERR_CBOR_TYPE | The claim labeled to contain SW components is not an array. |
Definition at line 531 of file attest_token_decode_common.c.