diff options
author | David Hu <david.hu@arm.com> | 2020-03-26 10:33:57 +0800 |
---|---|---|
committer | David Hu <david.hu@arm.com> | 2020-06-22 02:33:00 +0000 |
commit | 2d70488743ca4f2f55d57a2cd91397054253119a (patch) | |
tree | 4fd2317b2265da4a26f25ad353be252bac29ff81 /test | |
parent | 47420d923202a6a91109a472f94d08fe58f17388 (diff) | |
download | trusted-firmware-m-2d70488743ca4f2f55d57a2cd91397054253119a.tar.gz |
Test: Enhance the test suites of symmetric Initial Attestation
Add test cases to perform minimal tests in test suites of symmetric
key algorithms based Initial Attestation both in NS and S side.
Add the expected token array of minimal tests for symmetric based
Initial Attestation.
Also add negative test cases.
Improve the buffer_too_small_test() a little and include it in the
negative test cases instead of a full-size token generation test,
to minimize the memory footprint of tests.
Change-Id: I0c4f8958081498f1fbab91220981877fc2f5abbc
Signed-off-by: David Hu <david.hu@arm.com>
Diffstat (limited to 'test')
4 files changed, 312 insertions, 7 deletions
diff --git a/test/suites/attestation/attest_token_test.c b/test/suites/attestation/attest_token_test.c index 0d3aeace32..52fc9aa08c 100644 --- a/test/suites/attestation/attest_token_test.c +++ b/test/suites/attestation/attest_token_test.c @@ -88,8 +88,52 @@ int token_main_alt(uint32_t option_flags, return 0; } -#ifndef SYMMETRIC_INITIAL_ATTESTATION #ifdef INCLUDE_TEST_CODE /* Remove them from release build */ +#ifdef SYMMETRIC_INITIAL_ATTESTATION +/** + * This is the expected output for the minimal test. It is the result + * of creating a token with \ref TOKEN_OPT_SHORT_CIRCUIT_SIGN and \ref + * TOKEN_OPT_OMIT_CLAIMS set. The nonce is the above constant string + * \ref nonce_bytes. The token output is completely deterministic. + * + * 17( + * [ + * / protected / h'A10105' / { + * \ alg \ 1:5 \ HMAC-SHA256 \ + * } /, + * / unprotected / {}, + * / payload / h'A13A000124FF5840000000C0000000000000000000000 + * 00000000000000000000000000000000000000000000000000000000000 + * 0000000000000000000000000000000000000000' / { + * / arm_psa_nonce / -75008: h'000000C00000000000000000000 + * 0000000000000000000000000000000000000000000000000000000 + * 0000000000000000000000000000000000000000000000, + * } /, + * / tag / h'966840FC0A60AE968F906D7092E57B205D3BBE83ED47EBBC2 + * AD9D1CFB41C87F3' + * ] + * ) + * + * The above is in CBOR Diagnostic notation. See RFC 8152. + */ +static const uint8_t expected_minimal_token_bytes[] = { + 0xD1, 0x84, 0x43, 0xA1, 0x01, 0x05, 0xA0, 0x58, + 0x48, 0xA1, 0x3A, 0x00, 0x01, 0x24, 0xFF, 0x58, + 0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x20, 0x96, 0x68, 0x40, 0xFC, 0x0A, + 0x60, 0xAE, 0x96, 0x8F, 0x90, 0x6D, 0x70, 0x92, + 0xE5, 0x7B, 0x20, 0x5D, 0x3B, 0xBE, 0x83, 0xED, + 0x47, 0xEB, 0xBC, 0x2A, 0xD9, 0xD1, 0xCF, 0xB4, + 0x1C, 0x87, 0xF3 +}; +#else /* SYMMETRIC_INITIAL_ATTESTATION */ /** * This is the expected output for the minimal test. It is the result * of creating a token with \ref TOKEN_OPT_SHORT_CIRCUIT_SIGN and \ref @@ -143,6 +187,7 @@ static const uint8_t expected_minimal_token_bytes[] = { 0xA6, 0xFC, 0x7F, 0x51, 0x90, 0x35, 0x2D, 0x3A, 0x16, 0xBC, 0x30, 0x7B, 0x50, 0x3D }; +#endif /* SYMMETRIC_INITIAL_ATTESTATION */ /* @@ -218,19 +263,29 @@ int_fast16_t minimal_get_size_test() int_fast16_t buffer_too_small_test() { int_fast16_t return_value = 0; - Q_USEFUL_BUF_MAKE_STACK_UB(token_storage, 100); /* too small on purpose */ + /* + * Construct a buffer with enough capacity in case buffer size check fails + * and the token is generated. If a smaller buffer is allocated, the + * incorrectly generated token may overwrite and corrupt the data following + * this buffer. + */ + Q_USEFUL_BUF_MAKE_STACK_UB(token_storage, + sizeof(expected_minimal_token_bytes)); struct q_useful_buf_c completed_token; struct q_useful_buf_c nonce; nonce = TOKEN_TEST_VALUE_NONCE; + /* Fake the size and cheat the token generation process. */ + token_storage.len = sizeof(expected_minimal_token_bytes) - 1; - return_value = token_main_alt(TOKEN_OPT_SHORT_CIRCUIT_SIGN, + return_value = token_main_alt(TOKEN_OPT_SHORT_CIRCUIT_SIGN | + TOKEN_OPT_OMIT_CLAIMS, nonce, token_storage, &completed_token); - if(return_value != ATTEST_TOKEN_ERR_TOO_SMALL) { + if(return_value != PSA_ERROR_BUFFER_TOO_SMALL) { return_value = -1; } else { return_value = 0; @@ -239,7 +294,6 @@ int_fast16_t buffer_too_small_test() return return_value; } #endif /* INCLUDE_TEST_CODE */ -#endif /* !SYMMETRIC_INITIAL_ATTESTATION */ /** @@ -788,7 +842,9 @@ enum decode_test_mode_t { /** See documentation for decode_test_normal_sig() */ NORMAL_SIGN, /** See documentation for decode_test_symmetric_initial_attest() */ - COSE_MAC0 + COSE_MAC0, + /** See documentation for decode_test_symmetric_iat_short_circuit_tag() */ + COSE_MAC0_SHORT_CIRCUIT_TAG }; /** @@ -830,6 +886,11 @@ static int_fast16_t decode_test_internal(enum decode_test_mode_t mode) token_decode_options = 0; break; + case COSE_MAC0_SHORT_CIRCUIT_TAG: + token_encode_options = TOKEN_OPT_SHORT_CIRCUIT_SIGN; + token_decode_options = TOKEN_OPT_SHORT_CIRCUIT_SIGN; + break; + default: return_value = -1000; goto Done; @@ -925,6 +986,11 @@ int_fast16_t decode_test_symmetric_initial_attest(void) { return decode_test_internal(COSE_MAC0); } + +int_fast16_t decode_test_symmetric_iat_short_circuit_tag(void) +{ + return decode_test_internal(COSE_MAC0_SHORT_CIRCUIT_TAG); +} #else /* SYMMETRIC_INITIAL_ATTESTATION */ /* * Public function. See token_test.h diff --git a/test/suites/attestation/attest_token_test.h b/test/suites/attestation/attest_token_test.h index 8bf022d620..37b12e0585 100644 --- a/test/suites/attestation/attest_token_test.h +++ b/test/suites/attestation/attest_token_test.h @@ -77,6 +77,24 @@ int_fast16_t buffer_too_small_test(void); * INCLUDE_TEST_CODE is enabled. */ int_fast16_t decode_test_symmetric_initial_attest(void); + +/** + * \brief Test by checking short-circuit tagged values of claims. + * + * \return non-zero on failure. + * + * This is an extensive test that can compare the values in the token + * to expected valued compiled into the test app from + * token_test_values.h. All the values represented in \ref + * attest_token_iat_simple_t and in \ref attest_token_sw_component_t + * are checked. + * + * This uses a short-circuit tag rather than real HMAC operation with + * symmetric IAK. This tests everything in the implementation except the final + * MAC. It can work even without HMAC integration and without + * any keys configured. + */ +int_fast16_t decode_test_symmetric_iat_short_circuit_tag(void); #else /* SYMMETRIC_INITIAL_ATTESTATION */ /** * \brief Test by checking signed values of claims. diff --git a/test/suites/attestation/non_secure/symmetric_attest_ns_interface_testsuite.c b/test/suites/attestation/non_secure/symmetric_attest_ns_interface_testsuite.c index cd208c6d03..4f5d99aba8 100644 --- a/test/suites/attestation/non_secure/symmetric_attest_ns_interface_testsuite.c +++ b/test/suites/attestation/non_secure/symmetric_attest_ns_interface_testsuite.c @@ -15,10 +15,26 @@ /* Define test suite for attestation service tests */ /* List of tests */ static void tfm_attest_test_2001(struct test_result_t *ret); +#ifdef INCLUDE_TEST_CODE /* Remove them from release build */ +static void tfm_attest_test_2002(struct test_result_t *ret); +static void tfm_attest_test_2003(struct test_result_t *ret); +static void tfm_attest_test_2004(struct test_result_t *ret); +static void tfm_attest_test_2005(struct test_result_t *ret); +#endif static struct test_t attestation_interface_tests[] = { {&tfm_attest_test_2001, "TFM_ATTEST_TEST_2001", "Symmetric key algorithm based Initial Attestation test", {0} }, +#ifdef INCLUDE_TEST_CODE /* Remove them from release build */ + {&tfm_attest_test_2002, "TFM_ATTEST_TEST_2002", + "Minimal token test of attest token", {0} }, + {&tfm_attest_test_2003, "TFM_ATTEST_TEST_2003", + "Minimal token size test of attest token", {0} }, + {&tfm_attest_test_2004, "TFM_ATTEST_TEST_2004", + "Short circuit tag test of attest token", {0} }, + {&tfm_attest_test_2005, "TFM_ATTEST_TEST_2005", + "Negative test cases for initial attestation service", {0} }, +#endif }; void @@ -50,3 +66,98 @@ static void tfm_attest_test_2001(struct test_result_t *ret) ret->val = TEST_PASSED; } + +#ifdef INCLUDE_TEST_CODE /* Remove them from release build */ +/*! + * \brief Get minimal token, only include a hard coded challenge, but omit the + * rest of the claims + * + * Calling the minimal_test, which just retrieves a specific token: + * - only hard coded challenge is included + * - only mandatory claims are included + */ +static void tfm_attest_test_2002(struct test_result_t *ret) +{ + int32_t err; + + err = minimal_test(); + if (err != 0) { + TEST_LOG("minimal_test() returned: %d\r\n", err); + TEST_FAIL("Attest token minimal_test() has failed"); + return; + } + + ret->val = TEST_PASSED; +} + +/*! + * \brief Get the size of the minimal token, only include a hard coded + * challenge, but omit the rest of the claims + */ +static void tfm_attest_test_2003(struct test_result_t *ret) +{ + int32_t err; + + err = minimal_get_size_test(); + if (err != 0) { + TEST_LOG("minimal_get_size_test() returned: %d\r\n", err); + TEST_FAIL("Attest token minimal_get_size_test() has failed"); + return; + } + + ret->val = TEST_PASSED; +} + +/*! + * \brief Get an IAT with short circuit tag (tag is hash of token). + * Parse the token, validate presence of claims and verify the hash value + * + * More info in token_test.h + */ +static void tfm_attest_test_2004(struct test_result_t *ret) +{ + int32_t err; + + err = decode_test_symmetric_iat_short_circuit_tag(); + if (err != 0) { + TEST_LOG("decode_test_symmetric_iat_short_circuit_tag() returned: %d\r\n", err); + TEST_FAIL("Attest token decode_test_symmetric_iat_short_circuit_tag() has failed"); + return; + } + + ret->val = TEST_PASSED; +} + +/*! + * \brief Negative tests for initial attestation service + * + * - Calling initial attestation service with bigger challenge object than + * allowed. + * - Calling initial attestation service with smaller buffer size than the + * expected size of the token. + */ +static void tfm_attest_test_2005(struct test_result_t *ret) +{ + psa_status_t err; + size_t token_size; + + /* Call with with bigger challenge object than allowed */ + err = psa_initial_attest_get_token_size(INVALID_CHALLENGE_OBJECT_SIZE, + &token_size); + + if (err != PSA_ERROR_INVALID_ARGUMENT) { + TEST_FAIL("Attestation should fail with too big challenge object"); + return; + } + + /* Call with smaller buffer size than size of test token */ + err = buffer_too_small_test(); + if (err != 0) { + TEST_LOG("buffer_too_small_test() returned: %d\r\n", err); + TEST_FAIL("Attest token buffer_too_small_test() has failed"); + return; + } + + ret->val = TEST_PASSED; +} +#endif /* INCLUDE_TEST_CODE */ diff --git a/test/suites/attestation/secure/symmetric_attest_s_interface_testsuite.c b/test/suites/attestation/secure/symmetric_attest_s_interface_testsuite.c index 43f0419a6f..a2eb1fdad0 100644 --- a/test/suites/attestation/secure/symmetric_attest_s_interface_testsuite.c +++ b/test/suites/attestation/secure/symmetric_attest_s_interface_testsuite.c @@ -15,11 +15,26 @@ /* Define test suite for attestation service tests */ /* List of tests */ static void tfm_attest_test_1001(struct test_result_t *ret); - +#ifdef INCLUDE_TEST_CODE /* Remove them from release build */ +static void tfm_attest_test_1002(struct test_result_t *ret); +static void tfm_attest_test_1003(struct test_result_t *ret); +static void tfm_attest_test_1004(struct test_result_t *ret); +static void tfm_attest_test_1005(struct test_result_t *ret); +#endif static struct test_t attestation_interface_tests[] = { {&tfm_attest_test_1001, "TFM_ATTEST_TEST_1001", "Symmetric key algorithm based Initial Attestation test", {0} }, +#ifdef INCLUDE_TEST_CODE /* Remove them from release build */ + {&tfm_attest_test_1002, "TFM_ATTEST_TEST_1002", + "Minimal token test of attest token", {0} }, + {&tfm_attest_test_1003, "TFM_ATTEST_TEST_1003", + "Minimal token size test of attest token", {0} }, + {&tfm_attest_test_1004, "TFM_ATTEST_TEST_1004", + "Short circuit tag test of attest token", {0} }, + {&tfm_attest_test_1005, "TFM_ATTEST_TEST_1005", + "Negative test cases for initial attestation service", {0} }, +#endif }; void @@ -51,3 +66,98 @@ static void tfm_attest_test_1001(struct test_result_t *ret) ret->val = TEST_PASSED; } + +#ifdef INCLUDE_TEST_CODE /* Remove them from release build */ +/*! + * \brief Get minimal token, only include a hard coded challenge, but omit the + * rest of the claims + * + * Calling the minimal_test, which just retrieves a specific token: + * - only hard coded challenge is included + * - only mandatory claims are included + */ +static void tfm_attest_test_1002(struct test_result_t *ret) +{ + int32_t err; + + err = minimal_test(); + if (err != 0) { + TEST_LOG("minimal_test() returned: %d\r\n", err); + TEST_FAIL("Attest token minimal_test() has failed"); + return; + } + + ret->val = TEST_PASSED; +} + +/*! + * \brief Get the size of the minimal token, only include a hard coded + * challenge, but omit the rest of the claims + */ +static void tfm_attest_test_1003(struct test_result_t *ret) +{ + int32_t err; + + err = minimal_get_size_test(); + if (err != 0) { + TEST_LOG("minimal_get_size_test() returned: %d\r\n", err); + TEST_FAIL("Attest token minimal_get_size_test() has failed"); + return; + } + + ret->val = TEST_PASSED; +} + +/*! + * \brief Get an IAT with short circuit tag (tag is hash of token). + * Parse the token, validate presence of claims and verify the hash value + * + * More info in token_test.h + */ +static void tfm_attest_test_1004(struct test_result_t *ret) +{ + int32_t err; + + err = decode_test_symmetric_iat_short_circuit_tag(); + if (err != 0) { + TEST_LOG("decode_test_symmetric_iat_short_circuit_tag() returned: %d\r\n", err); + TEST_FAIL("Attest token decode_test_symmetric_iat_short_circuit_tag() has failed"); + return; + } + + ret->val = TEST_PASSED; +} + +/*! + * \brief Negative tests for initial attestation service + * + * - Calling initial attestation service with bigger challenge object than + * allowed. + * - Calling initial attestation service with smaller buffer size than the + * expected size of the token. + */ +static void tfm_attest_test_1005(struct test_result_t *ret) +{ + psa_status_t err; + size_t token_size; + + /* Call with with bigger challenge object than allowed */ + err = psa_initial_attest_get_token_size(INVALID_CHALLENGE_OBJECT_SIZE, + &token_size); + + if (err != PSA_ERROR_INVALID_ARGUMENT) { + TEST_FAIL("Attestation should fail with too big challenge object"); + return; + } + + /* Call with smaller buffer size than size of test token */ + err = buffer_too_small_test(); + if (err != 0) { + TEST_LOG("buffer_too_small_test() returned: %d\r\n", err); + TEST_FAIL("Attest token buffer_too_small_test() has failed"); + return; + } + + ret->val = TEST_PASSED; +} +#endif /* INCLUDE_TEST_CODE */ |