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