diff options
-rw-r--r-- | secure_fw/services/initial_attestation/CMakeLists.inc | 6 | ||||
-rw-r--r-- | secure_fw/services/initial_attestation/CMakeLists.txt | 4 | ||||
-rw-r--r-- | secure_fw/services/initial_attestation/attest_token.c | 106 | ||||
-rw-r--r-- | secure_fw/services/initial_attestation/attest_token.h | 13 | ||||
-rw-r--r-- | secure_fw/services/initial_attestation/attestation_core.c | 10 | ||||
-rw-r--r-- | test/CMakeLists.txt | 4 | ||||
-rw-r--r-- | test/suites/attestation/CMakeLists.inc | 4 | ||||
-rw-r--r-- | test/suites/attestation/attest_token_decode.c | 44 |
8 files changed, 111 insertions, 80 deletions
diff --git a/secure_fw/services/initial_attestation/CMakeLists.inc b/secure_fw/services/initial_attestation/CMakeLists.inc index 21d8e021f9..8abfae2286 100644 --- a/secure_fw/services/initial_attestation/CMakeLists.inc +++ b/secure_fw/services/initial_attestation/CMakeLists.inc @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2018-2019, Arm Limited. All rights reserved. +# Copyright (c) 2018-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -64,8 +64,8 @@ embedded_include_directories(PATH ${TFM_ROOT_DIR}/bl2/include ABSOLUTE) embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core/include ABSOLUTE) embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/spm ABSOLUTE) embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/inc ABSOLUTE) -embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/inc ABSOLUTE) -embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/src ABSOLUTE) +embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/t_cose/inc ABSOLUTE) +embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/t_cose/src ABSOLUTE) embedded_include_directories(PATH ${INITIAL_ATTESTATION_DIR} ABSOLUTE) set(BUILD_CMSIS_CORE Off) diff --git a/secure_fw/services/initial_attestation/CMakeLists.txt b/secure_fw/services/initial_attestation/CMakeLists.txt index 36f26b00f0..fb61f81ad5 100644 --- a/secure_fw/services/initial_attestation/CMakeLists.txt +++ b/secure_fw/services/initial_attestation/CMakeLists.txt @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2018-2019, Arm Limited. All rights reserved. +# Copyright (c) 2018-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -34,7 +34,7 @@ if (NOT TARGET tfm_qcbor_encode) endif() if (NOT TARGET tfm_t_cose_sign) - add_subdirectory(${TFM_ROOT_DIR}/lib/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose) + add_subdirectory(${TFM_ROOT_DIR}/lib/ext/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose) endif() #Specify what we build (for the initial attestation service, build as a static library) 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; } - diff --git a/secure_fw/services/initial_attestation/attest_token.h b/secure_fw/services/initial_attestation/attest_token.h index 14c080d99d..dffee0b7d5 100644 --- a/secure_fw/services/initial_attestation/attest_token.h +++ b/secure_fw/services/initial_attestation/attest_token.h @@ -2,6 +2,7 @@ * attest_token.h * * Copyright (c) 2018-2019, Laurence Lundblade. + * Copyright (c) 2020, Arm Limited. * * SPDX-License-Identifier: BSD-3-Clause * @@ -78,13 +79,15 @@ enum attest_token_err_t { ATTEST_TOKEN_ERR_INSUFFICIENT_MEMORY, /** Tampering detected in cryptographic function. */ ATTEST_TOKEN_ERR_TAMPERING_DETECTED, + /** Signing key is not found or of wrong type. */ + ATTEST_TOKEN_ERR_SIGNING_KEY, /** Verification key is not found or of wrong type. */ ATTEST_TOKEN_ERR_VERIFICATION_KEY, /** No token was given or validated */ ATTEST_TOKEN_ERR_NO_VALID_TOKEN, /** Data item with label wasn't found. */ ATTEST_TOKEN_ERR_NOT_FOUND, - /** SW Compoments absence not correctly indicated. */ + /** SW Components absence not correctly indicated. */ ATTEST_TOKEN_ERR_SW_COMPONENTS_MISSING }; @@ -122,10 +125,10 @@ enum attest_token_err_t { */ struct attest_token_ctx { /* Private data structure */ - QCBOREncodeContext cbor_enc_ctx; - uint32_t opt_flags; - int32_t key_select; - struct t_cose_sign1_ctx signer_ctx; + QCBOREncodeContext cbor_enc_ctx; + uint32_t opt_flags; + int32_t key_select; + struct t_cose_sign1_sign_ctx signer_ctx; }; diff --git a/secure_fw/services/initial_attestation/attestation_core.c b/secure_fw/services/initial_attestation/attestation_core.c index 4f2278904f..052107c02e 100644 --- a/secure_fw/services/initial_attestation/attestation_core.c +++ b/secure_fw/services/initial_attestation/attestation_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. + * Copyright (c) 2018-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * @@ -18,7 +18,7 @@ #include "tfm_attest_hal.h" #include "attest_token.h" #include "attest_eat_defines.h" -#include "t_cose_defines.h" +#include "t_cose_common.h" #include "tfm_memory_utils.h" #include "platform/include/tfm_plat_crypto_keys.h" @@ -950,9 +950,9 @@ attest_create_token(struct q_useful_buf_c *challenge, * which causes the COSE headers to be constructed. */ token_err = attest_token_start(&attest_token_ctx, - option_flags, /* option_flags */ - key_select, /* key_select */ - COSE_ALGORITHM_ES256, /* alg_select */ + option_flags, /* option_flags */ + key_select, /* key_select */ + T_COSE_ALGORITHM_ES256, /* alg_select */ token); if (token_err != ATTEST_TOKEN_ERR_SUCCESS) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 926a1f0ed2..b55f467868 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2017-2019, Arm Limited. All rights reserved. +# Copyright (c) 2017-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -134,7 +134,7 @@ if (NOT DEFINED TFM_BUILD_IN_SPE) endif() if (NOT TARGET tfm_t_cose_verify AND ENABLE_ATTESTATION_SERVICE_TESTS) - add_subdirectory(${TFM_ROOT_DIR}/lib/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose) + add_subdirectory(${TFM_ROOT_DIR}/lib/ext/t_cose ${CMAKE_CURRENT_BINARY_DIR}/t_cose) endif() if ((NOT TARGET tfm_qcbor_encode OR NOT TARGET tfm_qcbor_decode) AND (ENABLE_ATTESTATION_SERVICE_TESTS OR ENABLE_QCBOR_TESTS)) diff --git a/test/suites/attestation/CMakeLists.inc b/test/suites/attestation/CMakeLists.inc index 9b6d82829b..38c0eb1df0 100644 --- a/test/suites/attestation/CMakeLists.inc +++ b/test/suites/attestation/CMakeLists.inc @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------- -# Copyright (c) 2018-2019, Arm Limited. All rights reserved. +# Copyright (c) 2018-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -58,7 +58,7 @@ elseif(ENABLE_ATTESTATION_SERVICE_TESTS) embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/services/initial_attestation ABSOLUTE) embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/inc ABSOLUTE) embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/qcbor/util ABSOLUTE) - embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/t_cose/inc ABSOLUTE) + embedded_include_directories(PATH ${TFM_ROOT_DIR}/lib/ext/t_cose/inc ABSOLUTE) #Append all our source files to global lists. list(APPEND ALL_SRC_C_S ${ATTEST_TEST_SRC_S}) diff --git a/test/suites/attestation/attest_token_decode.c b/test/suites/attestation/attest_token_decode.c index ffb2a6fbef..3c3fd3e111 100644 --- a/test/suites/attestation/attest_token_decode.c +++ b/test/suites/attestation/attest_token_decode.c @@ -2,6 +2,7 @@ * attest_token_decode.c * * Copyright (c) 2019, Laurence Lundblade. + * Copyright (c) 2020, Arm Limited. * * SPDX-License-Identifier: BSD-3-Clause * @@ -12,6 +13,8 @@ #include "t_cose_sign1_verify.h" #include "q_useful_buf.h" #include "qcbor_util.h" +#include "psa/crypto.h" +#include "attest_public_key.h" /** @@ -155,24 +158,43 @@ enum attest_token_err_t attest_token_decode_validate_token(struct attest_token_decode_context *me, struct q_useful_buf_c token) { - enum t_cose_err_t t_cose_error; - enum attest_token_err_t return_value; - uint32_t t_cose_options; - - /* - * FIXME: check for CWT/EAT CBOR tag if requested - * FIXME: deal with the public key per t_cose_crypto.h - */ - - t_cose_options = 0; + enum t_cose_err_t t_cose_error; + enum attest_token_err_t return_value; + enum psa_attest_err_t attest_ret; + int32_t t_cose_options = 0; + struct t_cose_sign1_verify_ctx verify_ctx; + struct t_cose_key attest_key; + psa_key_handle_t public_key; + + /* Run the signature verification */ if(me->options & TOKEN_OPT_SHORT_CIRCUIT_SIGN) { t_cose_options |= T_COSE_OPT_ALLOW_SHORT_CIRCUIT; } - t_cose_error = t_cose_sign1_verify(t_cose_options, 0, token, &me->payload); + t_cose_sign1_verify_init(&verify_ctx, t_cose_options); + + attest_ret = attest_register_initial_attestation_public_key(&public_key); + if (attest_ret != PSA_ATTEST_ERR_SUCCESS) { + return ATTEST_TOKEN_ERR_VERIFICATION_KEY; + } + + attest_key.crypto_lib = T_COSE_CRYPTO_LIB_PSA; + attest_key.k.key_handle = public_key; + + t_cose_sign1_set_verification_key(&verify_ctx, attest_key); + + t_cose_error = t_cose_sign1_verify(&verify_ctx, + token, /* COSE to verify */ + &me->payload, /* Payload from token */ + NULL); /* Don't return parameters */ return_value = map_t_cose_errors(t_cose_error); me->last_error = return_value; + attest_ret = attest_unregister_initial_attestation_public_key(public_key); + if (attest_ret != PSA_ATTEST_ERR_SUCCESS) { + return ATTEST_TOKEN_ERR_GENERAL; + } + return return_value; } |