1a8e1175bSopenharmony_ci/** Code to exercise a PSA key object, i.e. validate that it seems well-formed 2a8e1175bSopenharmony_ci * and can do what it is supposed to do. 3a8e1175bSopenharmony_ci */ 4a8e1175bSopenharmony_ci/* 5a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 6a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 7a8e1175bSopenharmony_ci */ 8a8e1175bSopenharmony_ci 9a8e1175bSopenharmony_ci#ifndef PSA_EXERCISE_KEY_H 10a8e1175bSopenharmony_ci#define PSA_EXERCISE_KEY_H 11a8e1175bSopenharmony_ci 12a8e1175bSopenharmony_ci#include "test/helpers.h" 13a8e1175bSopenharmony_ci#include "test/psa_crypto_helpers.h" 14a8e1175bSopenharmony_ci 15a8e1175bSopenharmony_ci#include <psa/crypto.h> 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C) 18a8e1175bSopenharmony_ci#include <mbedtls/pk.h> 19a8e1175bSopenharmony_ci#endif 20a8e1175bSopenharmony_ci 21a8e1175bSopenharmony_ci/** \def KNOWN_SUPPORTED_HASH_ALG 22a8e1175bSopenharmony_ci * 23a8e1175bSopenharmony_ci * A hash algorithm that is known to be supported. 24a8e1175bSopenharmony_ci * 25a8e1175bSopenharmony_ci * This is used in some smoke tests. 26a8e1175bSopenharmony_ci */ 27a8e1175bSopenharmony_ci#if defined(PSA_WANT_ALG_SHA_256) 28a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_256 29a8e1175bSopenharmony_ci#elif defined(PSA_WANT_ALG_SHA_384) 30a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_384 31a8e1175bSopenharmony_ci#elif defined(PSA_WANT_ALG_SHA_512) 32a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_512 33a8e1175bSopenharmony_ci#elif defined(PSA_WANT_ALG_SHA3_256) 34a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA3_256 35a8e1175bSopenharmony_ci#elif defined(PSA_WANT_ALG_SHA_1) 36a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_SHA_1 37a8e1175bSopenharmony_ci#elif defined(PSA_WANT_ALG_MD5) 38a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_HASH_ALG PSA_ALG_MD5 39a8e1175bSopenharmony_ci/* PSA_WANT_ALG_RIPEMD160 omitted. This is necessary for the sake of 40a8e1175bSopenharmony_ci * exercise_signature_key() because Mbed TLS doesn't support RIPEMD160 41a8e1175bSopenharmony_ci * in RSA PKCS#1v1.5 signatures. A RIPEMD160-only configuration would be 42a8e1175bSopenharmony_ci * implausible anyway. */ 43a8e1175bSopenharmony_ci#else 44a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_HASH_ALG 45a8e1175bSopenharmony_ci#endif 46a8e1175bSopenharmony_ci 47a8e1175bSopenharmony_ci/** \def KNOWN_SUPPORTED_BLOCK_CIPHER 48a8e1175bSopenharmony_ci * 49a8e1175bSopenharmony_ci * A block cipher that is known to be supported. 50a8e1175bSopenharmony_ci * 51a8e1175bSopenharmony_ci * For simplicity's sake, stick to block ciphers with 16-byte blocks. 52a8e1175bSopenharmony_ci */ 53a8e1175bSopenharmony_ci#if defined(PSA_WANT_KEY_TYPE_AES) 54a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_AES 55a8e1175bSopenharmony_ci#elif defined(PSA_WANT_KEY_TYPE_ARIA) 56a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_ARIA 57a8e1175bSopenharmony_ci#elif defined(PSA_WANT_KEY_TYPE_CAMELLIA) 58a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER PSA_KEY_TYPE_CAMELLIA 59a8e1175bSopenharmony_ci#else 60a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_BLOCK_CIPHER 61a8e1175bSopenharmony_ci#endif 62a8e1175bSopenharmony_ci 63a8e1175bSopenharmony_ci/** \def KNOWN_SUPPORTED_MAC_ALG 64a8e1175bSopenharmony_ci * 65a8e1175bSopenharmony_ci * A MAC mode that is known to be supported. 66a8e1175bSopenharmony_ci * 67a8e1175bSopenharmony_ci * It must either be HMAC with #KNOWN_SUPPORTED_HASH_ALG or 68a8e1175bSopenharmony_ci * a block cipher-based MAC with #KNOWN_SUPPORTED_BLOCK_CIPHER. 69a8e1175bSopenharmony_ci * 70a8e1175bSopenharmony_ci * This is used in some smoke tests. 71a8e1175bSopenharmony_ci */ 72a8e1175bSopenharmony_ci#if defined(KNOWN_SUPPORTED_HASH_ALG) && defined(PSA_WANT_ALG_HMAC) 73a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_MAC_ALG (PSA_ALG_HMAC(KNOWN_SUPPORTED_HASH_ALG)) 74a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_MAC_KEY_TYPE PSA_KEY_TYPE_HMAC 75a8e1175bSopenharmony_ci#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(MBEDTLS_CMAC_C) 76a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_MAC_ALG PSA_ALG_CMAC 77a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_MAC_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER 78a8e1175bSopenharmony_ci#else 79a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_MAC_ALG 80a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_MAC_KEY_TYPE 81a8e1175bSopenharmony_ci#endif 82a8e1175bSopenharmony_ci 83a8e1175bSopenharmony_ci/** \def KNOWN_SUPPORTED_BLOCK_CIPHER_ALG 84a8e1175bSopenharmony_ci * 85a8e1175bSopenharmony_ci * A cipher algorithm and key type that are known to be supported. 86a8e1175bSopenharmony_ci * 87a8e1175bSopenharmony_ci * This is used in some smoke tests. 88a8e1175bSopenharmony_ci */ 89a8e1175bSopenharmony_ci#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CTR) 90a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CTR 91a8e1175bSopenharmony_ci#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CBC_NO_PADDING) 92a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CBC_NO_PADDING 93a8e1175bSopenharmony_ci#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_CFB) 94a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_CFB 95a8e1175bSopenharmony_ci#elif defined(KNOWN_SUPPORTED_BLOCK_CIPHER) && defined(PSA_WANT_ALG_OFB) 96a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_BLOCK_CIPHER_ALG PSA_ALG_OFB 97a8e1175bSopenharmony_ci#else 98a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_BLOCK_CIPHER_ALG 99a8e1175bSopenharmony_ci#endif 100a8e1175bSopenharmony_ci#if defined(KNOWN_SUPPORTED_BLOCK_CIPHER_ALG) 101a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_CIPHER_ALG KNOWN_SUPPORTED_BLOCK_CIPHER_ALG 102a8e1175bSopenharmony_ci#define KNOWN_SUPPORTED_CIPHER_KEY_TYPE KNOWN_SUPPORTED_BLOCK_CIPHER 103a8e1175bSopenharmony_ci#else 104a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_CIPHER_ALG 105a8e1175bSopenharmony_ci#undef KNOWN_SUPPORTED_CIPHER_KEY_TYPE 106a8e1175bSopenharmony_ci#endif 107a8e1175bSopenharmony_ci 108a8e1175bSopenharmony_ci/** Convenience function to set up a key derivation. 109a8e1175bSopenharmony_ci * 110a8e1175bSopenharmony_ci * In case of failure, mark the current test case as failed. 111a8e1175bSopenharmony_ci * 112a8e1175bSopenharmony_ci * The inputs \p input1 and \p input2 are, in order: 113a8e1175bSopenharmony_ci * - HKDF: salt, info. 114a8e1175bSopenharmony_ci * - TKS 1.2 PRF, TLS 1.2 PSK-to-MS: seed, label. 115a8e1175bSopenharmony_ci * - PBKDF2: input cost, salt. 116a8e1175bSopenharmony_ci * 117a8e1175bSopenharmony_ci * \param operation The operation object to use. 118a8e1175bSopenharmony_ci * It must be in the initialized state. 119a8e1175bSopenharmony_ci * \param key The key to use. 120a8e1175bSopenharmony_ci * \param alg The algorithm to use. 121a8e1175bSopenharmony_ci * \param input1 The first input to pass. 122a8e1175bSopenharmony_ci * \param input1_length The length of \p input1 in bytes. 123a8e1175bSopenharmony_ci * \param input2 The first input to pass. 124a8e1175bSopenharmony_ci * \param input2_length The length of \p input2 in bytes. 125a8e1175bSopenharmony_ci * \param capacity The capacity to set. 126a8e1175bSopenharmony_ci * \param key_destroyable If set to 1, a failure due to the key not existing 127a8e1175bSopenharmony_ci * or the key being destroyed mid-operation will only 128a8e1175bSopenharmony_ci * be reported if the error code is unexpected. 129a8e1175bSopenharmony_ci * 130a8e1175bSopenharmony_ci * \return \c 1 on success, \c 0 on failure. 131a8e1175bSopenharmony_ci */ 132a8e1175bSopenharmony_ciint mbedtls_test_psa_setup_key_derivation_wrap( 133a8e1175bSopenharmony_ci psa_key_derivation_operation_t *operation, 134a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key, 135a8e1175bSopenharmony_ci psa_algorithm_t alg, 136a8e1175bSopenharmony_ci const unsigned char *input1, size_t input1_length, 137a8e1175bSopenharmony_ci const unsigned char *input2, size_t input2_length, 138a8e1175bSopenharmony_ci size_t capacity, int key_destroyable); 139a8e1175bSopenharmony_ci 140a8e1175bSopenharmony_ci/** Perform a key agreement using the given key pair against its public key 141a8e1175bSopenharmony_ci * using psa_raw_key_agreement(). 142a8e1175bSopenharmony_ci * 143a8e1175bSopenharmony_ci * The result is discarded. The purpose of this function is to smoke-test a key. 144a8e1175bSopenharmony_ci * 145a8e1175bSopenharmony_ci * In case of failure, mark the current test case as failed. 146a8e1175bSopenharmony_ci * 147a8e1175bSopenharmony_ci * \param alg A key agreement algorithm compatible with \p key. 148a8e1175bSopenharmony_ci * \param key A key that allows key agreement with \p alg. 149a8e1175bSopenharmony_ci * \param key_destroyable If set to 1, a failure due to the key not existing 150a8e1175bSopenharmony_ci * or the key being destroyed mid-operation will only 151a8e1175bSopenharmony_ci * be reported if the error code is unexpected. 152a8e1175bSopenharmony_ci * 153a8e1175bSopenharmony_ci * \return \c 1 on success, \c 0 on failure. 154a8e1175bSopenharmony_ci */ 155a8e1175bSopenharmony_cipsa_status_t mbedtls_test_psa_raw_key_agreement_with_self( 156a8e1175bSopenharmony_ci psa_algorithm_t alg, 157a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key, int key_destroyable); 158a8e1175bSopenharmony_ci 159a8e1175bSopenharmony_ci/** Perform a key agreement using the given key pair against its public key 160a8e1175bSopenharmony_ci * using psa_key_derivation_raw_key(). 161a8e1175bSopenharmony_ci * 162a8e1175bSopenharmony_ci * The result is discarded. The purpose of this function is to smoke-test a key. 163a8e1175bSopenharmony_ci * 164a8e1175bSopenharmony_ci * In case of failure, mark the current test case as failed. 165a8e1175bSopenharmony_ci * 166a8e1175bSopenharmony_ci * \param operation An operation that has been set up for a key 167a8e1175bSopenharmony_ci * agreement algorithm that is compatible with 168a8e1175bSopenharmony_ci * \p key. 169a8e1175bSopenharmony_ci * \param key A key pair object that is suitable for a key 170a8e1175bSopenharmony_ci * agreement with \p operation. 171a8e1175bSopenharmony_ci * \param key_destroyable If set to 1, a failure due to the key not existing 172a8e1175bSopenharmony_ci * or the key being destroyed mid-operation will only 173a8e1175bSopenharmony_ci * be reported if the error code is unexpected. 174a8e1175bSopenharmony_ci * 175a8e1175bSopenharmony_ci * \return \c 1 on success, \c 0 on failure. 176a8e1175bSopenharmony_ci */ 177a8e1175bSopenharmony_cipsa_status_t mbedtls_test_psa_key_agreement_with_self( 178a8e1175bSopenharmony_ci psa_key_derivation_operation_t *operation, 179a8e1175bSopenharmony_ci mbedtls_svc_key_id_t key, int key_destroyable); 180a8e1175bSopenharmony_ci 181a8e1175bSopenharmony_ci/** Perform sanity checks on the given key representation. 182a8e1175bSopenharmony_ci * 183a8e1175bSopenharmony_ci * If any of the checks fail, mark the current test case as failed. 184a8e1175bSopenharmony_ci * 185a8e1175bSopenharmony_ci * The checks depend on the key type. 186a8e1175bSopenharmony_ci * - All types: check the export size against maximum-size macros. 187a8e1175bSopenharmony_ci * - DES: parity bits. 188a8e1175bSopenharmony_ci * - RSA: check the ASN.1 structure and the size and parity of the integers. 189a8e1175bSopenharmony_ci * - ECC private or public key: exact representation length. 190a8e1175bSopenharmony_ci * - Montgomery public key: first byte. 191a8e1175bSopenharmony_ci * 192a8e1175bSopenharmony_ci * \param type The key type. 193a8e1175bSopenharmony_ci * \param bits The key size in bits. 194a8e1175bSopenharmony_ci * \param exported A buffer containing the key representation. 195a8e1175bSopenharmony_ci * \param exported_length The length of \p exported in bytes. 196a8e1175bSopenharmony_ci * 197a8e1175bSopenharmony_ci * \return \c 1 if all checks passed, \c 0 on failure. 198a8e1175bSopenharmony_ci */ 199a8e1175bSopenharmony_ciint mbedtls_test_psa_exported_key_sanity_check( 200a8e1175bSopenharmony_ci psa_key_type_t type, size_t bits, 201a8e1175bSopenharmony_ci const uint8_t *exported, size_t exported_length); 202a8e1175bSopenharmony_ci 203a8e1175bSopenharmony_ci/** Do smoke tests on a key. 204a8e1175bSopenharmony_ci * 205a8e1175bSopenharmony_ci * Perform one of each operation indicated by \p alg (decrypt/encrypt, 206a8e1175bSopenharmony_ci * sign/verify, or derivation) that is permitted according to \p usage. 207a8e1175bSopenharmony_ci * \p usage and \p alg should correspond to the expected policy on the 208a8e1175bSopenharmony_ci * key. 209a8e1175bSopenharmony_ci * 210a8e1175bSopenharmony_ci * Export the key if permitted by \p usage, and check that the output 211a8e1175bSopenharmony_ci * looks sensible. If \p usage forbids export, check that 212a8e1175bSopenharmony_ci * \p psa_export_key correctly rejects the attempt. If the key is 213a8e1175bSopenharmony_ci * asymmetric, also check \p psa_export_public_key. 214a8e1175bSopenharmony_ci * 215a8e1175bSopenharmony_ci * If the key fails the tests, this function calls the test framework's 216a8e1175bSopenharmony_ci * `mbedtls_test_fail` function and returns false. Otherwise this function 217a8e1175bSopenharmony_ci * returns true. Therefore it should be used as follows: 218a8e1175bSopenharmony_ci * ``` 219a8e1175bSopenharmony_ci * if( ! exercise_key( ... ) ) goto exit; 220a8e1175bSopenharmony_ci * ``` 221a8e1175bSopenharmony_ci * To use this function for multi-threaded tests where the key 222a8e1175bSopenharmony_ci * may be destroyed at any point: call this function with key_destroyable set 223a8e1175bSopenharmony_ci * to 1, while another thread calls psa_destroy_key on the same key; 224a8e1175bSopenharmony_ci * this will test whether destroying the key in use leads to any corruption. 225a8e1175bSopenharmony_ci * 226a8e1175bSopenharmony_ci * There cannot be a set of concurrent calls: 227a8e1175bSopenharmony_ci * `mbedtls_test_psa_exercise_key(ki,...)` such that each ki is a unique 228a8e1175bSopenharmony_ci * persistent key not loaded into any key slot, and i is greater than the 229a8e1175bSopenharmony_ci * number of free key slots. 230a8e1175bSopenharmony_ci * This is because such scenarios can lead to unsupported 231a8e1175bSopenharmony_ci * `PSA_ERROR_INSUFFICIENT_MEMORY` return codes. 232a8e1175bSopenharmony_ci * 233a8e1175bSopenharmony_ci * 234a8e1175bSopenharmony_ci * \param key The key to exercise. It should be capable of performing 235a8e1175bSopenharmony_ci * \p alg. 236a8e1175bSopenharmony_ci * \param usage The usage flags to assume. 237a8e1175bSopenharmony_ci * \param alg The algorithm to exercise. 238a8e1175bSopenharmony_ci * \param key_destroyable If set to 1, a failure due to the key not existing 239a8e1175bSopenharmony_ci * or the key being destroyed mid-operation will only 240a8e1175bSopenharmony_ci * be reported if the error code is unexpected. 241a8e1175bSopenharmony_ci * 242a8e1175bSopenharmony_ci * \retval 0 The key failed the smoke tests. 243a8e1175bSopenharmony_ci * \retval 1 The key passed the smoke tests. 244a8e1175bSopenharmony_ci */ 245a8e1175bSopenharmony_ciint mbedtls_test_psa_exercise_key(mbedtls_svc_key_id_t key, 246a8e1175bSopenharmony_ci psa_key_usage_t usage, 247a8e1175bSopenharmony_ci psa_algorithm_t alg, 248a8e1175bSopenharmony_ci int key_destroyable); 249a8e1175bSopenharmony_ci 250a8e1175bSopenharmony_cipsa_key_usage_t mbedtls_test_psa_usage_to_exercise(psa_key_type_t type, 251a8e1175bSopenharmony_ci psa_algorithm_t alg); 252a8e1175bSopenharmony_ci 253a8e1175bSopenharmony_ci/** Whether the specified algorithm can be exercised. 254a8e1175bSopenharmony_ci * 255a8e1175bSopenharmony_ci * \note This function is solely based on the algorithm and does not 256a8e1175bSopenharmony_ci * consider potential issues with the compatibility of a key. 257a8e1175bSopenharmony_ci * The idea is that you already have a key, so you know that the 258a8e1175bSopenharmony_ci * key type is supported, and you want to exercise the key but 259a8e1175bSopenharmony_ci * only if the algorithm given in its policy is enabled in the 260a8e1175bSopenharmony_ci * compile-time configuration. 261a8e1175bSopenharmony_ci * 262a8e1175bSopenharmony_ci * \note This function currently only supports signature algorithms 263a8e1175bSopenharmony_ci * (including wildcards). 264a8e1175bSopenharmony_ci * TODO: a more general mechanism, which should be automatically 265a8e1175bSopenharmony_ci * generated and possibly available as a library function? 266a8e1175bSopenharmony_ci */ 267a8e1175bSopenharmony_ciint mbedtls_test_can_exercise_psa_algorithm(psa_algorithm_t alg); 268a8e1175bSopenharmony_ci 269a8e1175bSopenharmony_ci#if defined(MBEDTLS_PK_C) 270a8e1175bSopenharmony_ci/** PK-PSA key consistency test. 271a8e1175bSopenharmony_ci * 272a8e1175bSopenharmony_ci * This function tests that the pk context and the PSA key are 273a8e1175bSopenharmony_ci * consistent. At a minimum: 274a8e1175bSopenharmony_ci * 275a8e1175bSopenharmony_ci * - The two objects must contain keys of the same type, 276a8e1175bSopenharmony_ci * or a key pair and a public key of the matching type. 277a8e1175bSopenharmony_ci * - The two objects must have the same public key. 278a8e1175bSopenharmony_ci * 279a8e1175bSopenharmony_ci * \retval 0 The key failed the consistency tests. 280a8e1175bSopenharmony_ci * \retval 1 The key passed the consistency tests. 281a8e1175bSopenharmony_ci */ 282a8e1175bSopenharmony_ciint mbedtls_test_key_consistency_psa_pk(mbedtls_svc_key_id_t psa_key, 283a8e1175bSopenharmony_ci const mbedtls_pk_context *pk); 284a8e1175bSopenharmony_ci#endif /* MBEDTLS_PK_C */ 285a8e1175bSopenharmony_ci 286a8e1175bSopenharmony_ci#endif /* PSA_EXERCISE_KEY_H */ 287