xref: /aosp_15_r20/external/mbedtls/tests/src/psa_crypto_helpers.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /** \file psa_crypto_helpers.c
2*62c56f98SSadaf Ebrahimi  *
3*62c56f98SSadaf Ebrahimi  * \brief Helper functions to test PSA crypto functionality.
4*62c56f98SSadaf Ebrahimi  */
5*62c56f98SSadaf Ebrahimi 
6*62c56f98SSadaf Ebrahimi /*
7*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
8*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
9*62c56f98SSadaf Ebrahimi  */
10*62c56f98SSadaf Ebrahimi 
11*62c56f98SSadaf Ebrahimi #include <test/helpers.h>
12*62c56f98SSadaf Ebrahimi #include <test/macros.h>
13*62c56f98SSadaf Ebrahimi #include <psa_crypto_slot_management.h>
14*62c56f98SSadaf Ebrahimi #include <test/psa_crypto_helpers.h>
15*62c56f98SSadaf Ebrahimi 
16*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_C)
17*62c56f98SSadaf Ebrahimi 
18*62c56f98SSadaf Ebrahimi #include <psa/crypto.h>
19*62c56f98SSadaf Ebrahimi 
20*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
21*62c56f98SSadaf Ebrahimi 
22*62c56f98SSadaf Ebrahimi #include <psa_crypto_storage.h>
23*62c56f98SSadaf Ebrahimi 
24*62c56f98SSadaf Ebrahimi static mbedtls_svc_key_id_t key_ids_used_in_test[9];
25*62c56f98SSadaf Ebrahimi static size_t num_key_ids_used;
26*62c56f98SSadaf Ebrahimi 
mbedtls_test_uses_key_id(mbedtls_svc_key_id_t key_id)27*62c56f98SSadaf Ebrahimi int mbedtls_test_uses_key_id(mbedtls_svc_key_id_t key_id)
28*62c56f98SSadaf Ebrahimi {
29*62c56f98SSadaf Ebrahimi     size_t i;
30*62c56f98SSadaf Ebrahimi     if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key_id) >
31*62c56f98SSadaf Ebrahimi         PSA_MAX_PERSISTENT_KEY_IDENTIFIER) {
32*62c56f98SSadaf Ebrahimi         /* Don't touch key id values that designate non-key files. */
33*62c56f98SSadaf Ebrahimi         return 1;
34*62c56f98SSadaf Ebrahimi     }
35*62c56f98SSadaf Ebrahimi     for (i = 0; i < num_key_ids_used; i++) {
36*62c56f98SSadaf Ebrahimi         if (mbedtls_svc_key_id_equal(key_id, key_ids_used_in_test[i])) {
37*62c56f98SSadaf Ebrahimi             return 1;
38*62c56f98SSadaf Ebrahimi         }
39*62c56f98SSadaf Ebrahimi     }
40*62c56f98SSadaf Ebrahimi     if (num_key_ids_used == ARRAY_LENGTH(key_ids_used_in_test)) {
41*62c56f98SSadaf Ebrahimi         return 0;
42*62c56f98SSadaf Ebrahimi     }
43*62c56f98SSadaf Ebrahimi     key_ids_used_in_test[num_key_ids_used] = key_id;
44*62c56f98SSadaf Ebrahimi     ++num_key_ids_used;
45*62c56f98SSadaf Ebrahimi     return 1;
46*62c56f98SSadaf Ebrahimi }
47*62c56f98SSadaf Ebrahimi 
mbedtls_test_psa_purge_key_storage(void)48*62c56f98SSadaf Ebrahimi void mbedtls_test_psa_purge_key_storage(void)
49*62c56f98SSadaf Ebrahimi {
50*62c56f98SSadaf Ebrahimi     size_t i;
51*62c56f98SSadaf Ebrahimi     for (i = 0; i < num_key_ids_used; i++) {
52*62c56f98SSadaf Ebrahimi         psa_destroy_persistent_key(key_ids_used_in_test[i]);
53*62c56f98SSadaf Ebrahimi     }
54*62c56f98SSadaf Ebrahimi     num_key_ids_used = 0;
55*62c56f98SSadaf Ebrahimi }
56*62c56f98SSadaf Ebrahimi 
mbedtls_test_psa_purge_key_cache(void)57*62c56f98SSadaf Ebrahimi void mbedtls_test_psa_purge_key_cache(void)
58*62c56f98SSadaf Ebrahimi {
59*62c56f98SSadaf Ebrahimi     size_t i;
60*62c56f98SSadaf Ebrahimi     for (i = 0; i < num_key_ids_used; i++) {
61*62c56f98SSadaf Ebrahimi         psa_purge_key(key_ids_used_in_test[i]);
62*62c56f98SSadaf Ebrahimi     }
63*62c56f98SSadaf Ebrahimi }
64*62c56f98SSadaf Ebrahimi 
65*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
66*62c56f98SSadaf Ebrahimi 
mbedtls_test_helper_is_psa_leaking(void)67*62c56f98SSadaf Ebrahimi const char *mbedtls_test_helper_is_psa_leaking(void)
68*62c56f98SSadaf Ebrahimi {
69*62c56f98SSadaf Ebrahimi     mbedtls_psa_stats_t stats;
70*62c56f98SSadaf Ebrahimi 
71*62c56f98SSadaf Ebrahimi     mbedtls_psa_get_stats(&stats);
72*62c56f98SSadaf Ebrahimi 
73*62c56f98SSadaf Ebrahimi     if (stats.volatile_slots != 0) {
74*62c56f98SSadaf Ebrahimi         return "A volatile slot has not been closed properly.";
75*62c56f98SSadaf Ebrahimi     }
76*62c56f98SSadaf Ebrahimi     if (stats.persistent_slots != 0) {
77*62c56f98SSadaf Ebrahimi         return "A persistent slot has not been closed properly.";
78*62c56f98SSadaf Ebrahimi     }
79*62c56f98SSadaf Ebrahimi     if (stats.external_slots != 0) {
80*62c56f98SSadaf Ebrahimi         return "An external slot has not been closed properly.";
81*62c56f98SSadaf Ebrahimi     }
82*62c56f98SSadaf Ebrahimi     if (stats.half_filled_slots != 0) {
83*62c56f98SSadaf Ebrahimi         return "A half-filled slot has not been cleared properly.";
84*62c56f98SSadaf Ebrahimi     }
85*62c56f98SSadaf Ebrahimi     if (stats.locked_slots != 0) {
86*62c56f98SSadaf Ebrahimi         return "Some slots are still marked as locked.";
87*62c56f98SSadaf Ebrahimi     }
88*62c56f98SSadaf Ebrahimi 
89*62c56f98SSadaf Ebrahimi     return NULL;
90*62c56f98SSadaf Ebrahimi }
91*62c56f98SSadaf Ebrahimi 
92*62c56f98SSadaf Ebrahimi #if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
93*62c56f98SSadaf Ebrahimi /** Name of the file where return statuses are logged by #RECORD_STATUS. */
94*62c56f98SSadaf Ebrahimi #define STATUS_LOG_FILE_NAME "statuses.log"
95*62c56f98SSadaf Ebrahimi 
mbedtls_test_record_status(psa_status_t status,const char * func,const char * file,int line,const char * expr)96*62c56f98SSadaf Ebrahimi psa_status_t mbedtls_test_record_status(psa_status_t status,
97*62c56f98SSadaf Ebrahimi                                         const char *func,
98*62c56f98SSadaf Ebrahimi                                         const char *file, int line,
99*62c56f98SSadaf Ebrahimi                                         const char *expr)
100*62c56f98SSadaf Ebrahimi {
101*62c56f98SSadaf Ebrahimi     /* We open the log file on first use.
102*62c56f98SSadaf Ebrahimi      * We never close the log file, so the record_status feature is not
103*62c56f98SSadaf Ebrahimi      * compatible with resource leak detectors such as Asan.
104*62c56f98SSadaf Ebrahimi      */
105*62c56f98SSadaf Ebrahimi     static FILE *log;
106*62c56f98SSadaf Ebrahimi     if (log == NULL) {
107*62c56f98SSadaf Ebrahimi         log = fopen(STATUS_LOG_FILE_NAME, "a");
108*62c56f98SSadaf Ebrahimi     }
109*62c56f98SSadaf Ebrahimi     fprintf(log, "%d:%s:%s:%d:%s\n", (int) status, func, file, line, expr);
110*62c56f98SSadaf Ebrahimi     return status;
111*62c56f98SSadaf Ebrahimi }
112*62c56f98SSadaf Ebrahimi #endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
113*62c56f98SSadaf Ebrahimi 
mbedtls_test_update_key_usage_flags(psa_key_usage_t usage_flags)114*62c56f98SSadaf Ebrahimi psa_key_usage_t mbedtls_test_update_key_usage_flags(psa_key_usage_t usage_flags)
115*62c56f98SSadaf Ebrahimi {
116*62c56f98SSadaf Ebrahimi     psa_key_usage_t updated_usage = usage_flags;
117*62c56f98SSadaf Ebrahimi 
118*62c56f98SSadaf Ebrahimi     if (usage_flags & PSA_KEY_USAGE_SIGN_HASH) {
119*62c56f98SSadaf Ebrahimi         updated_usage |= PSA_KEY_USAGE_SIGN_MESSAGE;
120*62c56f98SSadaf Ebrahimi     }
121*62c56f98SSadaf Ebrahimi 
122*62c56f98SSadaf Ebrahimi     if (usage_flags & PSA_KEY_USAGE_VERIFY_HASH) {
123*62c56f98SSadaf Ebrahimi         updated_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
124*62c56f98SSadaf Ebrahimi     }
125*62c56f98SSadaf Ebrahimi 
126*62c56f98SSadaf Ebrahimi     return updated_usage;
127*62c56f98SSadaf Ebrahimi }
128*62c56f98SSadaf Ebrahimi 
mbedtls_test_fail_if_psa_leaking(int line_no,const char * filename)129*62c56f98SSadaf Ebrahimi int mbedtls_test_fail_if_psa_leaking(int line_no, const char *filename)
130*62c56f98SSadaf Ebrahimi {
131*62c56f98SSadaf Ebrahimi     const char *msg = mbedtls_test_helper_is_psa_leaking();
132*62c56f98SSadaf Ebrahimi     if (msg == NULL) {
133*62c56f98SSadaf Ebrahimi         return 0;
134*62c56f98SSadaf Ebrahimi     } else {
135*62c56f98SSadaf Ebrahimi         mbedtls_test_fail(msg, line_no, filename);
136*62c56f98SSadaf Ebrahimi         return 1;
137*62c56f98SSadaf Ebrahimi     }
138*62c56f98SSadaf Ebrahimi }
139*62c56f98SSadaf Ebrahimi 
mbedtls_test_parse_binary_string(data_t * bin_string)140*62c56f98SSadaf Ebrahimi uint64_t mbedtls_test_parse_binary_string(data_t *bin_string)
141*62c56f98SSadaf Ebrahimi {
142*62c56f98SSadaf Ebrahimi     uint64_t result = 0;
143*62c56f98SSadaf Ebrahimi     TEST_LE_U(bin_string->len, 8);
144*62c56f98SSadaf Ebrahimi     for (size_t i = 0; i < bin_string->len; i++) {
145*62c56f98SSadaf Ebrahimi         result = result << 8 | bin_string->x[i];
146*62c56f98SSadaf Ebrahimi     }
147*62c56f98SSadaf Ebrahimi exit:
148*62c56f98SSadaf Ebrahimi     return result; /* returns 0 if len > 8 */
149*62c56f98SSadaf Ebrahimi }
150*62c56f98SSadaf Ebrahimi 
151*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_PSA_INJECT_ENTROPY)
152*62c56f98SSadaf Ebrahimi 
153*62c56f98SSadaf Ebrahimi #include <mbedtls/entropy.h>
154*62c56f98SSadaf Ebrahimi #include <psa_crypto_its.h>
155*62c56f98SSadaf Ebrahimi 
mbedtls_test_inject_entropy_seed_read(unsigned char * buf,size_t len)156*62c56f98SSadaf Ebrahimi int mbedtls_test_inject_entropy_seed_read(unsigned char *buf, size_t len)
157*62c56f98SSadaf Ebrahimi {
158*62c56f98SSadaf Ebrahimi     size_t actual_len = 0;
159*62c56f98SSadaf Ebrahimi     psa_status_t status = psa_its_get(PSA_CRYPTO_ITS_RANDOM_SEED_UID,
160*62c56f98SSadaf Ebrahimi                                       0, len, buf, &actual_len);
161*62c56f98SSadaf Ebrahimi     if (status != 0) {
162*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
163*62c56f98SSadaf Ebrahimi     }
164*62c56f98SSadaf Ebrahimi     if (actual_len != len) {
165*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
166*62c56f98SSadaf Ebrahimi     }
167*62c56f98SSadaf Ebrahimi     return 0;
168*62c56f98SSadaf Ebrahimi }
169*62c56f98SSadaf Ebrahimi 
mbedtls_test_inject_entropy_seed_write(unsigned char * buf,size_t len)170*62c56f98SSadaf Ebrahimi int mbedtls_test_inject_entropy_seed_write(unsigned char *buf, size_t len)
171*62c56f98SSadaf Ebrahimi {
172*62c56f98SSadaf Ebrahimi     psa_status_t status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID,
173*62c56f98SSadaf Ebrahimi                                       len, buf, 0);
174*62c56f98SSadaf Ebrahimi     if (status != 0) {
175*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
176*62c56f98SSadaf Ebrahimi     }
177*62c56f98SSadaf Ebrahimi     return 0;
178*62c56f98SSadaf Ebrahimi }
179*62c56f98SSadaf Ebrahimi 
mbedtls_test_inject_entropy_restore(void)180*62c56f98SSadaf Ebrahimi int mbedtls_test_inject_entropy_restore(void)
181*62c56f98SSadaf Ebrahimi {
182*62c56f98SSadaf Ebrahimi     unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
183*62c56f98SSadaf Ebrahimi     for (size_t i = 0; i < sizeof(buf); i++) {
184*62c56f98SSadaf Ebrahimi         buf[i] = (unsigned char) i;
185*62c56f98SSadaf Ebrahimi     }
186*62c56f98SSadaf Ebrahimi     psa_status_t status = mbedtls_psa_inject_entropy(buf, sizeof(buf));
187*62c56f98SSadaf Ebrahimi     /* It's ok if the file was just created, or if it already exists. */
188*62c56f98SSadaf Ebrahimi     if (status != PSA_SUCCESS && status != PSA_ERROR_NOT_PERMITTED) {
189*62c56f98SSadaf Ebrahimi         return status;
190*62c56f98SSadaf Ebrahimi     }
191*62c56f98SSadaf Ebrahimi     return PSA_SUCCESS;
192*62c56f98SSadaf Ebrahimi }
193*62c56f98SSadaf Ebrahimi 
194*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_INJECT_ENTROPY */
195*62c56f98SSadaf Ebrahimi 
196*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_PSA_CRYPTO_C */
197