Dev APIs: Updating the testsuite with enhancements and fixes
- Attest: Move token verification from PAL to VAL layer
- Attest: Support to obtain public key from platform
- Crypto: Bug fixes and resolving stack overflow issues
- Crypto: HKDF does not take a LABEL or SEED input
- Attest: Utilizing token size buffer from PSA spec
- Attest: Key ID not mandatory in attestation token
Signed-off-by: Gowtham Siddarth <gowtham.siddarth@arm.com>
diff --git a/api-tests/CMakeLists.txt b/api-tests/CMakeLists.txt
index a43c3ae..625fb62 100644
--- a/api-tests/CMakeLists.txt
+++ b/api-tests/CMakeLists.txt
@@ -365,6 +365,7 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
add_dependencies(${PSA_TARGET_QCBOR} ${PSA_TARGET_GENERATE_DATABASE_POST})
add_dependencies(${PSA_TARGET_PAL_NSPE_LIB} ${PSA_TARGET_QCBOR})
+add_dependencies(${PSA_TARGET_VAL_NSPE_LIB} ${PSA_TARGET_QCBOR})
else()
add_dependencies(${PSA_TARGET_PAL_NSPE_LIB} ${PSA_TARGET_GENERATE_DATABASE_POST})
endif()
diff --git a/api-tests/dev_apis/crypto/test_c002/test_c002.c b/api-tests/dev_apis/crypto/test_c002/test_c002.c
index 3cee88c..a23a797 100644
--- a/api-tests/dev_apis/crypto/test_c002/test_c002.c
+++ b/api-tests/dev_apis/crypto/test_c002/test_c002.c
@@ -146,7 +146,7 @@
status = val->crypto_function(VAL_CRYPTO_IMPORT_KEY, &attributes, key_data,
check1[i].key_length, &check1[i].key_handle);
- TEST_ASSERT_EQUAL(status, PSA_ERROR_INVALID_ARGUMENT, TEST_CHECKPOINT_NUM(12));
+ TEST_ASSERT_NOT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(12));
TEST_ASSERT_EQUAL(check1[i].key_handle, 0, TEST_CHECKPOINT_NUM(13));
}
diff --git a/api-tests/dev_apis/crypto/test_c009/test_data.h b/api-tests/dev_apis/crypto/test_c009/test_data.h
index 647537b..d485067 100644
--- a/api-tests/dev_apis/crypto/test_c009/test_data.h
+++ b/api-tests/dev_apis/crypto/test_c009/test_data.h
@@ -52,14 +52,14 @@
PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)),
"abcdefghijklmnop", 16,
PSA_KEY_DERIVATION_INPUT_LABEL,
- PSA_SUCCESS,
+ PSA_ERROR_INVALID_ARGUMENT,
},
{"Test psa_key_derivation_input_bytes - Step as seed\n",
PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)),
"abcdefghijklmnop", 16,
PSA_KEY_DERIVATION_INPUT_SEED,
- PSA_SUCCESS,
+ PSA_ERROR_INVALID_ARGUMENT,
},
{"Test psa_key_derivation_input_bytes - Invalid step\n",
diff --git a/api-tests/dev_apis/crypto/test_c032/test_c032.c b/api-tests/dev_apis/crypto/test_c032/test_c032.c
index c246c0c..aa35e30 100644
--- a/api-tests/dev_apis/crypto/test_c032/test_c032.c
+++ b/api-tests/dev_apis/crypto/test_c032/test_c032.c
@@ -116,11 +116,14 @@
status = val->crypto_function(VAL_CRYPTO_CIPHER_ENCRYPT_SETUP, &operation,
check1[i].key_handle, check1[i].key_alg);
TEST_ASSERT_EQUAL(status, check1[i].expected_status, TEST_CHECKPOINT_NUM(6));
+
+ status = val->crypto_function(VAL_CRYPTO_CIPHER_ABORT, &operation);
+ TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(7));
}
/* Destroy the key */
status = val->crypto_function(VAL_CRYPTO_DESTROY_KEY, check1[i].key_handle);
- TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(7));
+ TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(8));
/* Reset the key attributes and check if psa_import_key fails */
val->crypto_function(VAL_CRYPTO_RESET_KEY_ATTRIBUTES, &attributes);
@@ -157,6 +160,9 @@
status = val->crypto_function(VAL_CRYPTO_CIPHER_ENCRYPT_SETUP, &operation,
0, check2[i].key_alg);
TEST_ASSERT_EQUAL(status, PSA_ERROR_INVALID_HANDLE, TEST_CHECKPOINT_NUM(4));
+
+ status = val->crypto_function(VAL_CRYPTO_CIPHER_ABORT, &operation);
+ TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(5));
}
return VAL_STATUS_SUCCESS;
diff --git a/api-tests/dev_apis/crypto/test_c033/test_c033.c b/api-tests/dev_apis/crypto/test_c033/test_c033.c
index c44e115..4899f10 100644
--- a/api-tests/dev_apis/crypto/test_c033/test_c033.c
+++ b/api-tests/dev_apis/crypto/test_c033/test_c033.c
@@ -115,11 +115,15 @@
status = val->crypto_function(VAL_CRYPTO_CIPHER_DECRYPT_SETUP, &operation,
check1[i].key_handle, check1[i].key_alg);
TEST_ASSERT_EQUAL(status, check1[i].expected_status, TEST_CHECKPOINT_NUM(6));
+
+ /* Abort a cipher operation */
+ status = val->crypto_function(VAL_CRYPTO_CIPHER_ABORT, &operation);
+ TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(7));
}
/* Destroy the key */
status = val->crypto_function(VAL_CRYPTO_DESTROY_KEY, check1[i].key_handle);
- TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(7));
+ TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(8));
/* Reset the key attributes and check if psa_import_key fails */
val->crypto_function(VAL_CRYPTO_RESET_KEY_ATTRIBUTES, &attributes);
@@ -157,6 +161,8 @@
0, check2[i].key_alg);
TEST_ASSERT_EQUAL(status, PSA_ERROR_INVALID_HANDLE, TEST_CHECKPOINT_NUM(4));
+ status = val->crypto_function(VAL_CRYPTO_CIPHER_ABORT, &operation);
+ TEST_ASSERT_EQUAL(status, PSA_SUCCESS, TEST_CHECKPOINT_NUM(5));
}
return VAL_STATUS_SUCCESS;
diff --git a/api-tests/dev_apis/crypto/test_c037/test_c037.c b/api-tests/dev_apis/crypto/test_c037/test_c037.c
index 40ee54b..86c2931 100644
--- a/api-tests/dev_apis/crypto/test_c037/test_c037.c
+++ b/api-tests/dev_apis/crypto/test_c037/test_c037.c
@@ -56,6 +56,7 @@
val->print(PRINT_TEST, "[Check %d] ", g_test_count++);
val->print(PRINT_TEST, check1[i].test_desc, 0);
memset(&operation, 0, sizeof(operation));
+ memset(&invalid_operation, 0, sizeof(invalid_operation));
/* Setting up the watchdog timer for each check */
status = val->wd_reprogram_timer(WD_CRYPTO_TIMEOUT);
diff --git a/api-tests/dev_apis/crypto/test_c050/test_c050.c b/api-tests/dev_apis/crypto/test_c050/test_c050.c
index 3d91281..8499fc1 100644
--- a/api-tests/dev_apis/crypto/test_c050/test_c050.c
+++ b/api-tests/dev_apis/crypto/test_c050/test_c050.c
@@ -27,12 +27,12 @@
NULL,
};
-static int g_test_count = 1;
+static int g_test_count = 1;
+static uint8_t data[BUFFER_SIZE];
int32_t psa_open_key_test(caller_security_t caller)
{
int32_t status, i = 0;
- uint8_t data[BUFFER_SIZE];
size_t length, get_key_bits;
const uint8_t *key_data;
psa_key_type_t get_key_type;
diff --git a/api-tests/dev_apis/crypto/test_c059/test_c059.c b/api-tests/dev_apis/crypto/test_c059/test_c059.c
index ce94a95..86f3fb7 100644
--- a/api-tests/dev_apis/crypto/test_c059/test_c059.c
+++ b/api-tests/dev_apis/crypto/test_c059/test_c059.c
@@ -26,12 +26,12 @@
NULL,
};
-static int g_test_count = 1;
+static int g_test_count = 1;
+static uint8_t output[BUFFER_SIZE], tag[SIZE_128B];
int32_t psa_aead_finish_test(caller_security_t caller)
{
int32_t i, status;
- uint8_t output[BUFFER_SIZE], tag[SIZE_128B];
size_t length, tag_length;
int num_checks = sizeof(check1)/sizeof(check1[0]);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
diff --git a/api-tests/dev_apis/crypto/test_c061/test_c061.c b/api-tests/dev_apis/crypto/test_c061/test_c061.c
index d1bbe39..4b6bec9 100644
--- a/api-tests/dev_apis/crypto/test_c061/test_c061.c
+++ b/api-tests/dev_apis/crypto/test_c061/test_c061.c
@@ -26,12 +26,12 @@
NULL,
};
-static int g_test_count = 1;
+static int g_test_count = 1;
+static uint8_t output[BUFFER_SIZE], tag[SIZE_128B];
int32_t psa_aead_verify_test(caller_security_t caller)
{
int32_t i, status;
- uint8_t output[BUFFER_SIZE], tag[SIZE_128B];
size_t length;
int num_checks = sizeof(check1)/sizeof(check1[0]);
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
diff --git a/api-tests/dev_apis/initial_attestation/suite.cmake b/api-tests/dev_apis/initial_attestation/suite.cmake
index ddb3128..913f7a4 100644
--- a/api-tests/dev_apis/initial_attestation/suite.cmake
+++ b/api-tests/dev_apis/initial_attestation/suite.cmake
@@ -35,6 +35,12 @@
add_definitions(${AS_OPTIONS})
add_library(${PSA_TARGET_TEST_COMBINE_LIB} STATIC ${SUITE_CC_SOURCE} ${SUITE_AS_SOURCE})
+if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
+target_include_directories(${PSA_TARGET_TEST_COMBINE_LIB} PRIVATE
+ ${PSA_QCBOR_INCLUDE_PATH}
+)
+endif()
+
# Test related Include directories
foreach(test ${PSA_TEST_LIST})
target_include_directories(${PSA_TARGET_TEST_COMBINE_LIB} PRIVATE ${PSA_SUITE_DIR}/${test})
diff --git a/api-tests/docs/psa_attestation_testlist.md b/api-tests/docs/psa_attestation_testlist.md
index 12153ad..c43cbe4 100644
--- a/api-tests/docs/psa_attestation_testlist.md
+++ b/api-tests/docs/psa_attestation_testlist.md
@@ -12,7 +12,9 @@
1. In verifying the token, only the data type of claims and presence of the mandatory claims are checked and the values of the claims are not checked. <br />
2. Specify the version of underlying PSA crypto in <psa-arch-tests>/api-tests/platform/targets/<target_name>/nspe/common/pal_config.h <br />
-3. Supported crypto versions are CRYPTO_VERSION_BETA1, CRYPTO_VERSION_BETA2 and CRYPTO_VERSION_BETA3
+3. Supported crypto versions are CRYPTO_VERSION_BETA1, CRYPTO_VERSION_BETA2 and CRYPTO_VERSION_BETA3 <br />
+4. Signer ID and Version fields of the software component must be present to be compliant with the PSA-SM <br />
+5. Define the macro PLATFORM_OVERRIDE_ATTEST_PK in <psa-arch-tests>/api-tests/platform/targets/<target_name>/nspe/common/pal_config.h to use hardcoded public key <br />
# License
Arm PSA test suite is distributed under Apache v2.0 License.
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/common/pal_config.h
index 2871339..61db8d8 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/common/pal_config.h
@@ -43,6 +43,9 @@
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c
index 2da03fa..04fe5ef 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c
@@ -19,29 +19,13 @@
static uint32_t public_key_registered;
static psa_key_handle_t public_key_handle;
+
static inline struct q_useful_buf_c useful_buf_head(struct q_useful_buf_c buf,
size_t amount)
{
return UsefulBuf_Head(buf, amount);
}
-static psa_ecc_curve_t attest_map_elliptic_curve_type(int32_t cose_curve)
-{
- psa_ecc_curve_t psa_curve;
-
- /*FixMe: Mapping is not complete, missing ones: P384, P521, ED25519, ED448 */
- switch (cose_curve)
- {
- case P_256:
- psa_curve = PSA_ECC_CURVE_SECP256R1;
- break;
- default:
- psa_curve = USHRT_MAX;
- }
-
- return psa_curve;
-}
-
static psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
{
psa_algorithm_t status;
@@ -137,6 +121,15 @@
return status;
}
+/**
+ @brief - Computes hash for the requested data
+ @param - cose_alg_id : Algorithm ID
+ - buffer_for_hash : Temp buffer for calculating hash
+ - hash : Pointer to store the hash
+ - protected_headers : Buffer containing protected data
+ - payload : payload data
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_compute_hash(int32_t cose_alg_id, struct q_useful_buf buffer_for_hash,
struct q_useful_buf_c *hash, struct q_useful_buf_c protected_headers,
struct q_useful_buf_c payload)
@@ -203,22 +196,56 @@
return status;
}
+static int32_t pal_attest_get_public_key(uint8_t *public_key_buff, size_t public_key_buf_size,
+ size_t *public_key_len, psa_ecc_curve_t *elliptic_curve_type)
+{
+ int32_t status = PAL_ATTEST_ERROR;
+
+#ifdef PLATFORM_OVERRIDE_ATTEST_PK
+ if (public_key_buf_size < (attest_key.pubx_key_size + attest_key.puby_key_size + 1))
+ return PAL_ATTEST_ERR_SMALL_BUFFER;
+
+ *public_key_len = (attest_key.pubx_key_size + attest_key.puby_key_size + 1);
+ *elliptic_curve_type = PSA_ECC_CURVE_SECP256R1;
+ memcpy(public_key_buff, (void *)&attest_public_key, *public_key_len);
+ status = PSA_SUCCESS;
+#else
+ status = tfm_initial_attest_get_public_key(public_key_buff,
+ public_key_buf_size,
+ public_key_len,
+ elliptic_curve_type);
+#endif
+
+ return status;
+}
+
static uint32_t pal_import_attest_key(psa_algorithm_t key_alg)
{
psa_status_t status = PAL_ATTEST_ERROR;
psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY;
- psa_ecc_curve_t psa_curve = attest_map_elliptic_curve_type(P_256);
- psa_key_type_t attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve);
- size_t public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
+ psa_ecc_curve_t ecc_curve;
+ psa_key_type_t attest_key_type;
+ size_t public_key_size;
+ uint8_t public_key_buff[ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH] = {0};
#if defined(CRYPTO_VERSION_BETA1) || defined(CRYPTO_VERSION_BETA2)
psa_key_policy_t policy;
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Setup the key policy for public key */
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, key_alg);
@@ -234,8 +261,8 @@
/* Import the public key */
status = psa_import_key(public_key_handle,
attest_key_type,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1);
+ public_key_buff,
+ public_key_size);
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -247,21 +274,30 @@
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Set the attributes for the public key */
psa_set_key_type(&attributes, attest_key_type);
- psa_set_key_bits(&attributes, public_key_size + 1);
+ psa_set_key_bits(&attributes, public_key_size);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, key_alg);
/* Import the public key */
status = psa_import_key(&attributes,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1,
+ public_key_buff,
+ public_key_size,
&public_key_handle);
-
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -288,6 +324,13 @@
return PAL_ATTEST_SUCCESS;
}
+/**
+ @brief - Verify the signature using the public key
+ @param - cose_algorithm_id : Algorithm ID
+ - token_hash : Data that needs to be verified
+ - signature : Signature to be verified against
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id,
struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature)
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h
index bd47990..559a24c 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h
@@ -15,12 +15,15 @@
* limitations under the License.
**/
-#include "pal_common.h"
+#ifndef _PAL_ATTESTATION_CRYPTO_H_
+#define _PAL_ATTESTATION_CRYPTO_H_
+
#include "pal_attestation_eat.h"
-#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH (1 + 2 * PSA_BITS_TO_BYTES(256))
-typedef struct{
+typedef struct {
uint8_t *pubx_key;
size_t pubx_key_size;
uint8_t *puby_key;
@@ -47,16 +50,14 @@
0x0F, 0x34, 0x11, 0x7D, 0x97, 0x1D, 0x68, 0x64},
};
-static const uint8_t initial_attestation_public_x_key[] =
-{
+static const uint8_t initial_attestation_public_x_key[] = {
0x79, 0xEB, 0xA9, 0x0E, 0x8B, 0xF4, 0x50, 0xA6,
0x75, 0x15, 0x76, 0xAD, 0x45, 0x99, 0xB0, 0x7A,
0xDF, 0x93, 0x8D, 0xA3, 0xBB, 0x0B, 0xD1, 0x7D,
0x00, 0x36, 0xED, 0x49, 0xA2, 0xD0, 0xFC, 0x3F
};
-static const uint8_t initial_attestation_public_y_key[] =
-{
+static const uint8_t initial_attestation_public_y_key[] = {
0xBF, 0xCD, 0xFA, 0x89, 0x56, 0xB5, 0x68, 0xBF,
0xDB, 0x86, 0x73, 0xE6, 0x48, 0xD8, 0xB5, 0x8D,
0x92, 0x99, 0x55, 0xB1, 0x4A, 0x26, 0xC3, 0x08,
@@ -84,5 +85,4 @@
struct q_useful_buf_c payload);
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id, struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature);
-
-
+#endif /* _PAL_ATTESTATION_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.c b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.c
deleted file mode 100644
index 68c4312..0000000
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @file
- * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
- * SPDX-License-Identifier : Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-**/
-
-#include "pal_attestation_crypto.h"
-
-uint32_t mandatory_claims = 0;
-uint32_t mandaroty_sw_components = 0;
-bool_t sw_component_present = 0;
-
-int pal_encode_cose_key(struct q_useful_buf_c *cose_key,
- struct q_useful_buf buffer_for_cose_key,
- struct q_useful_buf_c x_cord, struct q_useful_buf_c y_cord)
-{
- uint32_t return_value;
- QCBORError qcbor_result;
- QCBOREncodeContext cbor_encode_ctx;
- int32_t cose_curve_id = P_256;
- struct q_useful_buf_c encoded_key_id;
-
- /* Get the public key x and y */
- /* Encode it into a COSE_Key structure */
- QCBOREncode_Init(&cbor_encode_ctx, buffer_for_cose_key);
- QCBOREncode_OpenMap(&cbor_encode_ctx);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_COMMON_KTY,
- COSE_KEY_TYPE_EC2);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_CRV,
- cose_curve_id);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_X_COORDINATE,
- x_cord);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_Y_COORDINATE,
- y_cord);
- QCBOREncode_CloseMap(&cbor_encode_ctx);
-
- qcbor_result = QCBOREncode_Finish(&cbor_encode_ctx, &encoded_key_id);
- if (qcbor_result != QCBOR_SUCCESS)
- {
- /* Mainly means that the COSE_Key was too big for buffer_for_cose_key */
- return_value = PAL_ATTEST_ERR_PROTECTED_HEADERS;
- goto Done;
- }
-
- /* Finish up and return */
- *cose_key = encoded_key_id;
- return_value = PAL_ATTEST_SUCCESS;
-
-Done:
- return return_value;
-}
-
-
-static int get_items_in_map(QCBORDecodeContext *decode_context,
- struct items_to_get_t *item_list)
-{
- int item_index;
- QCBORItem item;
- struct items_to_get_t *item_ptr = item_list;
-
- /* initialize the data type of all items in the list */
- while (item_ptr->label != 0)
- {
- item_ptr->item.uDataType = QCBOR_TYPE_NONE;
- item_ptr++;
- }
-
- QCBORDecode_GetNext(decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_MAP)
- {
- return PAL_ATTEST_ERROR;
- }
-
- for (item_index = item.val.uCount; item_index != 0; item_index--)
- {
- if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- if (item.uLabelType != QCBOR_TYPE_INT64)
- {
- continue;
- }
-
- item_ptr = item_list;
- while (item_ptr->label != 0)
- {
- if (item.label.int64 == item_ptr->label)
- {
- item_ptr->item = item;
- }
- item_ptr++;
- }
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int get_item_in_map(QCBORDecodeContext *decode_context,
- int32_t label,
- QCBORItem *item)
-{
- struct items_to_get_t item_list[2];
-
- item_list[0].label = label;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- *item = item_list[0].item;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
- struct q_useful_buf_c *child)
-{
- struct items_to_get_t item_list[3];
-
- item_list[0].label = COSE_HEADER_PARAM_KID;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERR_CBOR_STRUCTURE;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_protected_headers(struct q_useful_buf_c protected_headers,
- int32_t *alg_id)
-{
- QCBORDecodeContext decode_context;
- QCBORItem item;
-
- QCBORDecode_Init(&decode_context, protected_headers, 0);
-
- if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (QCBORDecode_Finish(&decode_context))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
- {
- return PAL_ATTEST_ERROR;
- }
-
- *alg_id = (int32_t)item.val.int64;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-/**
- @brief - This API will verify the claims
- @param - decode_context : The buffer containing the challenge
- item : context for decoding the data items
- completed_challenge : Buffer containing the challenge
- @return - error status
-**/
-static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
- struct q_useful_buf_c completed_challenge)
-{
- int i, count = 0;
- int status = PAL_ATTEST_SUCCESS;
-
- /* Parse each claim and validate their data type */
- while (status == PAL_ATTEST_SUCCESS)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- break;
-
- mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
- if (item.uLabelType == QCBOR_TYPE_INT64)
- {
- if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
- {
- if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
- {
- /* Given challenge vs challenge in token */
- if (UsefulBuf_Compare(item.val.string, completed_challenge))
- return PAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
- }
- else
- return PAL_ATTEST_TOKEN_NOT_SUPPORTED;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
- {
- if (item.uDataType != QCBOR_TYPE_ARRAY)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- sw_component_present = 1;
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- continue;
-
- count = item.val.uCount;
- for (i = 0; i <= count; i++)
- {
- mandaroty_sw_components |= 1 << item.label.int64;
-
- if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- if (i < count)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- }
-
- }
- }
- else
- {
- /* ToDo: Add other claim types */
- }
- }
-
- if (status == QCBOR_ERR_HIT_END)
- return PAL_ATTEST_SUCCESS;
- else
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-}
-
-/**
- @brief - This API will verify the attestation token
- @param - challenge : The buffer containing the challenge
- challenge_size : Size of the challenge buffer
- token : The buffer containing the attestation token
- token_size : Size of the token buffer
- @return - error status
-**/
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size)
-{
- int32_t status = PAL_ATTEST_SUCCESS;
- int32_t cose_algorithm_id;
- QCBORItem item;
- QCBORDecodeContext decode_context;
- struct q_useful_buf_c completed_challenge;
- struct q_useful_buf_c completed_token;
- struct q_useful_buf_c payload;
- struct q_useful_buf_c signature;
- struct q_useful_buf_c protected_headers;
- struct q_useful_buf_c kid;
- struct q_useful_buf_c token_hash;
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_x_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_y_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
-
- kid.ptr = buffer_for_encoded_key.ptr;
-
- memcpy(buf_to_hold_x_coord.ptr, (const void *)attest_key.pubx_key, attest_key.pubx_key_size);
- memcpy(buf_to_hold_y_coord.ptr, (const void *)attest_key.puby_key, attest_key.puby_key_size);
-
- /* Update size */
- buf_to_hold_x_coord.len = attest_key.pubx_key_size;
- buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
- /* Construct the token buffer for validation */
- completed_token.ptr = token;
- completed_token.len = token_size;
-
- /* Construct the challenge buffer for validation */
- completed_challenge.ptr = challenge;
- completed_challenge.len = challenge_size;
-
-/*
- -------------------------
- | CBOR Array Type |
- -------------------------
- | Protected Headers |
- -------------------------
- | Unprotected Headers |
- -------------------------
- | Payload |
- -------------------------
- | Signature |
- -------------------------
-*/
-
- /* Initialize the decorder */
- QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
-
- /* Get the Header */
- QCBORDecode_GetNext(&decode_context, &item);
-
- /* Check the CBOR Array type. Check if the count is 4.
- * Only COSE_SIGN1 is supported now.
- */
- if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
- !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Get the next headers */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- protected_headers = item.val.string;
-
- /* Parse the protected headers and check the data type and value*/
- status = parse_protected_headers(protected_headers, &cose_algorithm_id);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Parse the unprotected headers and check the data type and value */
- status = parse_unprotected_headers(&decode_context, &kid);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Get the payload */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- payload = item.val.string;
-
- /* Get the digital signature */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- signature = item.val.string;
-
- /* Compute the hash from the token */
- status = pal_compute_hash(cose_algorithm_id, buffer_for_token_hash, &token_hash,
- protected_headers, payload);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Verify the signature */
- status = pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Initialize the Decoder and validate the payload format */
- QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
- status = QCBORDecode_GetNext(&decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if (item.uDataType != QCBOR_TYPE_MAP)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Parse the payload and check the data type of each claim */
- status = parse_claims(&decode_context, item, completed_challenge);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
- {
- if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
- else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
- {
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h
index df24c89..fae5434 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h
@@ -15,43 +15,17 @@
* limitations under the License.
**/
+#ifndef _PAL_ATTESTATION_EAT_H_
+#define _PAL_ATTESTATION_EAT_H_
+
#include "qcbor.h"
#include "pal_common.h"
-#include "psa/crypto.h"
#define PAL_ATTEST_MIN_ERROR 30
-/* NIST P-256 also known as secp256r1 */
-#define P_256 1
-
-#define COSE_HEADER_PARAM_ALG 1
-#define COSE_HEADER_PARAM_KID 4
-
-#define COSE_KEY_COMMON_KTY 1
-#define COSE_KEY_TYPE_EC2 2
-#define COSE_KEY_PARAM_CRV -1
-#define COSE_KEY_PARAM_X_COORDINATE -2
-#define COSE_KEY_PARAM_Y_COORDINATE -3
#define COSE_ALGORITHM_ES256 -7
#define COSE_ALG_SHA256_PROPRIETARY -72000
-/**
- * The size of X and Y coordinate in 2 parameter style EC public
- * key. Format is as defined in [COSE (RFC 8152)]
- * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
- * Cryptography](http://www.secg.org/sec1-v2.pdf).
- *
- * This size is well-known and documented in public standards.
- */
-#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
-#define T_COSE_CRYPTO_SHA256_SIZE 32
-
-#define MAX_ENCODED_COSE_KEY_SIZE \
- 1 + /* 1 byte to encode map */ \
- 2 + /* 2 bytes to encode key type */ \
- 2 + /* 2 bytes to encode curve */ \
- 2 * /* the X and Y coordinates at 32 bytes each */ \
- (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2)
#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
#define COSE_SIG_CONTEXT_STRING_SIGNATURE1 "Signature1"
@@ -78,71 +52,9 @@
sizeof(COSE_SIG_CONTEXT_STRING_SIGNATURE1) + /* "Signature1" */ \
2 + /* Overhead for encoding string */ \
T_COSE_SIGN1_MAX_PROT_HEADER + /* entire protected headers */ \
- 3 * ( /* 3 NULL bstrs for fields not used */ \
+ 3 * (/* 3 NULL bstrs for fields not used */ \
1 /* size of a NULL bstr */ \
)
-
-/*
- CBOR Label for proprietary header indicating short-circuit
- signing was used. Just a random number in the proprietary
- label space */
-#define T_COSE_SHORT_CIRCUIT_LABEL (-8675309)
-
-#define EAT_CBOR_ARM_RANGE_BASE (-75000)
-#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
-#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
-#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
-#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
-#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
-#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
-#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
-#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
-#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
-#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
-#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
-
-#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
-
-#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
-#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
-#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
-#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
-
-#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
-
-#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
-
-#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
- 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
-
#define NULL_USEFUL_BUF_C NULLUsefulBufC
enum attestation_error_code {
@@ -161,13 +73,8 @@
PAL_ATTEST_ERR_KEY_FAIL,
PAL_ATTEST_ERR_SIGNATURE_FAIL,
PAL_ATTEST_ERR_CBOR_STRUCTURE,
+ PAL_ATTEST_ERR_SMALL_BUFFER,
PAL_ATTEST_ERROR,
};
-struct items_to_get_t {
- int64_t label;
- QCBORItem item;
-};
-
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size);
+#endif /* _PAL_ATTESTATION_EAT_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h
index 12f6ee9..3ab7ebb 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_INITIAL_ATTESTATION_H_
-#define _PAL_INITIAL_ATTESTATION_H_
+#ifndef _PAL_ATTESTATION_INTF_H_
+#define _PAL_ATTESTATION_INTF_H_
#include "pal_attestation_crypto.h"
@@ -24,7 +24,9 @@
PAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
PAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
PAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ PAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ PAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
int32_t pal_attestation_function(int type, va_list valist);
-#endif /* _PAL_INITIAL_ATTESTATION_H_ */
+#endif /* _PAL_ATTESTATION_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/target.cmake b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/target.cmake
index 5c5c942..db9a4fa 100644
--- a/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/target.cmake
+++ b/api-tests/platform/targets/tgt_dev_apis_mbedos_fvp_mps2_m4/target.cmake
@@ -71,7 +71,6 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
list(APPEND PAL_SRC_C_NSPE
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_intf.c
- ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_eat.c
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_crypto.c
)
endif()
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h
index 0076891..8a8f064 100644
--- a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_common.h
@@ -37,8 +37,7 @@
#define PAL_STATUS_UNSUPPORTED_FUNC 0xFF
-typedef enum
-{
+typedef enum {
PAL_STATUS_SUCCESS = 0x0,
PAL_STATUS_ERROR = 0x80
} pal_status_t;
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h
index 2871339..640f56f 100644
--- a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_config.h
@@ -38,11 +38,17 @@
/* Are Dynamic memory APIs available to secure partition? */
#define SP_HEAP_MEM_SUPP
+
+/* PSA Isolation level supported by platform */
+#define PLATFORM_PSA_ISOLATION_LEVEL 3
#endif /* PSA_CMAKE_BUILD */
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c
index 204adfb..2bbaad7 100644
--- a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/common/pal_driver_ns_intf.c
@@ -31,7 +31,7 @@
/* Using zero as NVMEM_BASE is a bit arbitrary - we don't actually need callers
* to specify a base address but the nvmem function signatures have "base" params.
- * Zero is the value used in our target.cfg file so that's what we should recieve.
+ * Zero is the value used in our target.cfg file so that's what we should receive.
*/
#define NVMEM_BASE 0
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake b/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake
index 38e4db2..e46fe21 100644
--- a/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake
+++ b/api-tests/platform/targets/tgt_dev_apis_stdc/target.cmake
@@ -44,10 +44,14 @@
)
endif()
if(${SUITE} STREQUAL "PROTECTED_STORAGE")
- message(FATAL_ERROR "Protected Storage not supported")
+ list(APPEND PAL_SRC_C_NSPE
+ ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/protected_storage/pal_protected_storage_intf.c
+ )
endif()
if(${SUITE} STREQUAL "INTERNAL_TRUSTED_STORAGE")
- message(FATAL_ERROR "Internal Trusted Storage not support")
+ list(APPEND PAL_SRC_C_NSPE
+ ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/internal_trusted_storage/pal_internal_trusted_storage_intf.c
+ )
endif()
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
message(FATAL_ERROR "Initial attestation not supported")
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/common/pal_config.h
index 2871339..61db8d8 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/common/pal_config.h
@@ -43,6 +43,9 @@
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.c b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.c
index 2da03fa..eec2619 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.c
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.c
@@ -19,29 +19,13 @@
static uint32_t public_key_registered;
static psa_key_handle_t public_key_handle;
+
static inline struct q_useful_buf_c useful_buf_head(struct q_useful_buf_c buf,
size_t amount)
{
return UsefulBuf_Head(buf, amount);
}
-static psa_ecc_curve_t attest_map_elliptic_curve_type(int32_t cose_curve)
-{
- psa_ecc_curve_t psa_curve;
-
- /*FixMe: Mapping is not complete, missing ones: P384, P521, ED25519, ED448 */
- switch (cose_curve)
- {
- case P_256:
- psa_curve = PSA_ECC_CURVE_SECP256R1;
- break;
- default:
- psa_curve = USHRT_MAX;
- }
-
- return psa_curve;
-}
-
static psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
{
psa_algorithm_t status;
@@ -137,6 +121,15 @@
return status;
}
+/**
+ @brief - Computes hash for the requested data
+ @param - cose_alg_id : Algorithm ID
+ - buffer_for_hash : Temp buffer for calculating hash
+ - hash : Pointer to store the hash
+ - protected_headers : Buffer containing protected data
+ - payload : payload data
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_compute_hash(int32_t cose_alg_id, struct q_useful_buf buffer_for_hash,
struct q_useful_buf_c *hash, struct q_useful_buf_c protected_headers,
struct q_useful_buf_c payload)
@@ -203,22 +196,56 @@
return status;
}
+static int32_t pal_attest_get_public_key(uint8_t *public_key_buff, size_t public_key_buf_size,
+ size_t *public_key_len, psa_ecc_curve_t *elliptic_curve_type)
+{
+ int32_t status = PAL_ATTEST_ERROR;
+
+#ifdef PLATFORM_OVERRIDE_ATTEST_PK
+ if (public_key_buf_size < (attest_key.pubx_key_size + attest_key.puby_key_size + 1))
+ return PAL_ATTEST_ERR_SMALL_BUFFER;
+
+ *public_key_len = (attest_key.pubx_key_size + attest_key.puby_key_size + 1);
+ *elliptic_curve_type = PSA_ECC_CURVE_SECP256R1;
+ memcpy(public_key_buff, (void *)&attest_public_key, *public_key_len);
+ status = PSA_SUCCESS;
+#else
+ status = tfm_initial_attest_get_public_key(public_key_buff,
+ public_key_buf_size,
+ public_key_len,
+ elliptic_curve_type);
+#endif
+
+ return status;
+}
+
static uint32_t pal_import_attest_key(psa_algorithm_t key_alg)
{
psa_status_t status = PAL_ATTEST_ERROR;
psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY;
- psa_ecc_curve_t psa_curve = attest_map_elliptic_curve_type(P_256);
- psa_key_type_t attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve);
- size_t public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
+ psa_ecc_curve_t ecc_curve;
+ psa_key_type_t attest_key_type;
+ size_t public_key_size;
+ uint8_t public_key_buff[ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH] = {0};
#if defined(CRYPTO_VERSION_BETA1) || defined(CRYPTO_VERSION_BETA2)
psa_key_policy_t policy;
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Setup the key policy for public key */
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, key_alg);
@@ -234,8 +261,8 @@
/* Import the public key */
status = psa_import_key(public_key_handle,
attest_key_type,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1);
+ public_key_buff,
+ public_key_size);
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -247,21 +274,30 @@
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Set the attributes for the public key */
psa_set_key_type(&attributes, attest_key_type);
- psa_set_key_bits(&attributes, public_key_size + 1);
+ psa_set_key_bits(&attributes, public_key_size);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, key_alg);
/* Import the public key */
status = psa_import_key(&attributes,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1,
+ public_key_buff,
+ public_key_size,
&public_key_handle);
-
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -272,6 +308,7 @@
return status;
}
+
static uint32_t pal_destroy_attest_key(void)
{
psa_status_t status;
@@ -288,6 +325,13 @@
return PAL_ATTEST_SUCCESS;
}
+/**
+ @brief - Verify the signature using the public key
+ @param - cose_algorithm_id : Algorithm ID
+ - token_hash : Data that needs to be verified
+ - signature : Signature to be verified against
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id,
struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature)
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.h
index bd47990..559a24c 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_crypto.h
@@ -15,12 +15,15 @@
* limitations under the License.
**/
-#include "pal_common.h"
+#ifndef _PAL_ATTESTATION_CRYPTO_H_
+#define _PAL_ATTESTATION_CRYPTO_H_
+
#include "pal_attestation_eat.h"
-#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH (1 + 2 * PSA_BITS_TO_BYTES(256))
-typedef struct{
+typedef struct {
uint8_t *pubx_key;
size_t pubx_key_size;
uint8_t *puby_key;
@@ -47,16 +50,14 @@
0x0F, 0x34, 0x11, 0x7D, 0x97, 0x1D, 0x68, 0x64},
};
-static const uint8_t initial_attestation_public_x_key[] =
-{
+static const uint8_t initial_attestation_public_x_key[] = {
0x79, 0xEB, 0xA9, 0x0E, 0x8B, 0xF4, 0x50, 0xA6,
0x75, 0x15, 0x76, 0xAD, 0x45, 0x99, 0xB0, 0x7A,
0xDF, 0x93, 0x8D, 0xA3, 0xBB, 0x0B, 0xD1, 0x7D,
0x00, 0x36, 0xED, 0x49, 0xA2, 0xD0, 0xFC, 0x3F
};
-static const uint8_t initial_attestation_public_y_key[] =
-{
+static const uint8_t initial_attestation_public_y_key[] = {
0xBF, 0xCD, 0xFA, 0x89, 0x56, 0xB5, 0x68, 0xBF,
0xDB, 0x86, 0x73, 0xE6, 0x48, 0xD8, 0xB5, 0x8D,
0x92, 0x99, 0x55, 0xB1, 0x4A, 0x26, 0xC3, 0x08,
@@ -84,5 +85,4 @@
struct q_useful_buf_c payload);
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id, struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature);
-
-
+#endif /* _PAL_ATTESTATION_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.c b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.c
deleted file mode 100644
index 68c4312..0000000
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @file
- * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
- * SPDX-License-Identifier : Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-**/
-
-#include "pal_attestation_crypto.h"
-
-uint32_t mandatory_claims = 0;
-uint32_t mandaroty_sw_components = 0;
-bool_t sw_component_present = 0;
-
-int pal_encode_cose_key(struct q_useful_buf_c *cose_key,
- struct q_useful_buf buffer_for_cose_key,
- struct q_useful_buf_c x_cord, struct q_useful_buf_c y_cord)
-{
- uint32_t return_value;
- QCBORError qcbor_result;
- QCBOREncodeContext cbor_encode_ctx;
- int32_t cose_curve_id = P_256;
- struct q_useful_buf_c encoded_key_id;
-
- /* Get the public key x and y */
- /* Encode it into a COSE_Key structure */
- QCBOREncode_Init(&cbor_encode_ctx, buffer_for_cose_key);
- QCBOREncode_OpenMap(&cbor_encode_ctx);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_COMMON_KTY,
- COSE_KEY_TYPE_EC2);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_CRV,
- cose_curve_id);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_X_COORDINATE,
- x_cord);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_Y_COORDINATE,
- y_cord);
- QCBOREncode_CloseMap(&cbor_encode_ctx);
-
- qcbor_result = QCBOREncode_Finish(&cbor_encode_ctx, &encoded_key_id);
- if (qcbor_result != QCBOR_SUCCESS)
- {
- /* Mainly means that the COSE_Key was too big for buffer_for_cose_key */
- return_value = PAL_ATTEST_ERR_PROTECTED_HEADERS;
- goto Done;
- }
-
- /* Finish up and return */
- *cose_key = encoded_key_id;
- return_value = PAL_ATTEST_SUCCESS;
-
-Done:
- return return_value;
-}
-
-
-static int get_items_in_map(QCBORDecodeContext *decode_context,
- struct items_to_get_t *item_list)
-{
- int item_index;
- QCBORItem item;
- struct items_to_get_t *item_ptr = item_list;
-
- /* initialize the data type of all items in the list */
- while (item_ptr->label != 0)
- {
- item_ptr->item.uDataType = QCBOR_TYPE_NONE;
- item_ptr++;
- }
-
- QCBORDecode_GetNext(decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_MAP)
- {
- return PAL_ATTEST_ERROR;
- }
-
- for (item_index = item.val.uCount; item_index != 0; item_index--)
- {
- if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- if (item.uLabelType != QCBOR_TYPE_INT64)
- {
- continue;
- }
-
- item_ptr = item_list;
- while (item_ptr->label != 0)
- {
- if (item.label.int64 == item_ptr->label)
- {
- item_ptr->item = item;
- }
- item_ptr++;
- }
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int get_item_in_map(QCBORDecodeContext *decode_context,
- int32_t label,
- QCBORItem *item)
-{
- struct items_to_get_t item_list[2];
-
- item_list[0].label = label;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- *item = item_list[0].item;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
- struct q_useful_buf_c *child)
-{
- struct items_to_get_t item_list[3];
-
- item_list[0].label = COSE_HEADER_PARAM_KID;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERR_CBOR_STRUCTURE;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_protected_headers(struct q_useful_buf_c protected_headers,
- int32_t *alg_id)
-{
- QCBORDecodeContext decode_context;
- QCBORItem item;
-
- QCBORDecode_Init(&decode_context, protected_headers, 0);
-
- if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (QCBORDecode_Finish(&decode_context))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
- {
- return PAL_ATTEST_ERROR;
- }
-
- *alg_id = (int32_t)item.val.int64;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-/**
- @brief - This API will verify the claims
- @param - decode_context : The buffer containing the challenge
- item : context for decoding the data items
- completed_challenge : Buffer containing the challenge
- @return - error status
-**/
-static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
- struct q_useful_buf_c completed_challenge)
-{
- int i, count = 0;
- int status = PAL_ATTEST_SUCCESS;
-
- /* Parse each claim and validate their data type */
- while (status == PAL_ATTEST_SUCCESS)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- break;
-
- mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
- if (item.uLabelType == QCBOR_TYPE_INT64)
- {
- if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
- {
- if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
- {
- /* Given challenge vs challenge in token */
- if (UsefulBuf_Compare(item.val.string, completed_challenge))
- return PAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
- }
- else
- return PAL_ATTEST_TOKEN_NOT_SUPPORTED;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
- {
- if (item.uDataType != QCBOR_TYPE_ARRAY)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- sw_component_present = 1;
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- continue;
-
- count = item.val.uCount;
- for (i = 0; i <= count; i++)
- {
- mandaroty_sw_components |= 1 << item.label.int64;
-
- if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- if (i < count)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- }
-
- }
- }
- else
- {
- /* ToDo: Add other claim types */
- }
- }
-
- if (status == QCBOR_ERR_HIT_END)
- return PAL_ATTEST_SUCCESS;
- else
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-}
-
-/**
- @brief - This API will verify the attestation token
- @param - challenge : The buffer containing the challenge
- challenge_size : Size of the challenge buffer
- token : The buffer containing the attestation token
- token_size : Size of the token buffer
- @return - error status
-**/
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size)
-{
- int32_t status = PAL_ATTEST_SUCCESS;
- int32_t cose_algorithm_id;
- QCBORItem item;
- QCBORDecodeContext decode_context;
- struct q_useful_buf_c completed_challenge;
- struct q_useful_buf_c completed_token;
- struct q_useful_buf_c payload;
- struct q_useful_buf_c signature;
- struct q_useful_buf_c protected_headers;
- struct q_useful_buf_c kid;
- struct q_useful_buf_c token_hash;
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_x_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_y_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
-
- kid.ptr = buffer_for_encoded_key.ptr;
-
- memcpy(buf_to_hold_x_coord.ptr, (const void *)attest_key.pubx_key, attest_key.pubx_key_size);
- memcpy(buf_to_hold_y_coord.ptr, (const void *)attest_key.puby_key, attest_key.puby_key_size);
-
- /* Update size */
- buf_to_hold_x_coord.len = attest_key.pubx_key_size;
- buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
- /* Construct the token buffer for validation */
- completed_token.ptr = token;
- completed_token.len = token_size;
-
- /* Construct the challenge buffer for validation */
- completed_challenge.ptr = challenge;
- completed_challenge.len = challenge_size;
-
-/*
- -------------------------
- | CBOR Array Type |
- -------------------------
- | Protected Headers |
- -------------------------
- | Unprotected Headers |
- -------------------------
- | Payload |
- -------------------------
- | Signature |
- -------------------------
-*/
-
- /* Initialize the decorder */
- QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
-
- /* Get the Header */
- QCBORDecode_GetNext(&decode_context, &item);
-
- /* Check the CBOR Array type. Check if the count is 4.
- * Only COSE_SIGN1 is supported now.
- */
- if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
- !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Get the next headers */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- protected_headers = item.val.string;
-
- /* Parse the protected headers and check the data type and value*/
- status = parse_protected_headers(protected_headers, &cose_algorithm_id);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Parse the unprotected headers and check the data type and value */
- status = parse_unprotected_headers(&decode_context, &kid);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Get the payload */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- payload = item.val.string;
-
- /* Get the digital signature */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- signature = item.val.string;
-
- /* Compute the hash from the token */
- status = pal_compute_hash(cose_algorithm_id, buffer_for_token_hash, &token_hash,
- protected_headers, payload);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Verify the signature */
- status = pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Initialize the Decoder and validate the payload format */
- QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
- status = QCBORDecode_GetNext(&decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if (item.uDataType != QCBOR_TYPE_MAP)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Parse the payload and check the data type of each claim */
- status = parse_claims(&decode_context, item, completed_challenge);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
- {
- if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
- else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
- {
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.h
index df24c89..fae5434 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_eat.h
@@ -15,43 +15,17 @@
* limitations under the License.
**/
+#ifndef _PAL_ATTESTATION_EAT_H_
+#define _PAL_ATTESTATION_EAT_H_
+
#include "qcbor.h"
#include "pal_common.h"
-#include "psa/crypto.h"
#define PAL_ATTEST_MIN_ERROR 30
-/* NIST P-256 also known as secp256r1 */
-#define P_256 1
-
-#define COSE_HEADER_PARAM_ALG 1
-#define COSE_HEADER_PARAM_KID 4
-
-#define COSE_KEY_COMMON_KTY 1
-#define COSE_KEY_TYPE_EC2 2
-#define COSE_KEY_PARAM_CRV -1
-#define COSE_KEY_PARAM_X_COORDINATE -2
-#define COSE_KEY_PARAM_Y_COORDINATE -3
#define COSE_ALGORITHM_ES256 -7
#define COSE_ALG_SHA256_PROPRIETARY -72000
-/**
- * The size of X and Y coordinate in 2 parameter style EC public
- * key. Format is as defined in [COSE (RFC 8152)]
- * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
- * Cryptography](http://www.secg.org/sec1-v2.pdf).
- *
- * This size is well-known and documented in public standards.
- */
-#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
-#define T_COSE_CRYPTO_SHA256_SIZE 32
-
-#define MAX_ENCODED_COSE_KEY_SIZE \
- 1 + /* 1 byte to encode map */ \
- 2 + /* 2 bytes to encode key type */ \
- 2 + /* 2 bytes to encode curve */ \
- 2 * /* the X and Y coordinates at 32 bytes each */ \
- (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2)
#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
#define COSE_SIG_CONTEXT_STRING_SIGNATURE1 "Signature1"
@@ -78,71 +52,9 @@
sizeof(COSE_SIG_CONTEXT_STRING_SIGNATURE1) + /* "Signature1" */ \
2 + /* Overhead for encoding string */ \
T_COSE_SIGN1_MAX_PROT_HEADER + /* entire protected headers */ \
- 3 * ( /* 3 NULL bstrs for fields not used */ \
+ 3 * (/* 3 NULL bstrs for fields not used */ \
1 /* size of a NULL bstr */ \
)
-
-/*
- CBOR Label for proprietary header indicating short-circuit
- signing was used. Just a random number in the proprietary
- label space */
-#define T_COSE_SHORT_CIRCUIT_LABEL (-8675309)
-
-#define EAT_CBOR_ARM_RANGE_BASE (-75000)
-#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
-#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
-#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
-#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
-#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
-#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
-#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
-#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
-#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
-#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
-#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
-
-#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
-
-#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
-#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
-#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
-#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
-
-#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
-
-#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
-
-#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
- 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
-
#define NULL_USEFUL_BUF_C NULLUsefulBufC
enum attestation_error_code {
@@ -161,13 +73,8 @@
PAL_ATTEST_ERR_KEY_FAIL,
PAL_ATTEST_ERR_SIGNATURE_FAIL,
PAL_ATTEST_ERR_CBOR_STRUCTURE,
+ PAL_ATTEST_ERR_SMALL_BUFFER,
PAL_ATTEST_ERROR,
};
-struct items_to_get_t {
- int64_t label;
- QCBORItem item;
-};
-
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size);
+#endif /* _PAL_ATTESTATION_EAT_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.c b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.c
index 83c1ebd..8dc9406 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.c
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.c
@@ -26,8 +26,11 @@
**/
int32_t pal_attestation_function(int type, va_list valist)
{
- uint8_t *challenge, *token;
- size_t challenge_size, *token_size, verify_token_size, token_buffer_size;
+ uint8_t *challenge, *token;
+ size_t challenge_size, *token_size, token_buffer_size;
+ int32_t cose_algorithm_id;
+ struct q_useful_buf buffer_for_hash;
+ struct q_useful_buf_c *hash, payload, protected_headers, token_hash, signature;
switch (type)
{
@@ -43,13 +46,19 @@
challenge_size = va_arg(valist, size_t);
token_size = va_arg(valist, size_t*);
return psa_initial_attest_get_token_size(challenge_size, token_size);
- case PAL_INITIAL_ATTEST_VERIFY_TOKEN:
- challenge = va_arg(valist, uint8_t*);
- challenge_size = va_arg(valist, size_t);
- token = va_arg(valist, uint8_t*);
- verify_token_size = va_arg(valist, size_t);
- return pal_initial_attest_verify_token(challenge, challenge_size,
- token, verify_token_size);
+ case PAL_INITIAL_ATTEST_COMPUTE_HASH:
+ cose_algorithm_id = va_arg(valist, int32_t);
+ buffer_for_hash = va_arg(valist, struct q_useful_buf);
+ hash = va_arg(valist, struct q_useful_buf_c*);
+ protected_headers = va_arg(valist, struct q_useful_buf_c);
+ payload = va_arg(valist, struct q_useful_buf_c);
+ return pal_compute_hash(cose_algorithm_id, buffer_for_hash, hash,
+ protected_headers, payload);
+ case PAL_INITIAL_ATTEST_VERIFY_WITH_PK:
+ cose_algorithm_id = va_arg(valist, int32_t);
+ token_hash = va_arg(valist, struct q_useful_buf_c);
+ signature = va_arg(valist, struct q_useful_buf_c);
+ return pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
default:
return PAL_STATUS_UNSUPPORTED_FUNC;
}
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.h
index 12f6ee9..3ab7ebb 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/nspe/initial_attestation/pal_attestation_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_INITIAL_ATTESTATION_H_
-#define _PAL_INITIAL_ATTESTATION_H_
+#ifndef _PAL_ATTESTATION_INTF_H_
+#define _PAL_ATTESTATION_INTF_H_
#include "pal_attestation_crypto.h"
@@ -24,7 +24,9 @@
PAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
PAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
PAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ PAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ PAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
int32_t pal_attestation_function(int type, va_list valist);
-#endif /* _PAL_INITIAL_ATTESTATION_H_ */
+#endif /* _PAL_ATTESTATION_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/target.cmake b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/target.cmake
index 5c5c942..db9a4fa 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an521/target.cmake
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an521/target.cmake
@@ -71,7 +71,6 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
list(APPEND PAL_SRC_C_NSPE
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_intf.c
- ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_eat.c
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_crypto.c
)
endif()
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_common.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_common.h
index 0a63b02..a03cd8d 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_common.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_common.h
@@ -37,8 +37,7 @@
#define PAL_STATUS_UNSUPPORTED_FUNC 0xFF
-typedef enum
-{
+typedef enum {
PAL_STATUS_SUCCESS = 0x0,
PAL_STATUS_ERROR = 0x80
} pal_status_t;
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_config.h
index 2871339..61db8d8 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/common/pal_config.h
@@ -43,6 +43,9 @@
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.c b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.c
index 2da03fa..04fe5ef 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.c
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.c
@@ -19,29 +19,13 @@
static uint32_t public_key_registered;
static psa_key_handle_t public_key_handle;
+
static inline struct q_useful_buf_c useful_buf_head(struct q_useful_buf_c buf,
size_t amount)
{
return UsefulBuf_Head(buf, amount);
}
-static psa_ecc_curve_t attest_map_elliptic_curve_type(int32_t cose_curve)
-{
- psa_ecc_curve_t psa_curve;
-
- /*FixMe: Mapping is not complete, missing ones: P384, P521, ED25519, ED448 */
- switch (cose_curve)
- {
- case P_256:
- psa_curve = PSA_ECC_CURVE_SECP256R1;
- break;
- default:
- psa_curve = USHRT_MAX;
- }
-
- return psa_curve;
-}
-
static psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
{
psa_algorithm_t status;
@@ -137,6 +121,15 @@
return status;
}
+/**
+ @brief - Computes hash for the requested data
+ @param - cose_alg_id : Algorithm ID
+ - buffer_for_hash : Temp buffer for calculating hash
+ - hash : Pointer to store the hash
+ - protected_headers : Buffer containing protected data
+ - payload : payload data
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_compute_hash(int32_t cose_alg_id, struct q_useful_buf buffer_for_hash,
struct q_useful_buf_c *hash, struct q_useful_buf_c protected_headers,
struct q_useful_buf_c payload)
@@ -203,22 +196,56 @@
return status;
}
+static int32_t pal_attest_get_public_key(uint8_t *public_key_buff, size_t public_key_buf_size,
+ size_t *public_key_len, psa_ecc_curve_t *elliptic_curve_type)
+{
+ int32_t status = PAL_ATTEST_ERROR;
+
+#ifdef PLATFORM_OVERRIDE_ATTEST_PK
+ if (public_key_buf_size < (attest_key.pubx_key_size + attest_key.puby_key_size + 1))
+ return PAL_ATTEST_ERR_SMALL_BUFFER;
+
+ *public_key_len = (attest_key.pubx_key_size + attest_key.puby_key_size + 1);
+ *elliptic_curve_type = PSA_ECC_CURVE_SECP256R1;
+ memcpy(public_key_buff, (void *)&attest_public_key, *public_key_len);
+ status = PSA_SUCCESS;
+#else
+ status = tfm_initial_attest_get_public_key(public_key_buff,
+ public_key_buf_size,
+ public_key_len,
+ elliptic_curve_type);
+#endif
+
+ return status;
+}
+
static uint32_t pal_import_attest_key(psa_algorithm_t key_alg)
{
psa_status_t status = PAL_ATTEST_ERROR;
psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY;
- psa_ecc_curve_t psa_curve = attest_map_elliptic_curve_type(P_256);
- psa_key_type_t attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve);
- size_t public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
+ psa_ecc_curve_t ecc_curve;
+ psa_key_type_t attest_key_type;
+ size_t public_key_size;
+ uint8_t public_key_buff[ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH] = {0};
#if defined(CRYPTO_VERSION_BETA1) || defined(CRYPTO_VERSION_BETA2)
psa_key_policy_t policy;
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Setup the key policy for public key */
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, key_alg);
@@ -234,8 +261,8 @@
/* Import the public key */
status = psa_import_key(public_key_handle,
attest_key_type,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1);
+ public_key_buff,
+ public_key_size);
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -247,21 +274,30 @@
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Set the attributes for the public key */
psa_set_key_type(&attributes, attest_key_type);
- psa_set_key_bits(&attributes, public_key_size + 1);
+ psa_set_key_bits(&attributes, public_key_size);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, key_alg);
/* Import the public key */
status = psa_import_key(&attributes,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1,
+ public_key_buff,
+ public_key_size,
&public_key_handle);
-
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -288,6 +324,13 @@
return PAL_ATTEST_SUCCESS;
}
+/**
+ @brief - Verify the signature using the public key
+ @param - cose_algorithm_id : Algorithm ID
+ - token_hash : Data that needs to be verified
+ - signature : Signature to be verified against
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id,
struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature)
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.h
index bd47990..559a24c 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_crypto.h
@@ -15,12 +15,15 @@
* limitations under the License.
**/
-#include "pal_common.h"
+#ifndef _PAL_ATTESTATION_CRYPTO_H_
+#define _PAL_ATTESTATION_CRYPTO_H_
+
#include "pal_attestation_eat.h"
-#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH (1 + 2 * PSA_BITS_TO_BYTES(256))
-typedef struct{
+typedef struct {
uint8_t *pubx_key;
size_t pubx_key_size;
uint8_t *puby_key;
@@ -47,16 +50,14 @@
0x0F, 0x34, 0x11, 0x7D, 0x97, 0x1D, 0x68, 0x64},
};
-static const uint8_t initial_attestation_public_x_key[] =
-{
+static const uint8_t initial_attestation_public_x_key[] = {
0x79, 0xEB, 0xA9, 0x0E, 0x8B, 0xF4, 0x50, 0xA6,
0x75, 0x15, 0x76, 0xAD, 0x45, 0x99, 0xB0, 0x7A,
0xDF, 0x93, 0x8D, 0xA3, 0xBB, 0x0B, 0xD1, 0x7D,
0x00, 0x36, 0xED, 0x49, 0xA2, 0xD0, 0xFC, 0x3F
};
-static const uint8_t initial_attestation_public_y_key[] =
-{
+static const uint8_t initial_attestation_public_y_key[] = {
0xBF, 0xCD, 0xFA, 0x89, 0x56, 0xB5, 0x68, 0xBF,
0xDB, 0x86, 0x73, 0xE6, 0x48, 0xD8, 0xB5, 0x8D,
0x92, 0x99, 0x55, 0xB1, 0x4A, 0x26, 0xC3, 0x08,
@@ -84,5 +85,4 @@
struct q_useful_buf_c payload);
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id, struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature);
-
-
+#endif /* _PAL_ATTESTATION_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.c b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.c
deleted file mode 100644
index 68c4312..0000000
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @file
- * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
- * SPDX-License-Identifier : Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-**/
-
-#include "pal_attestation_crypto.h"
-
-uint32_t mandatory_claims = 0;
-uint32_t mandaroty_sw_components = 0;
-bool_t sw_component_present = 0;
-
-int pal_encode_cose_key(struct q_useful_buf_c *cose_key,
- struct q_useful_buf buffer_for_cose_key,
- struct q_useful_buf_c x_cord, struct q_useful_buf_c y_cord)
-{
- uint32_t return_value;
- QCBORError qcbor_result;
- QCBOREncodeContext cbor_encode_ctx;
- int32_t cose_curve_id = P_256;
- struct q_useful_buf_c encoded_key_id;
-
- /* Get the public key x and y */
- /* Encode it into a COSE_Key structure */
- QCBOREncode_Init(&cbor_encode_ctx, buffer_for_cose_key);
- QCBOREncode_OpenMap(&cbor_encode_ctx);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_COMMON_KTY,
- COSE_KEY_TYPE_EC2);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_CRV,
- cose_curve_id);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_X_COORDINATE,
- x_cord);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_Y_COORDINATE,
- y_cord);
- QCBOREncode_CloseMap(&cbor_encode_ctx);
-
- qcbor_result = QCBOREncode_Finish(&cbor_encode_ctx, &encoded_key_id);
- if (qcbor_result != QCBOR_SUCCESS)
- {
- /* Mainly means that the COSE_Key was too big for buffer_for_cose_key */
- return_value = PAL_ATTEST_ERR_PROTECTED_HEADERS;
- goto Done;
- }
-
- /* Finish up and return */
- *cose_key = encoded_key_id;
- return_value = PAL_ATTEST_SUCCESS;
-
-Done:
- return return_value;
-}
-
-
-static int get_items_in_map(QCBORDecodeContext *decode_context,
- struct items_to_get_t *item_list)
-{
- int item_index;
- QCBORItem item;
- struct items_to_get_t *item_ptr = item_list;
-
- /* initialize the data type of all items in the list */
- while (item_ptr->label != 0)
- {
- item_ptr->item.uDataType = QCBOR_TYPE_NONE;
- item_ptr++;
- }
-
- QCBORDecode_GetNext(decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_MAP)
- {
- return PAL_ATTEST_ERROR;
- }
-
- for (item_index = item.val.uCount; item_index != 0; item_index--)
- {
- if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- if (item.uLabelType != QCBOR_TYPE_INT64)
- {
- continue;
- }
-
- item_ptr = item_list;
- while (item_ptr->label != 0)
- {
- if (item.label.int64 == item_ptr->label)
- {
- item_ptr->item = item;
- }
- item_ptr++;
- }
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int get_item_in_map(QCBORDecodeContext *decode_context,
- int32_t label,
- QCBORItem *item)
-{
- struct items_to_get_t item_list[2];
-
- item_list[0].label = label;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- *item = item_list[0].item;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
- struct q_useful_buf_c *child)
-{
- struct items_to_get_t item_list[3];
-
- item_list[0].label = COSE_HEADER_PARAM_KID;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERR_CBOR_STRUCTURE;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_protected_headers(struct q_useful_buf_c protected_headers,
- int32_t *alg_id)
-{
- QCBORDecodeContext decode_context;
- QCBORItem item;
-
- QCBORDecode_Init(&decode_context, protected_headers, 0);
-
- if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (QCBORDecode_Finish(&decode_context))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
- {
- return PAL_ATTEST_ERROR;
- }
-
- *alg_id = (int32_t)item.val.int64;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-/**
- @brief - This API will verify the claims
- @param - decode_context : The buffer containing the challenge
- item : context for decoding the data items
- completed_challenge : Buffer containing the challenge
- @return - error status
-**/
-static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
- struct q_useful_buf_c completed_challenge)
-{
- int i, count = 0;
- int status = PAL_ATTEST_SUCCESS;
-
- /* Parse each claim and validate their data type */
- while (status == PAL_ATTEST_SUCCESS)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- break;
-
- mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
- if (item.uLabelType == QCBOR_TYPE_INT64)
- {
- if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
- {
- if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
- {
- /* Given challenge vs challenge in token */
- if (UsefulBuf_Compare(item.val.string, completed_challenge))
- return PAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
- }
- else
- return PAL_ATTEST_TOKEN_NOT_SUPPORTED;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
- {
- if (item.uDataType != QCBOR_TYPE_ARRAY)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- sw_component_present = 1;
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- continue;
-
- count = item.val.uCount;
- for (i = 0; i <= count; i++)
- {
- mandaroty_sw_components |= 1 << item.label.int64;
-
- if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- if (i < count)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- }
-
- }
- }
- else
- {
- /* ToDo: Add other claim types */
- }
- }
-
- if (status == QCBOR_ERR_HIT_END)
- return PAL_ATTEST_SUCCESS;
- else
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-}
-
-/**
- @brief - This API will verify the attestation token
- @param - challenge : The buffer containing the challenge
- challenge_size : Size of the challenge buffer
- token : The buffer containing the attestation token
- token_size : Size of the token buffer
- @return - error status
-**/
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size)
-{
- int32_t status = PAL_ATTEST_SUCCESS;
- int32_t cose_algorithm_id;
- QCBORItem item;
- QCBORDecodeContext decode_context;
- struct q_useful_buf_c completed_challenge;
- struct q_useful_buf_c completed_token;
- struct q_useful_buf_c payload;
- struct q_useful_buf_c signature;
- struct q_useful_buf_c protected_headers;
- struct q_useful_buf_c kid;
- struct q_useful_buf_c token_hash;
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_x_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_y_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
-
- kid.ptr = buffer_for_encoded_key.ptr;
-
- memcpy(buf_to_hold_x_coord.ptr, (const void *)attest_key.pubx_key, attest_key.pubx_key_size);
- memcpy(buf_to_hold_y_coord.ptr, (const void *)attest_key.puby_key, attest_key.puby_key_size);
-
- /* Update size */
- buf_to_hold_x_coord.len = attest_key.pubx_key_size;
- buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
- /* Construct the token buffer for validation */
- completed_token.ptr = token;
- completed_token.len = token_size;
-
- /* Construct the challenge buffer for validation */
- completed_challenge.ptr = challenge;
- completed_challenge.len = challenge_size;
-
-/*
- -------------------------
- | CBOR Array Type |
- -------------------------
- | Protected Headers |
- -------------------------
- | Unprotected Headers |
- -------------------------
- | Payload |
- -------------------------
- | Signature |
- -------------------------
-*/
-
- /* Initialize the decorder */
- QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
-
- /* Get the Header */
- QCBORDecode_GetNext(&decode_context, &item);
-
- /* Check the CBOR Array type. Check if the count is 4.
- * Only COSE_SIGN1 is supported now.
- */
- if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
- !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Get the next headers */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- protected_headers = item.val.string;
-
- /* Parse the protected headers and check the data type and value*/
- status = parse_protected_headers(protected_headers, &cose_algorithm_id);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Parse the unprotected headers and check the data type and value */
- status = parse_unprotected_headers(&decode_context, &kid);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Get the payload */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- payload = item.val.string;
-
- /* Get the digital signature */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- signature = item.val.string;
-
- /* Compute the hash from the token */
- status = pal_compute_hash(cose_algorithm_id, buffer_for_token_hash, &token_hash,
- protected_headers, payload);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Verify the signature */
- status = pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Initialize the Decoder and validate the payload format */
- QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
- status = QCBORDecode_GetNext(&decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if (item.uDataType != QCBOR_TYPE_MAP)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Parse the payload and check the data type of each claim */
- status = parse_claims(&decode_context, item, completed_challenge);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
- {
- if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
- else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
- {
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.h
index df24c89..fae5434 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_eat.h
@@ -15,43 +15,17 @@
* limitations under the License.
**/
+#ifndef _PAL_ATTESTATION_EAT_H_
+#define _PAL_ATTESTATION_EAT_H_
+
#include "qcbor.h"
#include "pal_common.h"
-#include "psa/crypto.h"
#define PAL_ATTEST_MIN_ERROR 30
-/* NIST P-256 also known as secp256r1 */
-#define P_256 1
-
-#define COSE_HEADER_PARAM_ALG 1
-#define COSE_HEADER_PARAM_KID 4
-
-#define COSE_KEY_COMMON_KTY 1
-#define COSE_KEY_TYPE_EC2 2
-#define COSE_KEY_PARAM_CRV -1
-#define COSE_KEY_PARAM_X_COORDINATE -2
-#define COSE_KEY_PARAM_Y_COORDINATE -3
#define COSE_ALGORITHM_ES256 -7
#define COSE_ALG_SHA256_PROPRIETARY -72000
-/**
- * The size of X and Y coordinate in 2 parameter style EC public
- * key. Format is as defined in [COSE (RFC 8152)]
- * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
- * Cryptography](http://www.secg.org/sec1-v2.pdf).
- *
- * This size is well-known and documented in public standards.
- */
-#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
-#define T_COSE_CRYPTO_SHA256_SIZE 32
-
-#define MAX_ENCODED_COSE_KEY_SIZE \
- 1 + /* 1 byte to encode map */ \
- 2 + /* 2 bytes to encode key type */ \
- 2 + /* 2 bytes to encode curve */ \
- 2 * /* the X and Y coordinates at 32 bytes each */ \
- (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2)
#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
#define COSE_SIG_CONTEXT_STRING_SIGNATURE1 "Signature1"
@@ -78,71 +52,9 @@
sizeof(COSE_SIG_CONTEXT_STRING_SIGNATURE1) + /* "Signature1" */ \
2 + /* Overhead for encoding string */ \
T_COSE_SIGN1_MAX_PROT_HEADER + /* entire protected headers */ \
- 3 * ( /* 3 NULL bstrs for fields not used */ \
+ 3 * (/* 3 NULL bstrs for fields not used */ \
1 /* size of a NULL bstr */ \
)
-
-/*
- CBOR Label for proprietary header indicating short-circuit
- signing was used. Just a random number in the proprietary
- label space */
-#define T_COSE_SHORT_CIRCUIT_LABEL (-8675309)
-
-#define EAT_CBOR_ARM_RANGE_BASE (-75000)
-#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
-#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
-#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
-#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
-#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
-#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
-#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
-#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
-#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
-#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
-#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
-
-#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
-
-#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
-#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
-#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
-#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
-
-#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
-
-#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
-
-#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
- 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
-
#define NULL_USEFUL_BUF_C NULLUsefulBufC
enum attestation_error_code {
@@ -161,13 +73,8 @@
PAL_ATTEST_ERR_KEY_FAIL,
PAL_ATTEST_ERR_SIGNATURE_FAIL,
PAL_ATTEST_ERR_CBOR_STRUCTURE,
+ PAL_ATTEST_ERR_SMALL_BUFFER,
PAL_ATTEST_ERROR,
};
-struct items_to_get_t {
- int64_t label;
- QCBORItem item;
-};
-
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size);
+#endif /* _PAL_ATTESTATION_EAT_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_intf.h
index 12f6ee9..3ab7ebb 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/nspe/initial_attestation/pal_attestation_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_INITIAL_ATTESTATION_H_
-#define _PAL_INITIAL_ATTESTATION_H_
+#ifndef _PAL_ATTESTATION_INTF_H_
+#define _PAL_ATTESTATION_INTF_H_
#include "pal_attestation_crypto.h"
@@ -24,7 +24,9 @@
PAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
PAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
PAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ PAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ PAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
int32_t pal_attestation_function(int type, va_list valist);
-#endif /* _PAL_INITIAL_ATTESTATION_H_ */
+#endif /* _PAL_ATTESTATION_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/target.cmake b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/target.cmake
index 5c5c942..db9a4fa 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_an524/target.cmake
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_an524/target.cmake
@@ -71,7 +71,6 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
list(APPEND PAL_SRC_C_NSPE
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_intf.c
- ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_eat.c
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_crypto.c
)
endif()
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/common/pal_config.h
index 2871339..61db8d8 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/common/pal_config.h
@@ -43,6 +43,9 @@
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.c b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.c
index 2da03fa..04fe5ef 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.c
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.c
@@ -19,29 +19,13 @@
static uint32_t public_key_registered;
static psa_key_handle_t public_key_handle;
+
static inline struct q_useful_buf_c useful_buf_head(struct q_useful_buf_c buf,
size_t amount)
{
return UsefulBuf_Head(buf, amount);
}
-static psa_ecc_curve_t attest_map_elliptic_curve_type(int32_t cose_curve)
-{
- psa_ecc_curve_t psa_curve;
-
- /*FixMe: Mapping is not complete, missing ones: P384, P521, ED25519, ED448 */
- switch (cose_curve)
- {
- case P_256:
- psa_curve = PSA_ECC_CURVE_SECP256R1;
- break;
- default:
- psa_curve = USHRT_MAX;
- }
-
- return psa_curve;
-}
-
static psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
{
psa_algorithm_t status;
@@ -137,6 +121,15 @@
return status;
}
+/**
+ @brief - Computes hash for the requested data
+ @param - cose_alg_id : Algorithm ID
+ - buffer_for_hash : Temp buffer for calculating hash
+ - hash : Pointer to store the hash
+ - protected_headers : Buffer containing protected data
+ - payload : payload data
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_compute_hash(int32_t cose_alg_id, struct q_useful_buf buffer_for_hash,
struct q_useful_buf_c *hash, struct q_useful_buf_c protected_headers,
struct q_useful_buf_c payload)
@@ -203,22 +196,56 @@
return status;
}
+static int32_t pal_attest_get_public_key(uint8_t *public_key_buff, size_t public_key_buf_size,
+ size_t *public_key_len, psa_ecc_curve_t *elliptic_curve_type)
+{
+ int32_t status = PAL_ATTEST_ERROR;
+
+#ifdef PLATFORM_OVERRIDE_ATTEST_PK
+ if (public_key_buf_size < (attest_key.pubx_key_size + attest_key.puby_key_size + 1))
+ return PAL_ATTEST_ERR_SMALL_BUFFER;
+
+ *public_key_len = (attest_key.pubx_key_size + attest_key.puby_key_size + 1);
+ *elliptic_curve_type = PSA_ECC_CURVE_SECP256R1;
+ memcpy(public_key_buff, (void *)&attest_public_key, *public_key_len);
+ status = PSA_SUCCESS;
+#else
+ status = tfm_initial_attest_get_public_key(public_key_buff,
+ public_key_buf_size,
+ public_key_len,
+ elliptic_curve_type);
+#endif
+
+ return status;
+}
+
static uint32_t pal_import_attest_key(psa_algorithm_t key_alg)
{
psa_status_t status = PAL_ATTEST_ERROR;
psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY;
- psa_ecc_curve_t psa_curve = attest_map_elliptic_curve_type(P_256);
- psa_key_type_t attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve);
- size_t public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
+ psa_ecc_curve_t ecc_curve;
+ psa_key_type_t attest_key_type;
+ size_t public_key_size;
+ uint8_t public_key_buff[ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH] = {0};
#if defined(CRYPTO_VERSION_BETA1) || defined(CRYPTO_VERSION_BETA2)
psa_key_policy_t policy;
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Setup the key policy for public key */
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, key_alg);
@@ -234,8 +261,8 @@
/* Import the public key */
status = psa_import_key(public_key_handle,
attest_key_type,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1);
+ public_key_buff,
+ public_key_size);
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -247,21 +274,30 @@
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Set the attributes for the public key */
psa_set_key_type(&attributes, attest_key_type);
- psa_set_key_bits(&attributes, public_key_size + 1);
+ psa_set_key_bits(&attributes, public_key_size);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, key_alg);
/* Import the public key */
status = psa_import_key(&attributes,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1,
+ public_key_buff,
+ public_key_size,
&public_key_handle);
-
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -288,6 +324,13 @@
return PAL_ATTEST_SUCCESS;
}
+/**
+ @brief - Verify the signature using the public key
+ @param - cose_algorithm_id : Algorithm ID
+ - token_hash : Data that needs to be verified
+ - signature : Signature to be verified against
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id,
struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature)
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.h
index bd47990..559a24c 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_crypto.h
@@ -15,12 +15,15 @@
* limitations under the License.
**/
-#include "pal_common.h"
+#ifndef _PAL_ATTESTATION_CRYPTO_H_
+#define _PAL_ATTESTATION_CRYPTO_H_
+
#include "pal_attestation_eat.h"
-#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH (1 + 2 * PSA_BITS_TO_BYTES(256))
-typedef struct{
+typedef struct {
uint8_t *pubx_key;
size_t pubx_key_size;
uint8_t *puby_key;
@@ -47,16 +50,14 @@
0x0F, 0x34, 0x11, 0x7D, 0x97, 0x1D, 0x68, 0x64},
};
-static const uint8_t initial_attestation_public_x_key[] =
-{
+static const uint8_t initial_attestation_public_x_key[] = {
0x79, 0xEB, 0xA9, 0x0E, 0x8B, 0xF4, 0x50, 0xA6,
0x75, 0x15, 0x76, 0xAD, 0x45, 0x99, 0xB0, 0x7A,
0xDF, 0x93, 0x8D, 0xA3, 0xBB, 0x0B, 0xD1, 0x7D,
0x00, 0x36, 0xED, 0x49, 0xA2, 0xD0, 0xFC, 0x3F
};
-static const uint8_t initial_attestation_public_y_key[] =
-{
+static const uint8_t initial_attestation_public_y_key[] = {
0xBF, 0xCD, 0xFA, 0x89, 0x56, 0xB5, 0x68, 0xBF,
0xDB, 0x86, 0x73, 0xE6, 0x48, 0xD8, 0xB5, 0x8D,
0x92, 0x99, 0x55, 0xB1, 0x4A, 0x26, 0xC3, 0x08,
@@ -84,5 +85,4 @@
struct q_useful_buf_c payload);
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id, struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature);
-
-
+#endif /* _PAL_ATTESTATION_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.c b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.c
deleted file mode 100644
index 68c4312..0000000
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @file
- * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
- * SPDX-License-Identifier : Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-**/
-
-#include "pal_attestation_crypto.h"
-
-uint32_t mandatory_claims = 0;
-uint32_t mandaroty_sw_components = 0;
-bool_t sw_component_present = 0;
-
-int pal_encode_cose_key(struct q_useful_buf_c *cose_key,
- struct q_useful_buf buffer_for_cose_key,
- struct q_useful_buf_c x_cord, struct q_useful_buf_c y_cord)
-{
- uint32_t return_value;
- QCBORError qcbor_result;
- QCBOREncodeContext cbor_encode_ctx;
- int32_t cose_curve_id = P_256;
- struct q_useful_buf_c encoded_key_id;
-
- /* Get the public key x and y */
- /* Encode it into a COSE_Key structure */
- QCBOREncode_Init(&cbor_encode_ctx, buffer_for_cose_key);
- QCBOREncode_OpenMap(&cbor_encode_ctx);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_COMMON_KTY,
- COSE_KEY_TYPE_EC2);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_CRV,
- cose_curve_id);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_X_COORDINATE,
- x_cord);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_Y_COORDINATE,
- y_cord);
- QCBOREncode_CloseMap(&cbor_encode_ctx);
-
- qcbor_result = QCBOREncode_Finish(&cbor_encode_ctx, &encoded_key_id);
- if (qcbor_result != QCBOR_SUCCESS)
- {
- /* Mainly means that the COSE_Key was too big for buffer_for_cose_key */
- return_value = PAL_ATTEST_ERR_PROTECTED_HEADERS;
- goto Done;
- }
-
- /* Finish up and return */
- *cose_key = encoded_key_id;
- return_value = PAL_ATTEST_SUCCESS;
-
-Done:
- return return_value;
-}
-
-
-static int get_items_in_map(QCBORDecodeContext *decode_context,
- struct items_to_get_t *item_list)
-{
- int item_index;
- QCBORItem item;
- struct items_to_get_t *item_ptr = item_list;
-
- /* initialize the data type of all items in the list */
- while (item_ptr->label != 0)
- {
- item_ptr->item.uDataType = QCBOR_TYPE_NONE;
- item_ptr++;
- }
-
- QCBORDecode_GetNext(decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_MAP)
- {
- return PAL_ATTEST_ERROR;
- }
-
- for (item_index = item.val.uCount; item_index != 0; item_index--)
- {
- if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- if (item.uLabelType != QCBOR_TYPE_INT64)
- {
- continue;
- }
-
- item_ptr = item_list;
- while (item_ptr->label != 0)
- {
- if (item.label.int64 == item_ptr->label)
- {
- item_ptr->item = item;
- }
- item_ptr++;
- }
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int get_item_in_map(QCBORDecodeContext *decode_context,
- int32_t label,
- QCBORItem *item)
-{
- struct items_to_get_t item_list[2];
-
- item_list[0].label = label;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- *item = item_list[0].item;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
- struct q_useful_buf_c *child)
-{
- struct items_to_get_t item_list[3];
-
- item_list[0].label = COSE_HEADER_PARAM_KID;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERR_CBOR_STRUCTURE;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_protected_headers(struct q_useful_buf_c protected_headers,
- int32_t *alg_id)
-{
- QCBORDecodeContext decode_context;
- QCBORItem item;
-
- QCBORDecode_Init(&decode_context, protected_headers, 0);
-
- if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (QCBORDecode_Finish(&decode_context))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
- {
- return PAL_ATTEST_ERROR;
- }
-
- *alg_id = (int32_t)item.val.int64;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-/**
- @brief - This API will verify the claims
- @param - decode_context : The buffer containing the challenge
- item : context for decoding the data items
- completed_challenge : Buffer containing the challenge
- @return - error status
-**/
-static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
- struct q_useful_buf_c completed_challenge)
-{
- int i, count = 0;
- int status = PAL_ATTEST_SUCCESS;
-
- /* Parse each claim and validate their data type */
- while (status == PAL_ATTEST_SUCCESS)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- break;
-
- mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
- if (item.uLabelType == QCBOR_TYPE_INT64)
- {
- if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
- {
- if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
- {
- /* Given challenge vs challenge in token */
- if (UsefulBuf_Compare(item.val.string, completed_challenge))
- return PAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
- }
- else
- return PAL_ATTEST_TOKEN_NOT_SUPPORTED;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
- {
- if (item.uDataType != QCBOR_TYPE_ARRAY)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- sw_component_present = 1;
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- continue;
-
- count = item.val.uCount;
- for (i = 0; i <= count; i++)
- {
- mandaroty_sw_components |= 1 << item.label.int64;
-
- if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- if (i < count)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- }
-
- }
- }
- else
- {
- /* ToDo: Add other claim types */
- }
- }
-
- if (status == QCBOR_ERR_HIT_END)
- return PAL_ATTEST_SUCCESS;
- else
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-}
-
-/**
- @brief - This API will verify the attestation token
- @param - challenge : The buffer containing the challenge
- challenge_size : Size of the challenge buffer
- token : The buffer containing the attestation token
- token_size : Size of the token buffer
- @return - error status
-**/
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size)
-{
- int32_t status = PAL_ATTEST_SUCCESS;
- int32_t cose_algorithm_id;
- QCBORItem item;
- QCBORDecodeContext decode_context;
- struct q_useful_buf_c completed_challenge;
- struct q_useful_buf_c completed_token;
- struct q_useful_buf_c payload;
- struct q_useful_buf_c signature;
- struct q_useful_buf_c protected_headers;
- struct q_useful_buf_c kid;
- struct q_useful_buf_c token_hash;
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_x_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_y_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
-
- kid.ptr = buffer_for_encoded_key.ptr;
-
- memcpy(buf_to_hold_x_coord.ptr, (const void *)attest_key.pubx_key, attest_key.pubx_key_size);
- memcpy(buf_to_hold_y_coord.ptr, (const void *)attest_key.puby_key, attest_key.puby_key_size);
-
- /* Update size */
- buf_to_hold_x_coord.len = attest_key.pubx_key_size;
- buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
- /* Construct the token buffer for validation */
- completed_token.ptr = token;
- completed_token.len = token_size;
-
- /* Construct the challenge buffer for validation */
- completed_challenge.ptr = challenge;
- completed_challenge.len = challenge_size;
-
-/*
- -------------------------
- | CBOR Array Type |
- -------------------------
- | Protected Headers |
- -------------------------
- | Unprotected Headers |
- -------------------------
- | Payload |
- -------------------------
- | Signature |
- -------------------------
-*/
-
- /* Initialize the decorder */
- QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
-
- /* Get the Header */
- QCBORDecode_GetNext(&decode_context, &item);
-
- /* Check the CBOR Array type. Check if the count is 4.
- * Only COSE_SIGN1 is supported now.
- */
- if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
- !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Get the next headers */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- protected_headers = item.val.string;
-
- /* Parse the protected headers and check the data type and value*/
- status = parse_protected_headers(protected_headers, &cose_algorithm_id);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Parse the unprotected headers and check the data type and value */
- status = parse_unprotected_headers(&decode_context, &kid);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Get the payload */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- payload = item.val.string;
-
- /* Get the digital signature */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- signature = item.val.string;
-
- /* Compute the hash from the token */
- status = pal_compute_hash(cose_algorithm_id, buffer_for_token_hash, &token_hash,
- protected_headers, payload);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Verify the signature */
- status = pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Initialize the Decoder and validate the payload format */
- QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
- status = QCBORDecode_GetNext(&decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if (item.uDataType != QCBOR_TYPE_MAP)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Parse the payload and check the data type of each claim */
- status = parse_claims(&decode_context, item, completed_challenge);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
- {
- if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
- else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
- {
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.h
index df24c89..fae5434 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_eat.h
@@ -15,43 +15,17 @@
* limitations under the License.
**/
+#ifndef _PAL_ATTESTATION_EAT_H_
+#define _PAL_ATTESTATION_EAT_H_
+
#include "qcbor.h"
#include "pal_common.h"
-#include "psa/crypto.h"
#define PAL_ATTEST_MIN_ERROR 30
-/* NIST P-256 also known as secp256r1 */
-#define P_256 1
-
-#define COSE_HEADER_PARAM_ALG 1
-#define COSE_HEADER_PARAM_KID 4
-
-#define COSE_KEY_COMMON_KTY 1
-#define COSE_KEY_TYPE_EC2 2
-#define COSE_KEY_PARAM_CRV -1
-#define COSE_KEY_PARAM_X_COORDINATE -2
-#define COSE_KEY_PARAM_Y_COORDINATE -3
#define COSE_ALGORITHM_ES256 -7
#define COSE_ALG_SHA256_PROPRIETARY -72000
-/**
- * The size of X and Y coordinate in 2 parameter style EC public
- * key. Format is as defined in [COSE (RFC 8152)]
- * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
- * Cryptography](http://www.secg.org/sec1-v2.pdf).
- *
- * This size is well-known and documented in public standards.
- */
-#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
-#define T_COSE_CRYPTO_SHA256_SIZE 32
-
-#define MAX_ENCODED_COSE_KEY_SIZE \
- 1 + /* 1 byte to encode map */ \
- 2 + /* 2 bytes to encode key type */ \
- 2 + /* 2 bytes to encode curve */ \
- 2 * /* the X and Y coordinates at 32 bytes each */ \
- (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2)
#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
#define COSE_SIG_CONTEXT_STRING_SIGNATURE1 "Signature1"
@@ -78,71 +52,9 @@
sizeof(COSE_SIG_CONTEXT_STRING_SIGNATURE1) + /* "Signature1" */ \
2 + /* Overhead for encoding string */ \
T_COSE_SIGN1_MAX_PROT_HEADER + /* entire protected headers */ \
- 3 * ( /* 3 NULL bstrs for fields not used */ \
+ 3 * (/* 3 NULL bstrs for fields not used */ \
1 /* size of a NULL bstr */ \
)
-
-/*
- CBOR Label for proprietary header indicating short-circuit
- signing was used. Just a random number in the proprietary
- label space */
-#define T_COSE_SHORT_CIRCUIT_LABEL (-8675309)
-
-#define EAT_CBOR_ARM_RANGE_BASE (-75000)
-#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
-#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
-#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
-#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
-#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
-#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
-#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
-#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
-#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
-#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
-#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
-
-#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
-
-#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
-#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
-#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
-#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
-
-#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
-
-#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
-
-#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
- 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
-
#define NULL_USEFUL_BUF_C NULLUsefulBufC
enum attestation_error_code {
@@ -161,13 +73,8 @@
PAL_ATTEST_ERR_KEY_FAIL,
PAL_ATTEST_ERR_SIGNATURE_FAIL,
PAL_ATTEST_ERR_CBOR_STRUCTURE,
+ PAL_ATTEST_ERR_SMALL_BUFFER,
PAL_ATTEST_ERROR,
};
-struct items_to_get_t {
- int64_t label;
- QCBORItem item;
-};
-
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size);
+#endif /* _PAL_ATTESTATION_EAT_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_intf.h
index 12f6ee9..3ab7ebb 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/nspe/initial_attestation/pal_attestation_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_INITIAL_ATTESTATION_H_
-#define _PAL_INITIAL_ATTESTATION_H_
+#ifndef _PAL_ATTESTATION_INTF_H_
+#define _PAL_ATTESTATION_INTF_H_
#include "pal_attestation_crypto.h"
@@ -24,7 +24,9 @@
PAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
PAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
PAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ PAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ PAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
int32_t pal_attestation_function(int type, va_list valist);
-#endif /* _PAL_INITIAL_ATTESTATION_H_ */
+#endif /* _PAL_ATTESTATION_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/target.cmake b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/target.cmake
index 7c6628a..756a0b4 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/target.cmake
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_a/target.cmake
@@ -71,7 +71,6 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
list(APPEND PAL_SRC_C_NSPE
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_intf.c
- ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_eat.c
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_crypto.c
)
endif()
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/common/pal_config.h
index 2871339..61db8d8 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/common/pal_config.h
@@ -43,6 +43,9 @@
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.c b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.c
index 2da03fa..04fe5ef 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.c
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.c
@@ -19,29 +19,13 @@
static uint32_t public_key_registered;
static psa_key_handle_t public_key_handle;
+
static inline struct q_useful_buf_c useful_buf_head(struct q_useful_buf_c buf,
size_t amount)
{
return UsefulBuf_Head(buf, amount);
}
-static psa_ecc_curve_t attest_map_elliptic_curve_type(int32_t cose_curve)
-{
- psa_ecc_curve_t psa_curve;
-
- /*FixMe: Mapping is not complete, missing ones: P384, P521, ED25519, ED448 */
- switch (cose_curve)
- {
- case P_256:
- psa_curve = PSA_ECC_CURVE_SECP256R1;
- break;
- default:
- psa_curve = USHRT_MAX;
- }
-
- return psa_curve;
-}
-
static psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
{
psa_algorithm_t status;
@@ -137,6 +121,15 @@
return status;
}
+/**
+ @brief - Computes hash for the requested data
+ @param - cose_alg_id : Algorithm ID
+ - buffer_for_hash : Temp buffer for calculating hash
+ - hash : Pointer to store the hash
+ - protected_headers : Buffer containing protected data
+ - payload : payload data
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_compute_hash(int32_t cose_alg_id, struct q_useful_buf buffer_for_hash,
struct q_useful_buf_c *hash, struct q_useful_buf_c protected_headers,
struct q_useful_buf_c payload)
@@ -203,22 +196,56 @@
return status;
}
+static int32_t pal_attest_get_public_key(uint8_t *public_key_buff, size_t public_key_buf_size,
+ size_t *public_key_len, psa_ecc_curve_t *elliptic_curve_type)
+{
+ int32_t status = PAL_ATTEST_ERROR;
+
+#ifdef PLATFORM_OVERRIDE_ATTEST_PK
+ if (public_key_buf_size < (attest_key.pubx_key_size + attest_key.puby_key_size + 1))
+ return PAL_ATTEST_ERR_SMALL_BUFFER;
+
+ *public_key_len = (attest_key.pubx_key_size + attest_key.puby_key_size + 1);
+ *elliptic_curve_type = PSA_ECC_CURVE_SECP256R1;
+ memcpy(public_key_buff, (void *)&attest_public_key, *public_key_len);
+ status = PSA_SUCCESS;
+#else
+ status = tfm_initial_attest_get_public_key(public_key_buff,
+ public_key_buf_size,
+ public_key_len,
+ elliptic_curve_type);
+#endif
+
+ return status;
+}
+
static uint32_t pal_import_attest_key(psa_algorithm_t key_alg)
{
psa_status_t status = PAL_ATTEST_ERROR;
psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY;
- psa_ecc_curve_t psa_curve = attest_map_elliptic_curve_type(P_256);
- psa_key_type_t attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve);
- size_t public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
+ psa_ecc_curve_t ecc_curve;
+ psa_key_type_t attest_key_type;
+ size_t public_key_size;
+ uint8_t public_key_buff[ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH] = {0};
#if defined(CRYPTO_VERSION_BETA1) || defined(CRYPTO_VERSION_BETA2)
psa_key_policy_t policy;
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Setup the key policy for public key */
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, key_alg);
@@ -234,8 +261,8 @@
/* Import the public key */
status = psa_import_key(public_key_handle,
attest_key_type,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1);
+ public_key_buff,
+ public_key_size);
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -247,21 +274,30 @@
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Set the attributes for the public key */
psa_set_key_type(&attributes, attest_key_type);
- psa_set_key_bits(&attributes, public_key_size + 1);
+ psa_set_key_bits(&attributes, public_key_size);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, key_alg);
/* Import the public key */
status = psa_import_key(&attributes,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1,
+ public_key_buff,
+ public_key_size,
&public_key_handle);
-
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -288,6 +324,13 @@
return PAL_ATTEST_SUCCESS;
}
+/**
+ @brief - Verify the signature using the public key
+ @param - cose_algorithm_id : Algorithm ID
+ - token_hash : Data that needs to be verified
+ - signature : Signature to be verified against
+ @return - SUCCESS/ERROR CODE
+**/
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id,
struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature)
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.h
index bd47990..559a24c 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_crypto.h
@@ -15,12 +15,15 @@
* limitations under the License.
**/
-#include "pal_common.h"
+#ifndef _PAL_ATTESTATION_CRYPTO_H_
+#define _PAL_ATTESTATION_CRYPTO_H_
+
#include "pal_attestation_eat.h"
-#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH (1 + 2 * PSA_BITS_TO_BYTES(256))
-typedef struct{
+typedef struct {
uint8_t *pubx_key;
size_t pubx_key_size;
uint8_t *puby_key;
@@ -47,16 +50,14 @@
0x0F, 0x34, 0x11, 0x7D, 0x97, 0x1D, 0x68, 0x64},
};
-static const uint8_t initial_attestation_public_x_key[] =
-{
+static const uint8_t initial_attestation_public_x_key[] = {
0x79, 0xEB, 0xA9, 0x0E, 0x8B, 0xF4, 0x50, 0xA6,
0x75, 0x15, 0x76, 0xAD, 0x45, 0x99, 0xB0, 0x7A,
0xDF, 0x93, 0x8D, 0xA3, 0xBB, 0x0B, 0xD1, 0x7D,
0x00, 0x36, 0xED, 0x49, 0xA2, 0xD0, 0xFC, 0x3F
};
-static const uint8_t initial_attestation_public_y_key[] =
-{
+static const uint8_t initial_attestation_public_y_key[] = {
0xBF, 0xCD, 0xFA, 0x89, 0x56, 0xB5, 0x68, 0xBF,
0xDB, 0x86, 0x73, 0xE6, 0x48, 0xD8, 0xB5, 0x8D,
0x92, 0x99, 0x55, 0xB1, 0x4A, 0x26, 0xC3, 0x08,
@@ -84,5 +85,4 @@
struct q_useful_buf_c payload);
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id, struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature);
-
-
+#endif /* _PAL_ATTESTATION_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.c b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.c
deleted file mode 100644
index 68c4312..0000000
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @file
- * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
- * SPDX-License-Identifier : Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-**/
-
-#include "pal_attestation_crypto.h"
-
-uint32_t mandatory_claims = 0;
-uint32_t mandaroty_sw_components = 0;
-bool_t sw_component_present = 0;
-
-int pal_encode_cose_key(struct q_useful_buf_c *cose_key,
- struct q_useful_buf buffer_for_cose_key,
- struct q_useful_buf_c x_cord, struct q_useful_buf_c y_cord)
-{
- uint32_t return_value;
- QCBORError qcbor_result;
- QCBOREncodeContext cbor_encode_ctx;
- int32_t cose_curve_id = P_256;
- struct q_useful_buf_c encoded_key_id;
-
- /* Get the public key x and y */
- /* Encode it into a COSE_Key structure */
- QCBOREncode_Init(&cbor_encode_ctx, buffer_for_cose_key);
- QCBOREncode_OpenMap(&cbor_encode_ctx);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_COMMON_KTY,
- COSE_KEY_TYPE_EC2);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_CRV,
- cose_curve_id);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_X_COORDINATE,
- x_cord);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_Y_COORDINATE,
- y_cord);
- QCBOREncode_CloseMap(&cbor_encode_ctx);
-
- qcbor_result = QCBOREncode_Finish(&cbor_encode_ctx, &encoded_key_id);
- if (qcbor_result != QCBOR_SUCCESS)
- {
- /* Mainly means that the COSE_Key was too big for buffer_for_cose_key */
- return_value = PAL_ATTEST_ERR_PROTECTED_HEADERS;
- goto Done;
- }
-
- /* Finish up and return */
- *cose_key = encoded_key_id;
- return_value = PAL_ATTEST_SUCCESS;
-
-Done:
- return return_value;
-}
-
-
-static int get_items_in_map(QCBORDecodeContext *decode_context,
- struct items_to_get_t *item_list)
-{
- int item_index;
- QCBORItem item;
- struct items_to_get_t *item_ptr = item_list;
-
- /* initialize the data type of all items in the list */
- while (item_ptr->label != 0)
- {
- item_ptr->item.uDataType = QCBOR_TYPE_NONE;
- item_ptr++;
- }
-
- QCBORDecode_GetNext(decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_MAP)
- {
- return PAL_ATTEST_ERROR;
- }
-
- for (item_index = item.val.uCount; item_index != 0; item_index--)
- {
- if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- if (item.uLabelType != QCBOR_TYPE_INT64)
- {
- continue;
- }
-
- item_ptr = item_list;
- while (item_ptr->label != 0)
- {
- if (item.label.int64 == item_ptr->label)
- {
- item_ptr->item = item;
- }
- item_ptr++;
- }
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int get_item_in_map(QCBORDecodeContext *decode_context,
- int32_t label,
- QCBORItem *item)
-{
- struct items_to_get_t item_list[2];
-
- item_list[0].label = label;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- *item = item_list[0].item;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
- struct q_useful_buf_c *child)
-{
- struct items_to_get_t item_list[3];
-
- item_list[0].label = COSE_HEADER_PARAM_KID;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERR_CBOR_STRUCTURE;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_protected_headers(struct q_useful_buf_c protected_headers,
- int32_t *alg_id)
-{
- QCBORDecodeContext decode_context;
- QCBORItem item;
-
- QCBORDecode_Init(&decode_context, protected_headers, 0);
-
- if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (QCBORDecode_Finish(&decode_context))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
- {
- return PAL_ATTEST_ERROR;
- }
-
- *alg_id = (int32_t)item.val.int64;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-/**
- @brief - This API will verify the claims
- @param - decode_context : The buffer containing the challenge
- item : context for decoding the data items
- completed_challenge : Buffer containing the challenge
- @return - error status
-**/
-static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
- struct q_useful_buf_c completed_challenge)
-{
- int i, count = 0;
- int status = PAL_ATTEST_SUCCESS;
-
- /* Parse each claim and validate their data type */
- while (status == PAL_ATTEST_SUCCESS)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- break;
-
- mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
- if (item.uLabelType == QCBOR_TYPE_INT64)
- {
- if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
- {
- if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
- {
- /* Given challenge vs challenge in token */
- if (UsefulBuf_Compare(item.val.string, completed_challenge))
- return PAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
- }
- else
- return PAL_ATTEST_TOKEN_NOT_SUPPORTED;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
- {
- if (item.uDataType != QCBOR_TYPE_ARRAY)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- sw_component_present = 1;
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- continue;
-
- count = item.val.uCount;
- for (i = 0; i <= count; i++)
- {
- mandaroty_sw_components |= 1 << item.label.int64;
-
- if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- if (i < count)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- }
-
- }
- }
- else
- {
- /* ToDo: Add other claim types */
- }
- }
-
- if (status == QCBOR_ERR_HIT_END)
- return PAL_ATTEST_SUCCESS;
- else
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-}
-
-/**
- @brief - This API will verify the attestation token
- @param - challenge : The buffer containing the challenge
- challenge_size : Size of the challenge buffer
- token : The buffer containing the attestation token
- token_size : Size of the token buffer
- @return - error status
-**/
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size)
-{
- int32_t status = PAL_ATTEST_SUCCESS;
- int32_t cose_algorithm_id;
- QCBORItem item;
- QCBORDecodeContext decode_context;
- struct q_useful_buf_c completed_challenge;
- struct q_useful_buf_c completed_token;
- struct q_useful_buf_c payload;
- struct q_useful_buf_c signature;
- struct q_useful_buf_c protected_headers;
- struct q_useful_buf_c kid;
- struct q_useful_buf_c token_hash;
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_x_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_y_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
-
- kid.ptr = buffer_for_encoded_key.ptr;
-
- memcpy(buf_to_hold_x_coord.ptr, (const void *)attest_key.pubx_key, attest_key.pubx_key_size);
- memcpy(buf_to_hold_y_coord.ptr, (const void *)attest_key.puby_key, attest_key.puby_key_size);
-
- /* Update size */
- buf_to_hold_x_coord.len = attest_key.pubx_key_size;
- buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
- /* Construct the token buffer for validation */
- completed_token.ptr = token;
- completed_token.len = token_size;
-
- /* Construct the challenge buffer for validation */
- completed_challenge.ptr = challenge;
- completed_challenge.len = challenge_size;
-
-/*
- -------------------------
- | CBOR Array Type |
- -------------------------
- | Protected Headers |
- -------------------------
- | Unprotected Headers |
- -------------------------
- | Payload |
- -------------------------
- | Signature |
- -------------------------
-*/
-
- /* Initialize the decorder */
- QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
-
- /* Get the Header */
- QCBORDecode_GetNext(&decode_context, &item);
-
- /* Check the CBOR Array type. Check if the count is 4.
- * Only COSE_SIGN1 is supported now.
- */
- if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
- !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Get the next headers */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- protected_headers = item.val.string;
-
- /* Parse the protected headers and check the data type and value*/
- status = parse_protected_headers(protected_headers, &cose_algorithm_id);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Parse the unprotected headers and check the data type and value */
- status = parse_unprotected_headers(&decode_context, &kid);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Get the payload */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- payload = item.val.string;
-
- /* Get the digital signature */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- signature = item.val.string;
-
- /* Compute the hash from the token */
- status = pal_compute_hash(cose_algorithm_id, buffer_for_token_hash, &token_hash,
- protected_headers, payload);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Verify the signature */
- status = pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Initialize the Decoder and validate the payload format */
- QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
- status = QCBORDecode_GetNext(&decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if (item.uDataType != QCBOR_TYPE_MAP)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Parse the payload and check the data type of each claim */
- status = parse_claims(&decode_context, item, completed_challenge);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
- {
- if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
- else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
- {
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.h
index df24c89..fae5434 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_eat.h
@@ -15,43 +15,17 @@
* limitations under the License.
**/
+#ifndef _PAL_ATTESTATION_EAT_H_
+#define _PAL_ATTESTATION_EAT_H_
+
#include "qcbor.h"
#include "pal_common.h"
-#include "psa/crypto.h"
#define PAL_ATTEST_MIN_ERROR 30
-/* NIST P-256 also known as secp256r1 */
-#define P_256 1
-
-#define COSE_HEADER_PARAM_ALG 1
-#define COSE_HEADER_PARAM_KID 4
-
-#define COSE_KEY_COMMON_KTY 1
-#define COSE_KEY_TYPE_EC2 2
-#define COSE_KEY_PARAM_CRV -1
-#define COSE_KEY_PARAM_X_COORDINATE -2
-#define COSE_KEY_PARAM_Y_COORDINATE -3
#define COSE_ALGORITHM_ES256 -7
#define COSE_ALG_SHA256_PROPRIETARY -72000
-/**
- * The size of X and Y coordinate in 2 parameter style EC public
- * key. Format is as defined in [COSE (RFC 8152)]
- * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
- * Cryptography](http://www.secg.org/sec1-v2.pdf).
- *
- * This size is well-known and documented in public standards.
- */
-#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
-#define T_COSE_CRYPTO_SHA256_SIZE 32
-
-#define MAX_ENCODED_COSE_KEY_SIZE \
- 1 + /* 1 byte to encode map */ \
- 2 + /* 2 bytes to encode key type */ \
- 2 + /* 2 bytes to encode curve */ \
- 2 * /* the X and Y coordinates at 32 bytes each */ \
- (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2)
#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
#define COSE_SIG_CONTEXT_STRING_SIGNATURE1 "Signature1"
@@ -78,71 +52,9 @@
sizeof(COSE_SIG_CONTEXT_STRING_SIGNATURE1) + /* "Signature1" */ \
2 + /* Overhead for encoding string */ \
T_COSE_SIGN1_MAX_PROT_HEADER + /* entire protected headers */ \
- 3 * ( /* 3 NULL bstrs for fields not used */ \
+ 3 * (/* 3 NULL bstrs for fields not used */ \
1 /* size of a NULL bstr */ \
)
-
-/*
- CBOR Label for proprietary header indicating short-circuit
- signing was used. Just a random number in the proprietary
- label space */
-#define T_COSE_SHORT_CIRCUIT_LABEL (-8675309)
-
-#define EAT_CBOR_ARM_RANGE_BASE (-75000)
-#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
-#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
-#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
-#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
-#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
-#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
-#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
-#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
-#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
-#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
-#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
-
-#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
-
-#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
-#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
-#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
-#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
-
-#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
-
-#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
-
-#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
- 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
-
#define NULL_USEFUL_BUF_C NULLUsefulBufC
enum attestation_error_code {
@@ -161,13 +73,8 @@
PAL_ATTEST_ERR_KEY_FAIL,
PAL_ATTEST_ERR_SIGNATURE_FAIL,
PAL_ATTEST_ERR_CBOR_STRUCTURE,
+ PAL_ATTEST_ERR_SMALL_BUFFER,
PAL_ATTEST_ERROR,
};
-struct items_to_get_t {
- int64_t label;
- QCBORItem item;
-};
-
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size);
+#endif /* _PAL_ATTESTATION_EAT_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_intf.h b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_intf.h
index 12f6ee9..3ab7ebb 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_intf.h
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/nspe/initial_attestation/pal_attestation_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_INITIAL_ATTESTATION_H_
-#define _PAL_INITIAL_ATTESTATION_H_
+#ifndef _PAL_ATTESTATION_INTF_H_
+#define _PAL_ATTESTATION_INTF_H_
#include "pal_attestation_crypto.h"
@@ -24,7 +24,9 @@
PAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
PAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
PAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ PAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ PAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
int32_t pal_attestation_function(int type, va_list valist);
-#endif /* _PAL_INITIAL_ATTESTATION_H_ */
+#endif /* _PAL_ATTESTATION_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/target.cmake b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/target.cmake
index 7c6628a..756a0b4 100644
--- a/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/target.cmake
+++ b/api-tests/platform/targets/tgt_dev_apis_tfm_musca_b1/target.cmake
@@ -71,7 +71,6 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
list(APPEND PAL_SRC_C_NSPE
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_intf.c
- ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_eat.c
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_crypto.c
)
endif()
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/common/pal_config.h b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/common/pal_config.h
index 2871339..61db8d8 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/common/pal_config.h
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/common/pal_config.h
@@ -43,6 +43,9 @@
/* Version of crypto spec used in attestation */
#define CRYPTO_VERSION_BETA2
+/* Use hardcoded public key */
+//#define PLATFORM_OVERRIDE_ATTEST_PK
+
/*
* Include of PSA defined Header files
*/
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h
index 486f793..671dfa0 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/crypto/pal_crypto_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_CRYPTO_H_
-#define _PAL_CRYPTO_H_
+#ifndef _PAL_CRYPTO_INTF_H_
+#define _PAL_CRYPTO_INTF_H_
#include "pal_common.h"
@@ -100,4 +100,4 @@
};
int32_t pal_crypto_function(int type, va_list valist);
-#endif /* _PAL_CRYPTO_H_ */
+#endif /* _PAL_CRYPTO_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c
index 2da03fa..488c96b 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.c
@@ -19,29 +19,13 @@
static uint32_t public_key_registered;
static psa_key_handle_t public_key_handle;
+
static inline struct q_useful_buf_c useful_buf_head(struct q_useful_buf_c buf,
size_t amount)
{
return UsefulBuf_Head(buf, amount);
}
-static psa_ecc_curve_t attest_map_elliptic_curve_type(int32_t cose_curve)
-{
- psa_ecc_curve_t psa_curve;
-
- /*FixMe: Mapping is not complete, missing ones: P384, P521, ED25519, ED448 */
- switch (cose_curve)
- {
- case P_256:
- psa_curve = PSA_ECC_CURVE_SECP256R1;
- break;
- default:
- psa_curve = USHRT_MAX;
- }
-
- return psa_curve;
-}
-
static psa_algorithm_t cose_hash_alg_id_to_psa(int32_t cose_hash_alg_id)
{
psa_algorithm_t status;
@@ -203,22 +187,56 @@
return status;
}
+static int32_t pal_attest_get_public_key(uint8_t *public_key_buff, size_t public_key_buf_size,
+ size_t *public_key_len, psa_ecc_curve_t *elliptic_curve_type)
+{
+ int32_t status = PAL_ATTEST_ERROR;
+
+#ifdef PLATFORM_OVERRIDE_ATTEST_PK
+ if (public_key_buf_size < (attest_key.pubx_key_size + attest_key.puby_key_size + 1))
+ return PAL_ATTEST_ERR_SMALL_BUFFER;
+
+ *public_key_len = (attest_key.pubx_key_size + attest_key.puby_key_size + 1);
+ *elliptic_curve_type = PSA_ECC_CURVE_SECP256R1;
+ memcpy(public_key_buff, (void *)&attest_public_key, *public_key_len);
+ status = PSA_SUCCESS;
+#else
+ status = tfm_initial_attest_get_public_key(public_key_buff,
+ public_key_buf_size,
+ public_key_len,
+ elliptic_curve_type);
+#endif
+
+ return status;
+}
+
static uint32_t pal_import_attest_key(psa_algorithm_t key_alg)
{
psa_status_t status = PAL_ATTEST_ERROR;
psa_key_usage_t usage = PSA_KEY_USAGE_VERIFY;
- psa_ecc_curve_t psa_curve = attest_map_elliptic_curve_type(P_256);
- psa_key_type_t attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(psa_curve);
- size_t public_key_size = attest_key.pubx_key_size + attest_key.puby_key_size;
+ psa_ecc_curve_t ecc_curve;
+ psa_key_type_t attest_key_type;
+ size_t public_key_size;
+ uint8_t public_key_buff[ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH] = {0};
#if defined(CRYPTO_VERSION_BETA1) || defined(CRYPTO_VERSION_BETA2)
psa_key_policy_t policy;
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Setup the key policy for public key */
policy = psa_key_policy_init();
psa_key_policy_set_usage(&policy, usage, key_alg);
@@ -234,8 +252,8 @@
/* Import the public key */
status = psa_import_key(public_key_handle,
attest_key_type,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1);
+ public_key_buff,
+ public_key_size);
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
@@ -247,21 +265,30 @@
if (!public_key_registered)
{
- if (psa_curve == USHRT_MAX)
+ status = pal_attest_get_public_key(public_key_buff,
+ sizeof(public_key_buff),
+ &public_key_size,
+ &ecc_curve);
+ if (status != PSA_SUCCESS)
+ return PAL_ATTEST_ERR_KEY_FAIL;
+
+ if (ecc_curve == USHRT_MAX)
return PAL_ATTEST_ERROR;
+ /* Set key type for public key */
+ attest_key_type = PSA_KEY_TYPE_ECC_PUBLIC_KEY(ecc_curve);
+
/* Set the attributes for the public key */
psa_set_key_type(&attributes, attest_key_type);
- psa_set_key_bits(&attributes, public_key_size + 1);
+ psa_set_key_bits(&attributes, public_key_size);
psa_set_key_usage_flags(&attributes, usage);
psa_set_key_algorithm(&attributes, key_alg);
/* Import the public key */
status = psa_import_key(&attributes,
- (const uint8_t *)&attest_public_key,
- public_key_size + 1,
+ public_key_buff,
+ public_key_size,
&public_key_handle);
-
if (status != PSA_SUCCESS)
return PAL_ATTEST_ERR_KEY_FAIL;
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h
index bd47990..559a24c 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_crypto.h
@@ -15,12 +15,15 @@
* limitations under the License.
**/
-#include "pal_common.h"
+#ifndef _PAL_ATTESTATION_CRYPTO_H_
+#define _PAL_ATTESTATION_CRYPTO_H_
+
#include "pal_attestation_eat.h"
-#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ATTEST_PUBLIC_KEY_SLOT 4
+#define ECC_CURVE_SECP256R1_PULBIC_KEY_LENGTH (1 + 2 * PSA_BITS_TO_BYTES(256))
-typedef struct{
+typedef struct {
uint8_t *pubx_key;
size_t pubx_key_size;
uint8_t *puby_key;
@@ -47,16 +50,14 @@
0x0F, 0x34, 0x11, 0x7D, 0x97, 0x1D, 0x68, 0x64},
};
-static const uint8_t initial_attestation_public_x_key[] =
-{
+static const uint8_t initial_attestation_public_x_key[] = {
0x79, 0xEB, 0xA9, 0x0E, 0x8B, 0xF4, 0x50, 0xA6,
0x75, 0x15, 0x76, 0xAD, 0x45, 0x99, 0xB0, 0x7A,
0xDF, 0x93, 0x8D, 0xA3, 0xBB, 0x0B, 0xD1, 0x7D,
0x00, 0x36, 0xED, 0x49, 0xA2, 0xD0, 0xFC, 0x3F
};
-static const uint8_t initial_attestation_public_y_key[] =
-{
+static const uint8_t initial_attestation_public_y_key[] = {
0xBF, 0xCD, 0xFA, 0x89, 0x56, 0xB5, 0x68, 0xBF,
0xDB, 0x86, 0x73, 0xE6, 0x48, 0xD8, 0xB5, 0x8D,
0x92, 0x99, 0x55, 0xB1, 0x4A, 0x26, 0xC3, 0x08,
@@ -84,5 +85,4 @@
struct q_useful_buf_c payload);
uint32_t pal_crypto_pub_key_verify(int32_t cose_algorithm_id, struct q_useful_buf_c token_hash,
struct q_useful_buf_c signature);
-
-
+#endif /* _PAL_ATTESTATION_CRYPTO_H_ */
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.c b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.c
deleted file mode 100644
index 68c4312..0000000
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/** @file
- * Copyright (c) 2019, Arm Limited or its affiliates. All rights reserved.
- * SPDX-License-Identifier : Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-**/
-
-#include "pal_attestation_crypto.h"
-
-uint32_t mandatory_claims = 0;
-uint32_t mandaroty_sw_components = 0;
-bool_t sw_component_present = 0;
-
-int pal_encode_cose_key(struct q_useful_buf_c *cose_key,
- struct q_useful_buf buffer_for_cose_key,
- struct q_useful_buf_c x_cord, struct q_useful_buf_c y_cord)
-{
- uint32_t return_value;
- QCBORError qcbor_result;
- QCBOREncodeContext cbor_encode_ctx;
- int32_t cose_curve_id = P_256;
- struct q_useful_buf_c encoded_key_id;
-
- /* Get the public key x and y */
- /* Encode it into a COSE_Key structure */
- QCBOREncode_Init(&cbor_encode_ctx, buffer_for_cose_key);
- QCBOREncode_OpenMap(&cbor_encode_ctx);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_COMMON_KTY,
- COSE_KEY_TYPE_EC2);
- QCBOREncode_AddInt64ToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_CRV,
- cose_curve_id);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_X_COORDINATE,
- x_cord);
- QCBOREncode_AddBytesToMapN(&cbor_encode_ctx,
- COSE_KEY_PARAM_Y_COORDINATE,
- y_cord);
- QCBOREncode_CloseMap(&cbor_encode_ctx);
-
- qcbor_result = QCBOREncode_Finish(&cbor_encode_ctx, &encoded_key_id);
- if (qcbor_result != QCBOR_SUCCESS)
- {
- /* Mainly means that the COSE_Key was too big for buffer_for_cose_key */
- return_value = PAL_ATTEST_ERR_PROTECTED_HEADERS;
- goto Done;
- }
-
- /* Finish up and return */
- *cose_key = encoded_key_id;
- return_value = PAL_ATTEST_SUCCESS;
-
-Done:
- return return_value;
-}
-
-
-static int get_items_in_map(QCBORDecodeContext *decode_context,
- struct items_to_get_t *item_list)
-{
- int item_index;
- QCBORItem item;
- struct items_to_get_t *item_ptr = item_list;
-
- /* initialize the data type of all items in the list */
- while (item_ptr->label != 0)
- {
- item_ptr->item.uDataType = QCBOR_TYPE_NONE;
- item_ptr++;
- }
-
- QCBORDecode_GetNext(decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_MAP)
- {
- return PAL_ATTEST_ERROR;
- }
-
- for (item_index = item.val.uCount; item_index != 0; item_index--)
- {
- if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- if (item.uLabelType != QCBOR_TYPE_INT64)
- {
- continue;
- }
-
- item_ptr = item_list;
- while (item_ptr->label != 0)
- {
- if (item.label.int64 == item_ptr->label)
- {
- item_ptr->item = item;
- }
- item_ptr++;
- }
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int get_item_in_map(QCBORDecodeContext *decode_context,
- int32_t label,
- QCBORItem *item)
-{
- struct items_to_get_t item_list[2];
-
- item_list[0].label = label;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
- {
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- *item = item_list[0].item;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
- struct q_useful_buf_c *child)
-{
- struct items_to_get_t item_list[3];
-
- item_list[0].label = COSE_HEADER_PARAM_KID;
- item_list[1].label = 0;
-
- if (get_items_in_map(decode_context, item_list))
- {
- return PAL_ATTEST_ERR_CBOR_STRUCTURE;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
-
-static int parse_protected_headers(struct q_useful_buf_c protected_headers,
- int32_t *alg_id)
-{
- QCBORDecodeContext decode_context;
- QCBORItem item;
-
- QCBORDecode_Init(&decode_context, protected_headers, 0);
-
- if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if (QCBORDecode_Finish(&decode_context))
- {
- return PAL_ATTEST_ERROR;
- }
-
- if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
- {
- return PAL_ATTEST_ERROR;
- }
-
- *alg_id = (int32_t)item.val.int64;
-
- return PAL_ATTEST_SUCCESS;
-}
-
-/**
- @brief - This API will verify the claims
- @param - decode_context : The buffer containing the challenge
- item : context for decoding the data items
- completed_challenge : Buffer containing the challenge
- @return - error status
-**/
-static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
- struct q_useful_buf_c completed_challenge)
-{
- int i, count = 0;
- int status = PAL_ATTEST_SUCCESS;
-
- /* Parse each claim and validate their data type */
- while (status == PAL_ATTEST_SUCCESS)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- break;
-
- mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
- if (item.uLabelType == QCBOR_TYPE_INT64)
- {
- if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
- {
- if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
- {
- /* Given challenge vs challenge in token */
- if (UsefulBuf_Compare(item.val.string, completed_challenge))
- return PAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
- }
- else
- return PAL_ATTEST_TOKEN_NOT_SUPPORTED;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
- item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
- {
- if (item.uDataType != QCBOR_TYPE_ARRAY)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- sw_component_present = 1;
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- continue;
-
- count = item.val.uCount;
- for (i = 0; i <= count; i++)
- {
- mandaroty_sw_components |= 1 << item.label.int64;
-
- if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
- {
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
- {
- if (item.uDataType != QCBOR_TYPE_INT64)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
- {
- if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
-
- if (i < count)
- {
- status = QCBORDecode_GetNext(decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
- }
- }
-
- }
- }
- else
- {
- /* ToDo: Add other claim types */
- }
- }
-
- if (status == QCBOR_ERR_HIT_END)
- return PAL_ATTEST_SUCCESS;
- else
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-}
-
-/**
- @brief - This API will verify the attestation token
- @param - challenge : The buffer containing the challenge
- challenge_size : Size of the challenge buffer
- token : The buffer containing the attestation token
- token_size : Size of the token buffer
- @return - error status
-**/
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size)
-{
- int32_t status = PAL_ATTEST_SUCCESS;
- int32_t cose_algorithm_id;
- QCBORItem item;
- QCBORDecodeContext decode_context;
- struct q_useful_buf_c completed_challenge;
- struct q_useful_buf_c completed_token;
- struct q_useful_buf_c payload;
- struct q_useful_buf_c signature;
- struct q_useful_buf_c protected_headers;
- struct q_useful_buf_c kid;
- struct q_useful_buf_c token_hash;
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_x_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buf_to_hold_y_coord, T_COSE_CRYPTO_EC_P256_COORD_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
- USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
-
- kid.ptr = buffer_for_encoded_key.ptr;
-
- memcpy(buf_to_hold_x_coord.ptr, (const void *)attest_key.pubx_key, attest_key.pubx_key_size);
- memcpy(buf_to_hold_y_coord.ptr, (const void *)attest_key.puby_key, attest_key.puby_key_size);
-
- /* Update size */
- buf_to_hold_x_coord.len = attest_key.pubx_key_size;
- buf_to_hold_y_coord.len = attest_key.puby_key_size;
-
- /* Construct the token buffer for validation */
- completed_token.ptr = token;
- completed_token.len = token_size;
-
- /* Construct the challenge buffer for validation */
- completed_challenge.ptr = challenge;
- completed_challenge.len = challenge_size;
-
-/*
- -------------------------
- | CBOR Array Type |
- -------------------------
- | Protected Headers |
- -------------------------
- | Unprotected Headers |
- -------------------------
- | Payload |
- -------------------------
- | Signature |
- -------------------------
-*/
-
- /* Initialize the decorder */
- QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
-
- /* Get the Header */
- QCBORDecode_GetNext(&decode_context, &item);
-
- /* Check the CBOR Array type. Check if the count is 4.
- * Only COSE_SIGN1 is supported now.
- */
- if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
- !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Get the next headers */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- protected_headers = item.val.string;
-
- /* Parse the protected headers and check the data type and value*/
- status = parse_protected_headers(protected_headers, &cose_algorithm_id);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Parse the unprotected headers and check the data type and value */
- status = parse_unprotected_headers(&decode_context, &kid);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Get the payload */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- payload = item.val.string;
-
- /* Get the digital signature */
- QCBORDecode_GetNext(&decode_context, &item);
- if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- signature = item.val.string;
-
- /* Compute the hash from the token */
- status = pal_compute_hash(cose_algorithm_id, buffer_for_token_hash, &token_hash,
- protected_headers, payload);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Verify the signature */
- status = pal_crypto_pub_key_verify(cose_algorithm_id, token_hash, signature);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- /* Initialize the Decoder and validate the payload format */
- QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
- status = QCBORDecode_GetNext(&decode_context, &item);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if (item.uDataType != QCBOR_TYPE_MAP)
- return PAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
-
- /* Parse the payload and check the data type of each claim */
- status = parse_claims(&decode_context, item, completed_challenge);
- if (status != PAL_ATTEST_SUCCESS)
- return status;
-
- if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
- {
- if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
- else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
- {
- return PAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
- }
-
- return PAL_ATTEST_SUCCESS;
-}
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h
index df24c89..56d624e 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_eat.h
@@ -15,43 +15,17 @@
* limitations under the License.
**/
+#ifndef _PAL_ATTESTATION_EAT_H_
+#define _PAL_ATTESTATION_EAT_H_
+
#include "qcbor.h"
#include "pal_common.h"
-#include "psa/crypto.h"
#define PAL_ATTEST_MIN_ERROR 30
-/* NIST P-256 also known as secp256r1 */
-#define P_256 1
-
-#define COSE_HEADER_PARAM_ALG 1
-#define COSE_HEADER_PARAM_KID 4
-
-#define COSE_KEY_COMMON_KTY 1
-#define COSE_KEY_TYPE_EC2 2
-#define COSE_KEY_PARAM_CRV -1
-#define COSE_KEY_PARAM_X_COORDINATE -2
-#define COSE_KEY_PARAM_Y_COORDINATE -3
#define COSE_ALGORITHM_ES256 -7
#define COSE_ALG_SHA256_PROPRIETARY -72000
-/**
- * The size of X and Y coordinate in 2 parameter style EC public
- * key. Format is as defined in [COSE (RFC 8152)]
- * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
- * Cryptography](http://www.secg.org/sec1-v2.pdf).
- *
- * This size is well-known and documented in public standards.
- */
-#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
-#define T_COSE_CRYPTO_SHA256_SIZE 32
-
-#define MAX_ENCODED_COSE_KEY_SIZE \
- 1 + /* 1 byte to encode map */ \
- 2 + /* 2 bytes to encode key type */ \
- 2 + /* 2 bytes to encode curve */ \
- 2 * /* the X and Y coordinates at 32 bytes each */ \
- (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2)
#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
#define COSE_SIG_CONTEXT_STRING_SIGNATURE1 "Signature1"
@@ -81,68 +55,6 @@
3 * ( /* 3 NULL bstrs for fields not used */ \
1 /* size of a NULL bstr */ \
)
-
-/*
- CBOR Label for proprietary header indicating short-circuit
- signing was used. Just a random number in the proprietary
- label space */
-#define T_COSE_SHORT_CIRCUIT_LABEL (-8675309)
-
-#define EAT_CBOR_ARM_RANGE_BASE (-75000)
-#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
-#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
-#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
-#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
-#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
-#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
-#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
-#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
-#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
-#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
-#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
-
-#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
-
-#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
-#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
-#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
-#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
-#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
-
-#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
-
-#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NONCE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_UEID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
- 1 << (EAT_CBOR_ARM_RANGE_BASE \
- - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
-
-#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
- 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
-
#define NULL_USEFUL_BUF_C NULLUsefulBufC
enum attestation_error_code {
@@ -161,13 +73,8 @@
PAL_ATTEST_ERR_KEY_FAIL,
PAL_ATTEST_ERR_SIGNATURE_FAIL,
PAL_ATTEST_ERR_CBOR_STRUCTURE,
+ PAL_ATTEST_ERR_SMALL_BUFFER,
PAL_ATTEST_ERROR,
};
-struct items_to_get_t {
- int64_t label;
- QCBORItem item;
-};
-
-int32_t pal_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
- uint8_t *token, size_t token_size);
+#endif /* _PAL_ATTESTATION_EAT_H_ */
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h
index 12f6ee9..3ab7ebb 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/nspe/initial_attestation/pal_attestation_intf.h
@@ -15,8 +15,8 @@
* limitations under the License.
**/
-#ifndef _PAL_INITIAL_ATTESTATION_H_
-#define _PAL_INITIAL_ATTESTATION_H_
+#ifndef _PAL_ATTESTATION_INTF_H_
+#define _PAL_ATTESTATION_INTF_H_
#include "pal_attestation_crypto.h"
@@ -24,7 +24,9 @@
PAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
PAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
PAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ PAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ PAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
int32_t pal_attestation_function(int type, va_list valist);
-#endif /* _PAL_INITIAL_ATTESTATION_H_ */
+#endif /* _PAL_ATTESTATION_INTF_H_ */
diff --git a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/target.cmake b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/target.cmake
index 5c5c942..db9a4fa 100644
--- a/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/target.cmake
+++ b/api-tests/platform/targets/tgt_ff_mbedos_fvp_mps2_m4/target.cmake
@@ -71,7 +71,6 @@
if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
list(APPEND PAL_SRC_C_NSPE
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_intf.c
- ${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_eat.c
${PSA_ROOT_DIR}/platform/targets/${TARGET}/nspe/initial_attestation/pal_attestation_crypto.c
)
endif()
diff --git a/api-tests/val/nspe/val_attestation.c b/api-tests/val/nspe/val_attestation.c
index 82d7191..50e400a 100644
--- a/api-tests/val/nspe/val_attestation.c
+++ b/api-tests/val/nspe/val_attestation.c
@@ -21,24 +21,415 @@
#include "val_client_defs.h"
#include "val_attestation.h"
+#ifdef INITIAL_ATTESTATION
+
+uint32_t mandatory_claims = 0;
+uint32_t mandaroty_sw_components = 0;
+bool_t sw_component_present = 0;
+
+static int get_items_in_map(QCBORDecodeContext *decode_context,
+ struct items_to_get_t *item_list)
+{
+ int item_index;
+ QCBORItem item;
+ struct items_to_get_t *item_ptr = item_list;
+
+ /* initialize the data type of all items in the list */
+ while (item_ptr->label != 0)
+ {
+ item_ptr->item.uDataType = QCBOR_TYPE_NONE;
+ item_ptr++;
+ }
+
+ QCBORDecode_GetNext(decode_context, &item);
+ if (item.uDataType != QCBOR_TYPE_MAP)
+ {
+ return VAL_ATTEST_ERROR;
+ }
+
+ for (item_index = item.val.uCount; item_index != 0; item_index--)
+ {
+ if (QCBORDecode_GetNext(decode_context, &item) != QCBOR_SUCCESS)
+ {
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ if (item.uLabelType != QCBOR_TYPE_INT64)
+ {
+ continue;
+ }
+
+ item_ptr = item_list;
+ while (item_ptr->label != 0)
+ {
+ if (item.label.int64 == item_ptr->label)
+ {
+ item_ptr->item = item;
+ }
+ item_ptr++;
+ }
+ }
+
+ return VAL_ATTEST_SUCCESS;
+}
+
+static int get_item_in_map(QCBORDecodeContext *decode_context,
+ int32_t label,
+ QCBORItem *item)
+{
+ struct items_to_get_t item_list[2];
+
+ item_list[0].label = label;
+ item_list[1].label = 0;
+
+ if (get_items_in_map(decode_context, item_list))
+ {
+ return VAL_ATTEST_ERROR;
+ }
+
+ if (item_list[0].item.uDataType == QCBOR_TYPE_NONE)
+ {
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+
+ *item = item_list[0].item;
+
+ return VAL_ATTEST_SUCCESS;
+}
+
+static int parse_unprotected_headers(QCBORDecodeContext *decode_context,
+ struct q_useful_buf_c *child)
+{
+ struct items_to_get_t item_list[3];
+
+ item_list[0].label = COSE_HEADER_PARAM_KID;
+ item_list[1].label = 0;
+
+ if (get_items_in_map(decode_context, item_list))
+ {
+ return VAL_ATTEST_ERR_CBOR_STRUCTURE;
+ }
+
+ return VAL_ATTEST_SUCCESS;
+}
+
+static int parse_protected_headers(struct q_useful_buf_c protected_headers,
+ int32_t *alg_id)
+{
+ QCBORDecodeContext decode_context;
+ QCBORItem item;
+
+ QCBORDecode_Init(&decode_context, protected_headers, 0);
+
+ if (get_item_in_map(&decode_context, COSE_HEADER_PARAM_ALG, &item))
+ {
+ return VAL_ATTEST_ERROR;
+ }
+
+ if (QCBORDecode_Finish(&decode_context))
+ {
+ return VAL_ATTEST_ERROR;
+ }
+
+ if ((item.uDataType != QCBOR_TYPE_INT64) || (item.val.int64 > INT32_MAX))
+ {
+ return VAL_ATTEST_ERROR;
+ }
+
+ *alg_id = (int32_t)item.val.int64;
+
+ return VAL_ATTEST_SUCCESS;
+}
+
+/**
+ @brief - This API will verify the claims
+ @param - decode_context : The buffer containing the challenge
+ item : context for decoding the data items
+ completed_challenge : Buffer containing the challenge
+ @return - error status
+**/
+static int parse_claims(QCBORDecodeContext *decode_context, QCBORItem item,
+ struct q_useful_buf_c completed_challenge)
+{
+ int i, count = 0;
+ int status = VAL_ATTEST_SUCCESS;
+
+ /* Parse each claim and validate their data type */
+ while (status == VAL_ATTEST_SUCCESS)
+ {
+ status = QCBORDecode_GetNext(decode_context, &item);
+ if (status != VAL_ATTEST_SUCCESS)
+ break;
+
+ mandatory_claims |= 1 << (EAT_CBOR_ARM_RANGE_BASE - item.label.int64);
+ if (item.uLabelType == QCBOR_TYPE_INT64)
+ {
+ if (item.label.int64 == EAT_CBOR_ARM_LABEL_NONCE)
+ {
+ if (item.uDataType == QCBOR_TYPE_BYTE_STRING)
+ {
+ /* Given challenge vs challenge in token */
+ if (UsefulBuf_Compare(item.val.string, completed_challenge))
+ return VAL_ATTEST_TOKEN_CHALLENGE_MISMATCH;
+ }
+ else
+ return VAL_ATTEST_TOKEN_NOT_SUPPORTED;
+ }
+ else if (item.label.int64 == EAT_CBOR_ARM_LABEL_BOOT_SEED ||
+ item.label.int64 == EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID ||
+ item.label.int64 == EAT_CBOR_ARM_LABEL_UEID)
+ {
+ if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_ARM_LABEL_ORIGINATION ||
+ item.label.int64 == EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION ||
+ item.label.int64 == EAT_CBOR_ARM_LABEL_HW_VERSION)
+ {
+ if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_ARM_LABEL_CLIENT_ID ||
+ item.label.int64 == EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE)
+ {
+ if (item.uDataType != QCBOR_TYPE_INT64)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_ARM_LABEL_SW_COMPONENTS)
+ {
+ if (item.uDataType != QCBOR_TYPE_ARRAY)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+
+ sw_component_present = 1;
+ status = QCBORDecode_GetNext(decode_context, &item);
+ if (status != VAL_ATTEST_SUCCESS)
+ continue;
+
+ count = item.val.uCount;
+ for (i = 0; i <= count; i++)
+ {
+ mandaroty_sw_components |= 1 << item.label.int64;
+
+ if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT)
+ {
+ if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC)
+ {
+ if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_VERSION)
+ {
+ if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_SIGNER_ID)
+ {
+ if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_EPOCH)
+ {
+ if (item.uDataType != QCBOR_TYPE_INT64)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ else if (item.label.int64 == EAT_CBOR_SW_COMPONENT_TYPE)
+ {
+ if (item.uDataType != QCBOR_TYPE_TEXT_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+
+ if (i < count)
+ {
+ status = QCBORDecode_GetNext(decode_context, &item);
+ if (status != VAL_ATTEST_SUCCESS)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+ }
+ }
+
+ }
+ }
+ else
+ {
+ /* For other claim types */
+ }
+ }
+
+ if (status == QCBOR_ERR_HIT_END)
+ return VAL_ATTEST_SUCCESS;
+ else
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+}
+
+/**
+ @brief - This API will verify the attestation token
+ @param - challenge : The buffer containing the challenge
+ challenge_size : Size of the challenge buffer
+ token : The buffer containing the attestation token
+ token_size : Size of the token buffer
+ @return - error status
+**/
+int32_t val_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
+ uint8_t *token, size_t token_size)
+{
+ int32_t status = VAL_ATTEST_SUCCESS;
+ int32_t cose_algorithm_id;
+ QCBORItem item;
+ QCBORDecodeContext decode_context;
+ struct q_useful_buf_c completed_challenge;
+ struct q_useful_buf_c completed_token;
+ struct q_useful_buf_c payload;
+ struct q_useful_buf_c signature;
+ struct q_useful_buf_c protected_headers;
+ struct q_useful_buf_c kid;
+ struct q_useful_buf_c token_hash;
+
+ USEFUL_BUF_MAKE_STACK_UB(buffer_for_encoded_key, MAX_ENCODED_COSE_KEY_SIZE);
+ USEFUL_BUF_MAKE_STACK_UB(buffer_for_token_hash, T_COSE_CRYPTO_SHA256_SIZE);
+
+ kid.ptr = buffer_for_encoded_key.ptr;
+
+ /* Construct the token buffer for validation */
+ completed_token.ptr = token;
+ completed_token.len = token_size;
+
+ /* Construct the challenge buffer for validation */
+ completed_challenge.ptr = challenge;
+ completed_challenge.len = challenge_size;
+
+/*
+ -------------------------
+ | CBOR Array Type |
+ -------------------------
+ | Protected Headers |
+ -------------------------
+ | Unprotected Headers |
+ -------------------------
+ | Payload |
+ -------------------------
+ | Signature |
+ -------------------------
+*/
+
+ /* Initialize the decorder */
+ QCBORDecode_Init(&decode_context, completed_token, QCBOR_DECODE_MODE_NORMAL);
+
+ /* Get the Header */
+ QCBORDecode_GetNext(&decode_context, &item);
+
+ /* Check the CBOR Array type. Check if the count is 4.
+ * Only COSE_SIGN1 is supported now.
+ */
+ if (item.uDataType != QCBOR_TYPE_ARRAY || item.val.uCount != 4 ||
+ !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_SIGN1))
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+
+ /* Get the next headers */
+ QCBORDecode_GetNext(&decode_context, &item);
+ if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+
+ protected_headers = item.val.string;
+
+ /* Parse the protected headers and check the data type and value*/
+ status = parse_protected_headers(protected_headers, &cose_algorithm_id);
+ if (status != VAL_ATTEST_SUCCESS)
+ return status;
+
+ /* Parse the unprotected headers and check the data type and value */
+ status = parse_unprotected_headers(&decode_context, &kid);
+ if (status != VAL_ATTEST_SUCCESS)
+ return status;
+
+ /* Get the payload */
+ QCBORDecode_GetNext(&decode_context, &item);
+ if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+
+ payload = item.val.string;
+
+ /* Get the digital signature */
+ QCBORDecode_GetNext(&decode_context, &item);
+ if (item.uDataType != QCBOR_TYPE_BYTE_STRING)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+
+ signature = item.val.string;
+
+ /* Compute the hash from the token */
+ status = val_attestation_function(VAL_INITIAL_ATTEST_COMPUTE_HASH, cose_algorithm_id,
+ buffer_for_token_hash, &token_hash,
+ protected_headers, payload);
+ if (status != VAL_ATTEST_SUCCESS)
+ return status;
+
+ /* Verify the signature */
+ status = val_attestation_function(VAL_INITIAL_ATTEST_VERIFY_WITH_PK, cose_algorithm_id,
+ token_hash, signature);
+ if (status != VAL_ATTEST_SUCCESS)
+ return status;
+
+ /* Initialize the Decoder and validate the payload format */
+ QCBORDecode_Init(&decode_context, payload, QCBOR_DECODE_MODE_NORMAL);
+ status = QCBORDecode_GetNext(&decode_context, &item);
+ if (status != VAL_ATTEST_SUCCESS)
+ return status;
+
+ if (item.uDataType != QCBOR_TYPE_MAP)
+ return VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING;
+
+ /* Parse the payload and check the data type of each claim */
+ status = parse_claims(&decode_context, item, completed_challenge);
+ if (status != VAL_ATTEST_SUCCESS)
+ return status;
+
+ if ((mandatory_claims & MANDATORY_CLAIM_WITH_SW_COMP) == MANDATORY_CLAIM_WITH_SW_COMP)
+ {
+ if ((mandaroty_sw_components & MANDATORY_SW_COMP) != MANDATORY_SW_COMP)
+ return VAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
+ }
+ else if ((mandatory_claims & MANDATORY_CLAIM_NO_SW_COMP) != MANDATORY_CLAIM_NO_SW_COMP)
+ {
+ return VAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS;
+ }
+
+ return VAL_ATTEST_SUCCESS;
+}
+#endif /* INITIAL_ATTESTATION */
+
/**
@brief - This API will call the requested attestation function
@param - type : function code
... : variable number of arguments
@return - Error status
**/
-
int32_t val_attestation_function(int type, ...)
{
#ifdef INITIAL_ATTESTATION
va_list valist;
val_status_t status;
+ uint8_t *challenge, *token;
+ size_t challenge_size, verify_token_size;
va_start(valist, type);
- status = pal_attestation_function(type, valist);
+ switch (type)
+ {
+ case VAL_INITIAL_ATTEST_VERIFY_TOKEN:
+ challenge = va_arg(valist, uint8_t*);
+ challenge_size = va_arg(valist, size_t);
+ token = va_arg(valist, uint8_t*);
+ verify_token_size = va_arg(valist, size_t);
+ status = val_initial_attest_verify_token(challenge, challenge_size,
+ token, verify_token_size);
+ break;
+ default:
+ status = pal_attestation_function(type, valist);
+ break;
+ }
+
va_end(valist);
return status;
#else
return VAL_STATUS_ERROR;
-#endif
+#endif /* INITIAL_ATTESTATION */
}
diff --git a/api-tests/val/nspe/val_attestation.h b/api-tests/val/nspe/val_attestation.h
index 58ea59c..f810fcc 100644
--- a/api-tests/val/nspe/val_attestation.h
+++ b/api-tests/val/nspe/val_attestation.h
@@ -18,14 +18,130 @@
#ifndef _VAL_INITIAL_ATTESTATION_H_
#define _VAL_INITIAL_ATTESTATION_H_
+#ifdef INITIAL_ATTESTATION
+
#include "val.h"
+#include "qcbor.h"
+
+#define COSE_HEADER_PARAM_ALG 1
+#define COSE_HEADER_PARAM_KID 4
+
+/**
+ * The size of X and Y coordinate in 2 parameter style EC public
+ * key. Format is as defined in [COSE (RFC 8152)]
+ * (https://tools.ietf.org/html/rfc8152) and [SEC 1: Elliptic Curve
+ * Cryptography](http://www.secg.org/sec1-v2.pdf).
+ *
+ * This size is well-known and documented in public standards.
+ */
+#define T_COSE_CRYPTO_EC_P256_COORD_SIZE 32
+#define T_COSE_CRYPTO_SHA256_SIZE 32
+
+#define MAX_ENCODED_COSE_KEY_SIZE \
+ (1 + /* 1 byte to encode map */ \
+ 2 + /* 2 bytes to encode key type */ \
+ 2 + /* 2 bytes to encode curve */ \
+ 2 * /* the X and Y coordinates at 32 bytes each */ \
+ (T_COSE_CRYPTO_EC_P256_COORD_SIZE + 1 + 2))
+
+#define USEFUL_BUF_MAKE_STACK_UB UsefulBuf_MAKE_STACK_UB
+
#define MAX_CHALLENGE_SIZE PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64
+#define EAT_CBOR_ARM_RANGE_BASE (-75000)
+#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION (EAT_CBOR_ARM_RANGE_BASE - 0)
+#define EAT_CBOR_ARM_LABEL_CLIENT_ID (EAT_CBOR_ARM_RANGE_BASE - 1)
+#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE (EAT_CBOR_ARM_RANGE_BASE - 2)
+#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID (EAT_CBOR_ARM_RANGE_BASE - 3)
+#define EAT_CBOR_ARM_LABEL_BOOT_SEED (EAT_CBOR_ARM_RANGE_BASE - 4)
+#define EAT_CBOR_ARM_LABEL_HW_VERSION (EAT_CBOR_ARM_RANGE_BASE - 5)
+#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 6)
+#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS (EAT_CBOR_ARM_RANGE_BASE - 7)
+#define EAT_CBOR_ARM_LABEL_NONCE (EAT_CBOR_ARM_RANGE_BASE - 8)
+#define EAT_CBOR_ARM_LABEL_UEID (EAT_CBOR_ARM_RANGE_BASE - 9)
+#define EAT_CBOR_ARM_LABEL_ORIGINATION (EAT_CBOR_ARM_RANGE_BASE - 10)
+
+#define CBOR_ARM_TOTAL_CLAIM_INSTANCE 10
+
+#define EAT_CBOR_SW_COMPONENT_TYPE (1u)
+#define EAT_CBOR_SW_COMPONENT_MEASUREMENT (2u)
+#define EAT_CBOR_SW_COMPONENT_EPOCH (3u)
+#define EAT_CBOR_SW_COMPONENT_VERSION (4u)
+#define EAT_CBOR_SW_COMPONENT_SIGNER_ID (5u)
+#define EAT_CBOR_SW_COMPONENT_MEASUREMENT_DESC (6u)
+
+#define MANDATORY_CLAIM_WITH_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_NONCE) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_UEID) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_SW_COMPONENTS))
+
+#define MANDATORY_CLAIM_NO_SW_COMP (1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_NONCE) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_UEID) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_CLIENT_ID) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_BOOT_SEED) | \
+ 1 << (EAT_CBOR_ARM_RANGE_BASE \
+ - EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS))
+
+#define MANDATORY_SW_COMP (1 << EAT_CBOR_SW_COMPONENT_MEASUREMENT | \
+ 1 << EAT_CBOR_SW_COMPONENT_VERSION | \
+ 1 << EAT_CBOR_SW_COMPONENT_SIGNER_ID)
+
+#define VAL_ATTEST_MIN_ERROR 70
+
+enum attestation_error_code {
+ VAL_ATTEST_SUCCESS = 0,
+ VAL_ATTEST_TOKEN_ERR_CBOR_FORMATTING = VAL_ATTEST_MIN_ERROR,
+ VAL_ATTEST_TOKEN_CHALLENGE_MISMATCH,
+ VAL_ATTEST_TOKEN_NOT_SUPPORTED,
+ VAL_ATTEST_TOKEN_NOT_ALL_MANDATORY_CLAIMS,
+ VAL_ATTEST_HASH_LENGTH_MISMATCH,
+ VAL_ATTEST_HASH_MISMATCH,
+ VAL_ATTEST_HASH_FAIL,
+ VAL_ATTEST_HASH_UNSUPPORTED,
+ VAL_ATTEST_HASH_BUFFER_SIZE,
+ VAL_ATTEST_ERR_PROTECTED_HEADERS,
+ VAL_ATTEST_ERR_SIGN_STRUCT,
+ VAL_ATTEST_ERR_KEY_FAIL,
+ VAL_ATTEST_ERR_SIGNATURE_FAIL,
+ VAL_ATTEST_ERR_CBOR_STRUCTURE,
+ VAL_ATTEST_ERR_SMALL_BUFFER,
+ VAL_ATTEST_ERROR,
+};
+
+struct items_to_get_t {
+ int64_t label;
+ QCBORItem item;
+};
+
enum attestation_function_code {
VAL_INITIAL_ATTEST_GET_TOKEN = 0x1,
VAL_INITIAL_ATTEST_GET_TOKEN_SIZE = 0x2,
VAL_INITIAL_ATTEST_VERIFY_TOKEN = 0x3,
+ VAL_INITIAL_ATTEST_COMPUTE_HASH = 0x4,
+ VAL_INITIAL_ATTEST_VERIFY_WITH_PK = 0x5,
};
+int32_t val_initial_attest_verify_token(uint8_t *challenge, size_t challenge_size,
+ uint8_t *token, size_t token_size);
+#endif /* INITIAL_ATTESTATION */
+
int32_t val_attestation_function(int type, ...);
#endif /* _VAL_INITIAL_ATTESTATION_H_ */
diff --git a/api-tests/val/val_nspe.cmake b/api-tests/val/val_nspe.cmake
index 91113b0..4494ed2 100644
--- a/api-tests/val/val_nspe.cmake
+++ b/api-tests/val/val_nspe.cmake
@@ -38,6 +38,12 @@
target_include_directories(${PSA_TARGET_VAL_NSPE_LIB} PRIVATE ${psa_inc_path})
endforeach()
+if(${SUITE} STREQUAL "INITIAL_ATTESTATION")
+target_include_directories(${PSA_TARGET_VAL_NSPE_LIB} PRIVATE
+ ${PSA_QCBOR_INCLUDE_PATH}
+)
+endif()
+
target_include_directories(${PSA_TARGET_VAL_NSPE_LIB} PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${PSA_ROOT_DIR}/val/common