aboutsummaryrefslogtreecommitdiff
path: root/secure_fw/services/initial_attestation/attest_token.c
diff options
context:
space:
mode:
Diffstat (limited to 'secure_fw/services/initial_attestation/attest_token.c')
-rw-r--r--secure_fw/services/initial_attestation/attest_token.c106
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;
}
-