1 /* 2 * Helper functions for tests that use the PSA Crypto API. 3 */ 4 /* 5 * Copyright The Mbed TLS Contributors 6 * SPDX-License-Identifier: Apache-2.0 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); you may 9 * not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 #ifndef PSA_CRYPTO_HELPERS_H 22 #define PSA_CRYPTO_HELPERS_H 23 24 #include "test/helpers.h" 25 26 #if defined(MBEDTLS_PSA_CRYPTO_C) 27 28 #include "test/psa_helpers.h" 29 30 #include <psa/crypto.h> 31 #include <psa_crypto_slot_management.h> 32 33 #if defined(MBEDTLS_USE_PSA_CRYPTO) 34 #include "mbedtls/psa_util.h" 35 #endif 36 37 #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) 38 39 /* Internal function for #TEST_USES_KEY_ID. Return 1 on success, 0 on failure. */ 40 int mbedtls_test_uses_key_id( mbedtls_svc_key_id_t key_id ); 41 42 /** Destroy persistent keys recorded with #TEST_USES_KEY_ID. 43 */ 44 void mbedtls_test_psa_purge_key_storage( void ); 45 46 /** Purge the in-memory cache of persistent keys recorded with 47 * #TEST_USES_KEY_ID. 48 * 49 * Call this function before calling PSA_DONE() if it's ok for 50 * persistent keys to still exist at this point. 51 */ 52 void mbedtls_test_psa_purge_key_cache( void ); 53 54 /** \def TEST_USES_KEY_ID 55 * 56 * Call this macro in a test function before potentially creating a 57 * persistent key. Test functions that use this mechanism must call 58 * mbedtls_test_psa_purge_key_storage() in their cleanup code. 59 * 60 * This macro records a persistent key identifier as potentially used in the 61 * current test case. Recorded key identifiers will be cleaned up at the end 62 * of the test case, even on failure. 63 * 64 * This macro has no effect on volatile keys. Therefore, it is safe to call 65 * this macro in a test function that creates either volatile or persistent 66 * keys depending on the test data. 67 * 68 * This macro currently has no effect on special identifiers 69 * used to store implementation-specific files. 70 * 71 * Calling this macro multiple times on the same key identifier in the same 72 * test case has no effect. 73 * 74 * This macro can fail the test case if there isn't enough memory to 75 * record the key id. 76 * 77 * \param key_id The PSA key identifier to record. 78 */ 79 #define TEST_USES_KEY_ID( key_id ) \ 80 TEST_ASSERT( mbedtls_test_uses_key_id( key_id ) ) 81 82 #else /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ 83 84 #define TEST_USES_KEY_ID( key_id ) ( (void) ( key_id ) ) 85 #define mbedtls_test_psa_purge_key_storage( ) ( (void) 0 ) 86 #define mbedtls_test_psa_purge_key_cache( ) ( (void) 0 ) 87 88 #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ 89 90 #define PSA_INIT( ) PSA_ASSERT( psa_crypto_init( ) ) 91 92 /** Check for things that have not been cleaned up properly in the 93 * PSA subsystem. 94 * 95 * \return NULL if nothing has leaked. 96 * \return A string literal explaining what has not been cleaned up 97 * if applicable. 98 */ 99 const char *mbedtls_test_helper_is_psa_leaking( void ); 100 101 /** Check that no PSA Crypto key slots are in use. 102 * 103 * If any slots are in use, mark the current test as failed and jump to 104 * the exit label. This is equivalent to 105 * `TEST_ASSERT( ! mbedtls_test_helper_is_psa_leaking( ) )` 106 * but with a more informative message. 107 */ 108 #define ASSERT_PSA_PRISTINE( ) \ 109 do \ 110 { \ 111 if( test_fail_if_psa_leaking( __LINE__, __FILE__ ) ) \ 112 goto exit; \ 113 } \ 114 while( 0 ) 115 116 /** Shut down the PSA Crypto subsystem and destroy persistent keys. 117 * Expect a clean shutdown, with no slots in use. 118 * 119 * If some key slots are still in use, record the test case as failed, 120 * but continue executing. This macro is suitable (and primarily intended) 121 * for use in the cleanup section of test functions. 122 * 123 * \note Persistent keys must be recorded with #TEST_USES_KEY_ID before 124 * creating them. 125 */ 126 #define PSA_DONE( ) \ 127 do \ 128 { \ 129 test_fail_if_psa_leaking( __LINE__, __FILE__ ); \ 130 mbedtls_test_psa_purge_key_storage( ); \ 131 mbedtls_psa_crypto_free( ); \ 132 } \ 133 while( 0 ) 134 135 /** Shut down the PSA Crypto subsystem, allowing persistent keys to survive. 136 * Expect a clean shutdown, with no slots in use. 137 * 138 * If some key slots are still in use, record the test case as failed and 139 * jump to the `exit` label. 140 */ 141 #define PSA_SESSION_DONE( ) \ 142 do \ 143 { \ 144 mbedtls_test_psa_purge_key_cache( ); \ 145 ASSERT_PSA_PRISTINE( ); \ 146 mbedtls_psa_crypto_free( ); \ 147 } \ 148 while( 0 ) 149 150 151 152 #if defined(RECORD_PSA_STATUS_COVERAGE_LOG) 153 psa_status_t mbedtls_test_record_status( psa_status_t status, 154 const char *func, 155 const char *file, int line, 156 const char *expr ); 157 158 /** Return value logging wrapper macro. 159 * 160 * Evaluate \p expr. Write a line recording its value to the log file 161 * #STATUS_LOG_FILE_NAME and return the value. The line is a colon-separated 162 * list of fields: 163 * ``` 164 * value of expr:string:__FILE__:__LINE__:expr 165 * ``` 166 * 167 * The test code does not call this macro explicitly because that would 168 * be very invasive. Instead, we instrument the source code by defining 169 * a bunch of wrapper macros like 170 * ``` 171 * #define psa_crypto_init() RECORD_STATUS("psa_crypto_init", psa_crypto_init()) 172 * ``` 173 * These macro definitions must be present in `instrument_record_status.h` 174 * when building the test suites. 175 * 176 * \param string A string, normally a function name. 177 * \param expr An expression to evaluate, normally a call of the function 178 * whose name is in \p string. This expression must return 179 * a value of type #psa_status_t. 180 * \return The value of \p expr. 181 */ 182 #define RECORD_STATUS( string, expr ) \ 183 mbedtls_test_record_status( ( expr ), string, __FILE__, __LINE__, #expr ) 184 185 #include "instrument_record_status.h" 186 187 #endif /* defined(RECORD_PSA_STATUS_COVERAGE_LOG) */ 188 189 /** Return extended key usage policies. 190 * 191 * Do a key policy permission extension on key usage policies always involves 192 * permissions of other usage policies 193 * (like PSA_KEY_USAGE_SIGN_HASH involves PSA_KEY_USAGE_SIGN_MESSGAE). 194 */ 195 psa_key_usage_t mbedtls_test_update_key_usage_flags( psa_key_usage_t usage_flags ); 196 197 /** Skip a test case if the given key is a 192 bits AES key and the AES 198 * implementation is at least partially provided by an accelerator or 199 * alternative implementation. 200 * 201 * Call this macro in a test case when a cryptographic operation that may 202 * involve an AES operation returns a #PSA_ERROR_NOT_SUPPORTED error code. 203 * The macro call will skip and not fail the test case in case the operation 204 * involves a 192 bits AES key and the AES implementation is at least 205 * partially provided by an accelerator or alternative implementation. 206 * 207 * Hardware AES implementations not supporting 192 bits keys commonly exist. 208 * Consequently, PSA test cases aim at not failing when an AES operation with 209 * a 192 bits key performed by an alternative AES implementation returns 210 * with the #PSA_ERROR_NOT_SUPPORTED error code. The purpose of this macro 211 * is to facilitate this and make the test case code more readable. 212 * 213 * \param key_type Key type 214 * \param key_bits Key length in number of bits. 215 */ 216 #if defined(MBEDTLS_AES_ALT) || \ 217 defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \ 218 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES) 219 #define MBEDTLS_TEST_HAVE_ALT_AES 1 220 #else 221 #define MBEDTLS_TEST_HAVE_ALT_AES 0 222 #endif 223 224 #define MBEDTLS_TEST_PSA_SKIP_IF_ALT_AES_192( key_type, key_bits ) \ 225 do \ 226 { \ 227 if( ( MBEDTLS_TEST_HAVE_ALT_AES ) && \ 228 ( ( key_type ) == PSA_KEY_TYPE_AES ) && \ 229 ( key_bits == 192 ) ) \ 230 { \ 231 mbedtls_test_skip( "AES-192 not supported", __LINE__, __FILE__ ); \ 232 goto exit; \ 233 } \ 234 } \ 235 while( 0 ) 236 237 /** Skip a test case if a GCM operation with a nonce length different from 238 * 12 bytes fails and was performed by an accelerator or alternative 239 * implementation. 240 * 241 * Call this macro in a test case when an AEAD cryptography operation that 242 * may involve the GCM mode returns with a #PSA_ERROR_NOT_SUPPORTED error 243 * code. The macro call will skip and not fail the test case in case the 244 * operation involves the GCM mode, a nonce with a length different from 245 * 12 bytes and the GCM mode implementation is an alternative one. 246 * 247 * Hardware GCM implementations not supporting nonce lengths different from 248 * 12 bytes commonly exist, as supporting a non-12-byte nonce requires 249 * additional computations involving the GHASH function. 250 * Consequently, PSA test cases aim at not failing when an AEAD operation in 251 * GCM mode with a nonce length different from 12 bytes is performed by an 252 * alternative GCM implementation and returns with a #PSA_ERROR_NOT_SUPPORTED 253 * error code. The purpose of this macro is to facilitate this check and make 254 * the test case code more readable. 255 * 256 * \param alg The AEAD algorithm. 257 * \param nonce_length The nonce length in number of bytes. 258 */ 259 #if defined(MBEDTLS_GCM_ALT) || \ 260 defined(MBEDTLS_PSA_ACCEL_ALG_GCM) 261 #define MBEDTLS_TEST_HAVE_ALT_GCM 1 262 #else 263 #define MBEDTLS_TEST_HAVE_ALT_GCM 0 264 #endif 265 266 #define MBEDTLS_TEST_PSA_SKIP_IF_ALT_GCM_NOT_12BYTES_NONCE( alg, \ 267 nonce_length ) \ 268 do \ 269 { \ 270 if( ( MBEDTLS_TEST_HAVE_ALT_GCM ) && \ 271 ( PSA_ALG_AEAD_WITH_SHORTENED_TAG( ( alg ) , 0 ) == \ 272 PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ) ) && \ 273 ( ( nonce_length ) != 12 ) ) \ 274 { \ 275 mbedtls_test_skip( "GCM with non-12-byte IV is not supported", __LINE__, __FILE__ ); \ 276 goto exit; \ 277 } \ 278 } \ 279 while( 0 ) 280 281 #endif /* MBEDTLS_PSA_CRYPTO_C */ 282 283 /** \def USE_PSA_INIT 284 * 285 * Call this macro to initialize the PSA subsystem if #MBEDTLS_USE_PSA_CRYPTO 286 * is enabled and do nothing otherwise. If the initialization fails, mark 287 * the test case as failed and jump to the \p exit label. 288 */ 289 /** \def USE_PSA_DONE 290 * 291 * Call this macro at the end of a test case if you called #USE_PSA_INIT. 292 * This is like #PSA_DONE, except that it does nothing if 293 * #MBEDTLS_USE_PSA_CRYPTO is disabled. 294 */ 295 #if defined(MBEDTLS_USE_PSA_CRYPTO) 296 #define USE_PSA_INIT( ) PSA_INIT( ) 297 #define USE_PSA_DONE( ) PSA_DONE( ) 298 #else /* MBEDTLS_USE_PSA_CRYPTO */ 299 /* Define empty macros so that we can use them in the preamble and teardown 300 * of every test function that uses PSA conditionally based on 301 * MBEDTLS_USE_PSA_CRYPTO. */ 302 #define USE_PSA_INIT( ) ( (void) 0 ) 303 #define USE_PSA_DONE( ) ( (void) 0 ) 304 #endif /* !MBEDTLS_USE_PSA_CRYPTO */ 305 306 #endif /* PSA_CRYPTO_HELPERS_H */ 307