blob: 18eac060f59154d4b9f19c28fc43eb92c8155e3d [file] [log] [blame]
Gilles Peskine514a8fd2020-11-13 17:41:53 +01001/** \file psa_crypto_helpers.c
2 *
3 * \brief Helper functions to test PSA crypto functionality.
4 */
5
6/*
7 * Copyright The Mbed TLS Contributors
8 * SPDX-License-Identifier: Apache-2.0
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
11 * not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23#include <test/helpers.h>
24#include <test/macros.h>
Przemyslaw Stekiel53de2622021-11-03 09:35:35 +010025#include <psa_crypto_slot_management.h>
Gilles Peskined4008d52020-11-24 17:34:30 +010026#include <test/psa_crypto_helpers.h>
Gilles Peskine514a8fd2020-11-13 17:41:53 +010027
28#if defined(MBEDTLS_PSA_CRYPTO_C)
29
30#include <psa/crypto.h>
31
Gilles Peskine313ffb82021-02-14 12:51:14 +010032#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C)
33
34#include <psa_crypto_storage.h>
35
36static mbedtls_svc_key_id_t key_ids_used_in_test[9];
37static size_t num_key_ids_used;
38
Gilles Peskine449bd832023-01-11 14:50:10 +010039int mbedtls_test_uses_key_id(mbedtls_svc_key_id_t key_id)
Gilles Peskine313ffb82021-02-14 12:51:14 +010040{
41 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010042 if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key_id) >
43 PSA_MAX_PERSISTENT_KEY_IDENTIFIER) {
Gilles Peskine313ffb82021-02-14 12:51:14 +010044 /* Don't touch key id values that designate non-key files. */
Gilles Peskine449bd832023-01-11 14:50:10 +010045 return 1;
Gilles Peskine313ffb82021-02-14 12:51:14 +010046 }
Gilles Peskine449bd832023-01-11 14:50:10 +010047 for (i = 0; i < num_key_ids_used; i++) {
48 if (mbedtls_svc_key_id_equal(key_id, key_ids_used_in_test[i])) {
49 return 1;
50 }
Gilles Peskine313ffb82021-02-14 12:51:14 +010051 }
Gilles Peskine449bd832023-01-11 14:50:10 +010052 if (num_key_ids_used == ARRAY_LENGTH(key_ids_used_in_test)) {
53 return 0;
54 }
Gilles Peskine313ffb82021-02-14 12:51:14 +010055 key_ids_used_in_test[num_key_ids_used] = key_id;
56 ++num_key_ids_used;
Gilles Peskine449bd832023-01-11 14:50:10 +010057 return 1;
Gilles Peskine313ffb82021-02-14 12:51:14 +010058}
59
Gilles Peskine449bd832023-01-11 14:50:10 +010060void mbedtls_test_psa_purge_key_storage(void)
Gilles Peskine313ffb82021-02-14 12:51:14 +010061{
62 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010063 for (i = 0; i < num_key_ids_used; i++) {
64 psa_destroy_persistent_key(key_ids_used_in_test[i]);
65 }
Gilles Peskine313ffb82021-02-14 12:51:14 +010066 num_key_ids_used = 0;
67}
Gilles Peskineaae718c2021-02-14 13:46:39 +010068
Gilles Peskine449bd832023-01-11 14:50:10 +010069void mbedtls_test_psa_purge_key_cache(void)
Gilles Peskineaae718c2021-02-14 13:46:39 +010070{
71 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010072 for (i = 0; i < num_key_ids_used; i++) {
73 psa_purge_key(key_ids_used_in_test[i]);
74 }
Gilles Peskineaae718c2021-02-14 13:46:39 +010075}
76
Gilles Peskine313ffb82021-02-14 12:51:14 +010077#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */
78
Gilles Peskine449bd832023-01-11 14:50:10 +010079const char *mbedtls_test_helper_is_psa_leaking(void)
Gilles Peskined4008d52020-11-24 17:34:30 +010080{
81 mbedtls_psa_stats_t stats;
82
Gilles Peskine449bd832023-01-11 14:50:10 +010083 mbedtls_psa_get_stats(&stats);
Gilles Peskined4008d52020-11-24 17:34:30 +010084
Gilles Peskine449bd832023-01-11 14:50:10 +010085 if (stats.volatile_slots != 0) {
86 return "A volatile slot has not been closed properly.";
87 }
88 if (stats.persistent_slots != 0) {
89 return "A persistent slot has not been closed properly.";
90 }
91 if (stats.external_slots != 0) {
92 return "An external slot has not been closed properly.";
93 }
94 if (stats.half_filled_slots != 0) {
95 return "A half-filled slot has not been cleared properly.";
96 }
97 if (stats.locked_slots != 0) {
98 return "Some slots are still marked as locked.";
99 }
Gilles Peskined4008d52020-11-24 17:34:30 +0100100
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 return NULL;
Gilles Peskined4008d52020-11-24 17:34:30 +0100102}
103
104#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
105/** Name of the file where return statuses are logged by #RECORD_STATUS. */
106#define STATUS_LOG_FILE_NAME "statuses.log"
107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108psa_status_t mbedtls_test_record_status(psa_status_t status,
109 const char *func,
110 const char *file, int line,
111 const char *expr)
Gilles Peskined4008d52020-11-24 17:34:30 +0100112{
113 /* We open the log file on first use.
114 * We never close the log file, so the record_status feature is not
115 * compatible with resource leak detectors such as Asan.
116 */
117 static FILE *log;
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 if (log == NULL) {
119 log = fopen(STATUS_LOG_FILE_NAME, "a");
120 }
121 fprintf(log, "%d:%s:%s:%d:%s\n", (int) status, func, file, line, expr);
122 return status;
Gilles Peskined4008d52020-11-24 17:34:30 +0100123}
124#endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */
125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126psa_key_usage_t mbedtls_test_update_key_usage_flags(psa_key_usage_t usage_flags)
gabor-mezei-arm4ff73032021-05-13 12:05:01 +0200127{
128 psa_key_usage_t updated_usage = usage_flags;
129
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 if (usage_flags & PSA_KEY_USAGE_SIGN_HASH) {
gabor-mezei-arm4ff73032021-05-13 12:05:01 +0200131 updated_usage |= PSA_KEY_USAGE_SIGN_MESSAGE;
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 }
gabor-mezei-arm4ff73032021-05-13 12:05:01 +0200133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 if (usage_flags & PSA_KEY_USAGE_VERIFY_HASH) {
gabor-mezei-arm4ff73032021-05-13 12:05:01 +0200135 updated_usage |= PSA_KEY_USAGE_VERIFY_MESSAGE;
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 }
gabor-mezei-arm4ff73032021-05-13 12:05:01 +0200137
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 return updated_usage;
gabor-mezei-arm4ff73032021-05-13 12:05:01 +0200139}
140
Yanray Wange64b4052022-10-28 18:12:01 +0800141int mbedtls_test_fail_if_psa_leaking(int line_no, const char *filename)
142{
143 const char *msg = mbedtls_test_helper_is_psa_leaking();
144 if (msg == NULL) {
145 return 0;
146 } else {
147 mbedtls_test_fail(msg, line_no, filename);
148 return 1;
149 }
150}
151
Kusumit Ghoderaoac7a04a2023-08-18 13:47:47 +0530152uint64_t parse_binary_string(data_t *bin_string)
153{
154 uint64_t result = 0;
155 TEST_LE_U(bin_string->len, 8);
156 for (size_t i = 0; i < bin_string->len; i++) {
157 result = result << 8 | bin_string->x[i];
158 }
159exit:
160 return result; /* returns 0 if len > 8 */
161}
162
Gilles Peskinea08def92023-04-28 21:01:49 +0200163#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
164
165#include <mbedtls/entropy.h>
166#include <psa_crypto_its.h>
167
168int mbedtls_test_inject_entropy_seed_read(unsigned char *buf, size_t len)
169{
170 size_t actual_len = 0;
171 psa_status_t status = psa_its_get(PSA_CRYPTO_ITS_RANDOM_SEED_UID,
172 0, len, buf, &actual_len);
173 if (status != 0) {
174 return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
175 }
176 if (actual_len != len) {
177 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
178 }
179 return 0;
180}
181
182int mbedtls_test_inject_entropy_seed_write(unsigned char *buf, size_t len)
183{
184 psa_status_t status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID,
185 len, buf, 0);
186 if (status != 0) {
187 return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
188 }
189 return 0;
190}
191
Gilles Peskinec2d16b22023-04-28 23:39:45 +0200192int mbedtls_test_inject_entropy_restore(void)
193{
194 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
195 for (size_t i = 0; i < sizeof(buf); i++) {
196 buf[i] = (unsigned char) i;
197 }
198 psa_status_t status = mbedtls_psa_inject_entropy(buf, sizeof(buf));
199 /* It's ok if the file was just created, or if it already exists. */
200 if (status != PSA_SUCCESS && status != PSA_ERROR_NOT_PERMITTED) {
201 return status;
202 }
203 return PSA_SUCCESS;
204}
205
Gilles Peskinea08def92023-04-28 21:01:49 +0200206#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
207
Gilles Peskine514a8fd2020-11-13 17:41:53 +0100208#endif /* MBEDTLS_PSA_CRYPTO_C */