1 /*
2 * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h>
8 #include <service/locator/interface/service_locator.h>
9 #include <CppUTest/TestHarness.h>
10
11 /*
12 * Security tests to check key store partition protects access to keys
13 */
TEST_GROUP(CryptoSecurityPartitioningTests)14 TEST_GROUP(CryptoSecurityPartitioningTests)
15 {
16 void setup()
17 {
18 m_crypto_service_context = NULL;
19 m_rpc_session_a = NULL;
20 m_rpc_session_b = NULL;
21 m_client_a = NULL;
22 m_client_b = NULL;
23
24 service_locator_init();
25
26 m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
27 CHECK_TRUE(m_crypto_service_context);
28
29 /*
30 * Open two RPC sessions, one for client a and the other for client b.
31 * Both have different client identities, assigned when the rpc session is opened.
32 */
33 m_rpc_session_a = service_context_open(m_crypto_service_context);
34 CHECK_TRUE(m_rpc_session_a);
35 m_client_a = new packedc_crypto_client(m_rpc_session_a);
36
37 m_rpc_session_b = service_context_open(m_crypto_service_context);
38 CHECK_TRUE(m_rpc_session_b);
39 m_client_b = new packedc_crypto_client(m_rpc_session_b);
40 }
41
42 void teardown()
43 {
44 delete m_client_a;
45 m_client_a = NULL;
46
47 delete m_client_b;
48 m_client_b = NULL;
49
50 if (m_crypto_service_context) {
51 if (m_rpc_session_a) {
52 service_context_close(m_crypto_service_context, m_rpc_session_a);
53 m_rpc_session_a = NULL;
54 }
55
56 if (m_rpc_session_b) {
57 service_context_close(m_crypto_service_context, m_rpc_session_b);
58 m_rpc_session_b = NULL;
59 }
60
61 service_context_relinquish(m_crypto_service_context);
62 m_crypto_service_context = NULL;
63 }
64 }
65
66 struct service_context *m_crypto_service_context;
67 struct rpc_caller_session *m_rpc_session_a;
68 struct rpc_caller_session *m_rpc_session_b;
69 crypto_client *m_client_a;
70 crypto_client *m_client_b;
71 };
72
TEST(CryptoSecurityPartitioningTests,unauthorizedKeyDestroy)73 TEST(CryptoSecurityPartitioningTests, unauthorizedKeyDestroy)
74 {
75 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
76 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
77
78 psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
79 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
80 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
81 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
82 psa_set_key_bits(&attributes, 256);
83
84 /* Generate a key in the context of client a */
85 psa_key_id_t key_id = PSA_KEY_ID_NULL;
86 status = m_client_a->generate_key(&attributes, &key_id);
87 CHECK_EQUAL(PSA_SUCCESS, status);
88
89 /* Client b attempts to destroy it but shouldn't be permitted */
90 status = m_client_b->destroy_key(key_id);
91 CHECK_EQUAL(PSA_ERROR_INVALID_HANDLE, status);
92
93 /* Client a should be permitted */
94 status = m_client_a->destroy_key(key_id);
95 CHECK_EQUAL(PSA_SUCCESS, status);
96
97 psa_reset_key_attributes(&attributes);
98 }
99
TEST(CryptoSecurityPartitioningTests,independentKeyIdSpace)100 TEST(CryptoSecurityPartitioningTests, independentKeyIdSpace)
101 {
102 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
103 psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
104
105 psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
106 psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
107 psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
108 psa_set_key_bits(&attributes, 256);
109
110 /*
111 * Use the same key id from both clients. Expect clients to have
112 * independent key id spaces.
113 */
114 psa_key_id_t common_key_id = 1111;
115
116 /* Client A generates key */
117 psa_key_id_t key_id_a = PSA_KEY_ID_NULL;
118 psa_set_key_id(&attributes, common_key_id);
119 status = m_client_a->generate_key(&attributes, &key_id_a);
120 CHECK_EQUAL(PSA_SUCCESS, status);
121 CHECK_EQUAL(common_key_id, key_id_a);
122
123 /* Client B does the same using the same key_id */
124 psa_key_id_t key_id_b = PSA_KEY_ID_NULL;
125 psa_set_key_id(&attributes, common_key_id);
126 status = m_client_b->generate_key(&attributes, &key_id_b);
127 CHECK_EQUAL(PSA_SUCCESS, status);
128 CHECK_EQUAL(common_key_id, key_id_b);
129
130 /* Expect both clients to have access to their own keys */
131 status = m_client_a->destroy_key(key_id_a);
132 CHECK_EQUAL(PSA_SUCCESS, status);
133 status = m_client_b->destroy_key(key_id_b);
134 CHECK_EQUAL(PSA_SUCCESS, status);
135
136 psa_reset_key_attributes(&attributes);
137 }
138