diff options
Diffstat (limited to 'secure_fw/services/initial_attestation/attest_token.c')
-rw-r--r-- | secure_fw/services/initial_attestation/attest_token.c | 106 |
1 files changed, 56 insertions, 50 deletions
diff --git a/secure_fw/services/initial_attestation/attest_token.c b/secure_fw/services/initial_attestation/attest_token.c index 077a57b13f..78c0ee0fdf 100644 --- a/secure_fw/services/initial_attestation/attest_token.c +++ b/secure_fw/services/initial_attestation/attest_token.c @@ -2,6 +2,7 @@ * attest_token.c * * Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved. + * Copyright (c) 2020, Arm Limited. * * SPDX-License-Identifier: BSD-3-Clause * @@ -11,6 +12,10 @@ #include "attest_token.h" #include "qcbor.h" #include "t_cose_sign1_sign.h" +#include "t_cose_common.h" +#include "q_useful_buf.h" +#include "psa/crypto.h" +#include "attestation_key.h" /** @@ -19,7 +24,7 @@ * \brief Attestation token creation implementation * * Outline of token creation. Much of this occurs inside - * t_cose_sign1_init() and t_cose_sign1_finish(). + * t_cose_sign1_encode_parameters() and t_cose_sign1_encode_signature(). * * - Create encoder context * - Open the CBOR array that hold the \c COSE_Sign1 @@ -29,7 +34,7 @@ * - Unprotected Headers * - Key ID * - Open payload bstr - * - Write payload data… lots of it… + * - Write payload data lots of it * - Get bstr that is the encoded payload * - Compute signature * - Create a separate encoder context for \c Sig_structure @@ -64,6 +69,9 @@ static enum attest_token_err_t t_cose_err_to_attest_err(enum t_cose_err_t err) case T_COSE_ERR_UNSUPPORTED_HASH: return ATTEST_TOKEN_ERR_HASH_UNAVAILABLE; + case T_COSE_ERR_TOO_SMALL: + return ATTEST_TOKEN_ERR_TOO_SMALL; + default: /* A lot of the errors are not mapped because they are * primarily internal errors that should never happen. They @@ -83,40 +91,48 @@ enum attest_token_err_t attest_token_start(struct attest_token_ctx *me, int32_t cose_alg_id, const struct q_useful_buf *out_buf) { - /* approximate stack usage on 32-bit machine: 4 bytes */ - enum t_cose_err_t cose_return_value; - enum attest_token_err_t return_value; + enum t_cose_err_t cose_ret; + enum attest_token_err_t return_value = ATTEST_TOKEN_ERR_SUCCESS; + enum psa_attest_err_t attest_ret; + int32_t t_cose_options = 0; + struct t_cose_key attest_key; + psa_key_handle_t private_key; /* Remember some of the configuration values */ me->opt_flags = opt_flags; me->key_select = key_select; + if (opt_flags & TOKEN_OPT_SHORT_CIRCUIT_SIGN) { + t_cose_options |= T_COSE_OPT_SHORT_CIRCUIT_SIG; + } + t_cose_sign1_sign_init(&(me->signer_ctx), t_cose_options, cose_alg_id); + + attest_ret = + attest_get_initial_attestation_private_key_handle(&private_key); + if (attest_ret != PSA_ATTEST_ERR_SUCCESS) { + return ATTEST_TOKEN_ERR_SIGNING_KEY; + } + attest_key.crypto_lib = T_COSE_CRYPTO_LIB_PSA; + attest_key.k.key_handle = private_key; + + t_cose_sign1_set_signing_key(&(me->signer_ctx), + attest_key, + NULL_Q_USEFUL_BUF_C); /* No kid */ + /* Spin up the CBOR encoder */ QCBOREncode_Init(&(me->cbor_enc_ctx), *out_buf); - - /* Initialize COSE signer. This will cause the cose headers to be - * encoded and written into out_buf using me->cbor_enc_ctx + /* This will cause the cose headers to be encoded and written into + * out_buf using me->cbor_enc_ctx */ - cose_return_value = t_cose_sign1_init(&(me->signer_ctx), - opt_flags & - TOKEN_OPT_SHORT_CIRCUIT_SIGN, - cose_alg_id, - key_select, - &(me->cbor_enc_ctx)); - if(cose_return_value) { - return_value = t_cose_err_to_attest_err(cose_return_value); - goto Done; + cose_ret = t_cose_sign1_encode_parameters(&(me->signer_ctx), + &(me->cbor_enc_ctx)); + if (cose_ret) { + return_value = t_cose_err_to_attest_err(cose_ret); } - /* Open the payload-wrapping bstr */ - QCBOREncode_BstrWrap(&(me->cbor_enc_ctx)); - QCBOREncode_OpenMap(&(me->cbor_enc_ctx)); - return_value = ATTEST_TOKEN_ERR_SUCCESS; - -Done: return return_value; } @@ -183,10 +199,7 @@ enum attest_token_err_t attest_token_finish(struct attest_token_ctx *me, struct q_useful_buf_c *completed_token) { - /* approximate stack usage on 32-bit machine: 4 + 4 + 8 + 8 = 24 */ enum attest_token_err_t return_value = ATTEST_TOKEN_ERR_SUCCESS; - /* The payload with all the claims that is signed */ - struct q_useful_buf_c token_payload_ub; /* The completed and signed encoded cose_sign1 */ struct q_useful_buf_c completed_token_ub; QCBORError qcbor_result; @@ -194,35 +207,28 @@ attest_token_finish(struct attest_token_ctx *me, QCBOREncode_CloseMap(&(me->cbor_enc_ctx)); - /* Close off the payload-wrapping bstr. This gives us back the - * pointer and length of the payload that needs to be hashed as - * part of the signature - */ - QCBOREncode_CloseBstrWrap(&(me->cbor_enc_ctx), &token_payload_ub); - - /* Finish off the cose signature. This does all the interesting work of - hashing and signing */ - cose_return_value = - t_cose_sign1_finish(&(me->signer_ctx), token_payload_ub); - if(cose_return_value) { + /* -- Finish up the COSE_Sign1. This is where the signing happens -- */ + cose_return_value = t_cose_sign1_encode_signature(&(me->signer_ctx), + &(me->cbor_enc_ctx)); + if (cose_return_value) { /* Main errors are invoking the hash or signature */ return_value = t_cose_err_to_attest_err(cose_return_value); goto Done; } - /* Close off the CBOR encoding and return the completed token */ - qcbor_result = QCBOREncode_Finish(&(me->cbor_enc_ctx), - &completed_token_ub); - if(qcbor_result == QCBOR_ERR_BUFFER_TOO_SMALL) { - return_value = ATTEST_TOKEN_ERR_TOO_SMALL; - } else if (qcbor_result != QCBOR_SUCCESS) { - /* likely from array not closed, too many closes, ... */ - return_value = ATTEST_TOKEN_ERR_CBOR_FORMATTING; - } else { - *completed_token = completed_token_ub; - } + /* Finally close off the CBOR formatting and get the pointer and length + * of the resulting COSE_Sign1 + */ + qcbor_result = QCBOREncode_Finish(&(me->cbor_enc_ctx), &completed_token_ub); + if (qcbor_result == QCBOR_ERR_BUFFER_TOO_SMALL) { + return_value = ATTEST_TOKEN_ERR_TOO_SMALL; + } else if (qcbor_result != QCBOR_SUCCESS) { + /* likely from array not closed, too many closes, ... */ + return_value = ATTEST_TOKEN_ERR_CBOR_FORMATTING; + } else { + *completed_token = completed_token_ub; + } Done: - return return_value; + return return_value; } - |