blob: 7861185ee813caeab4e2be4d7d31b2c7399581c3 [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
Gilles Peskinea08def92023-04-28 21:01:49 +0200152#if defined(MBEDTLS_PSA_INJECT_ENTROPY)
153
154#include <mbedtls/entropy.h>
155#include <psa_crypto_its.h>
156
157int mbedtls_test_inject_entropy_seed_read(unsigned char *buf, size_t len)
158{
159 size_t actual_len = 0;
160 psa_status_t status = psa_its_get(PSA_CRYPTO_ITS_RANDOM_SEED_UID,
161 0, len, buf, &actual_len);
162 if (status != 0) {
163 return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
164 }
165 if (actual_len != len) {
166 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
167 }
168 return 0;
169}
170
171int mbedtls_test_inject_entropy_seed_write(unsigned char *buf, size_t len)
172{
173 psa_status_t status = psa_its_set(PSA_CRYPTO_ITS_RANDOM_SEED_UID,
174 len, buf, 0);
175 if (status != 0) {
176 return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
177 }
178 return 0;
179}
180
181#endif /* MBEDTLS_PSA_INJECT_ENTROPY */
182
Gilles Peskine514a8fd2020-11-13 17:41:53 +0100183#endif /* MBEDTLS_PSA_CRYPTO_C */