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