From 6d81cbc81f1c0d045c3c84e1a59b9be37d1273bc Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 12 Feb 2024 16:25:19 +0100 Subject: [PATCH 01/11] Document new functions psa_generate_key_ext, psa_key_derivation_output_key_ext Document proposed additions to the PSA API: psa_generate_key_ext(), psa_key_derivation_output_key_ext(). For psa_generate_key_ext(), document the one use case we intend to implement immediately, which is generating an RSA key with a custom public exponent. Subsequent commits will implement the documented functionality. Signed-off-by: Gilles Peskine --- include/psa/crypto.h | 164 ++++++++++++++++++++++++++++++++++-- include/psa/crypto_struct.h | 23 +++++ include/psa/crypto_types.h | 24 ++++++ 3 files changed, 204 insertions(+), 7 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index fe10ee0e4..d6ad969b8 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -119,8 +119,9 @@ static psa_key_attributes_t psa_key_attributes_init(void); * value in the structure. * The persistent key will be written to storage when the attribute * structure is passed to a key creation function such as - * psa_import_key(), psa_generate_key(), - * psa_key_derivation_output_key() or psa_copy_key(). + * psa_import_key(), psa_generate_key(), psa_generate_key_ext(), + * psa_key_derivation_output_key(), psa_key_derivation_output_key_ext() + * or psa_copy_key(). * * This function may be declared as `static` (i.e. without external * linkage). This function may be provided as a function-like macro, @@ -163,8 +164,9 @@ static void mbedtls_set_key_owner_id(psa_key_attributes_t *attributes, * value in the structure. * The persistent key will be written to storage when the attribute * structure is passed to a key creation function such as - * psa_import_key(), psa_generate_key(), - * psa_key_derivation_output_key() or psa_copy_key(). + * psa_import_key(), psa_generate_key(), psa_generate_key_ext(), + * psa_key_derivation_output_key(), psa_key_derivation_output_key_ext() + * or psa_copy_key(). * * This function may be declared as `static` (i.e. without external * linkage). This function may be provided as a function-like macro, @@ -3226,7 +3228,8 @@ static psa_key_derivation_operation_t psa_key_derivation_operation_init(void); * psa_key_derivation_set_capacity(). You may do this before, in the middle * of or after providing inputs. For some algorithms, this step is mandatory * because the output depends on the maximum capacity. - * -# To derive a key, call psa_key_derivation_output_key(). + * -# To derive a key, call psa_key_derivation_output_key() or + * psa_key_derivation_output_key_ext(). * To derive a byte string for a different purpose, call * psa_key_derivation_output_bytes(). * Successive calls to these functions use successive output bytes @@ -3449,7 +3452,8 @@ psa_status_t psa_key_derivation_input_integer( * \note Once all inputs steps are completed, the operations will allow: * - psa_key_derivation_output_bytes() if each input was either a direct input * or a key with #PSA_KEY_USAGE_DERIVE set; - * - psa_key_derivation_output_key() if the input for step + * - psa_key_derivation_output_key() or psa_key_derivation_output_key_ext() + * if the input for step * #PSA_KEY_DERIVATION_INPUT_SECRET or #PSA_KEY_DERIVATION_INPUT_PASSWORD * was from a key slot with #PSA_KEY_USAGE_DERIVE and each other input was * either a direct input or a key with #PSA_KEY_USAGE_DERIVE set; @@ -3697,6 +3701,12 @@ psa_status_t psa_key_derivation_output_bytes( * Future versions of this specification may include additional restrictions * on the derived key based on the attributes and strength of the secret key. * + * \note This function is equivalent to calling + * psa_key_derivation_output_key_ext() + * with the method #PSA_KEY_GENERATION_METHOD_INIT and + * `method_length == sizeof(psa_key_generation_method_t)` + * (i.e. `method->flags == 0` and `method->data` is empty). + * * \param[in] attributes The attributes for the new key. * If the key type to be created is * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in @@ -3750,6 +3760,83 @@ psa_status_t psa_key_derivation_output_key( psa_key_derivation_operation_t *operation, mbedtls_svc_key_id_t *key); +/** Derive a key from an ongoing key derivation operation with a custom method. + * + * See the description of psa_key_derivation_out_key() for the operation of + * this function with the default method. + * Mbed TLS currently does not currently support any non-default methods. + * + * \note This function is experimental and may change in future minor + * versions of Mbed TLS. + * + * \param[in] attributes The attributes for the new key. + * If the key type to be created is + * #PSA_KEY_TYPE_PASSWORD_HASH then the algorithm in + * the policy must be the same as in the current + * operation. + * \param[in,out] operation The key derivation operation object to read from. + * \param[in] method Customization parameters for the key generation. + * When this is #PSA_KEY_GENERATION_METHOD_INIT + * with \p method_length = + * `sizeof(psa_key_generation_method_t)`, + * this function is equivalent to + * psa_key_derivation_output_key(). + * Mbed TLS currently only supports the default + * method, i.e. #PSA_KEY_GENERATION_METHOD_INIT, + * for all key types. + * \param method_length Length of \p method in bytes. + * This must be + * `sizeof(psa_key_generation_method_t) + n` + * where `n` is the size of `method->data` in bytes. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_INSUFFICIENT_DATA + * There was not enough data to create the desired key. + * Note that in this case, no output is written to the output buffer. + * The operation's capacity is set to 0, thus subsequent calls to + * this function will not succeed, even with a smaller output buffer. + * \retval #PSA_ERROR_NOT_SUPPORTED + * The key type or key size is not supported, either by the + * implementation in general or in this particular location. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The provided key attributes are not valid for the operation. + * \retval #PSA_ERROR_NOT_PERMITTED + * The #PSA_KEY_DERIVATION_INPUT_SECRET or + * #PSA_KEY_DERIVATION_INPUT_PASSWORD input was not provided through a + * key; or one of the inputs was a key whose policy didn't allow + * #PSA_KEY_USAGE_DERIVE. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The operation state is not valid (it must be active and completed + * all required input steps), or the library has not been previously + * initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_key_derivation_output_key_ext( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + const psa_key_generation_method_t *method, + size_t method_length, + mbedtls_svc_key_id_t *key); + /** Compare output data from a key derivation operation to an expected value. * * This function calculates output bytes from a key derivation algorithm and @@ -3835,7 +3922,8 @@ psa_status_t psa_key_derivation_verify_bytes( * and the permitted algorithm must match the * operation. The value of this key was likely * computed by a previous call to - * psa_key_derivation_output_key(). + * psa_key_derivation_output_key() or + * psa_key_derivation_output_key_ext(). * * \retval #PSA_SUCCESS \emptydescription * \retval #PSA_ERROR_INVALID_SIGNATURE @@ -4003,6 +4091,11 @@ psa_status_t psa_generate_random(uint8_t *output, * between 2^{n-1} and 2^n where n is the bit size specified in the * attributes. * + * \note This function is equivalent to calling psa_generate_key_ext() + * with the method #PSA_KEY_GENERATION_METHOD_INIT and + * `method_length == sizeof(psa_key_generation_method_t)` + * (i.e. `method->flags == 0` and `method->data` is empty). + * * \param[in] attributes The attributes for the new key. * \param[out] key On success, an identifier for the newly created * key. For persistent keys, this is the key @@ -4035,6 +4128,63 @@ psa_status_t psa_generate_random(uint8_t *output, psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key); +/** + * \brief Generate a key or key pair using a custom method. + * + * See the description of psa_generate_key() for the operation of this + * function with the default method. In addition, this function supports + * the following non-default methods, described in more detail in the + * documentation of ::psa_key_generation_method_t: + * + * - RSA keys: generation with a custom public exponent. + * + * \note This function is experimental and may change in future minor + * versions of Mbed TLS. + * + * \param[in] attributes The attributes for the new key. + * \param[in] method Customization parameters for the key generation. + * When this is #PSA_KEY_GENERATION_METHOD_INIT + * with \p method_length = + * `sizeof(psa_key_generation_method_t)`, + * this function is equivalent to + * psa_key_derivation_output_key(). + * \param method_length Length of \p method in bytes. + * This must be + * `sizeof(psa_key_generation_method_t) + n` + * where `n` is the size of `method->data` in bytes. + * \param[out] key On success, an identifier for the newly created + * key. For persistent keys, this is the key + * identifier defined in \p attributes. + * \c 0 on failure. + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * \retval #PSA_ERROR_ALREADY_EXISTS + * This is an attempt to create a persistent key, and there is + * already a persistent key with the given identifier. + * \retval #PSA_ERROR_NOT_SUPPORTED \emptydescription + * \retval #PSA_ERROR_INVALID_ARGUMENT \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_ENTROPY \emptydescription + * \retval #PSA_ERROR_COMMUNICATION_FAILURE \emptydescription + * \retval #PSA_ERROR_HARDWARE_FAILURE \emptydescription + * \retval #PSA_ERROR_CORRUPTION_DETECTED \emptydescription + * \retval #PSA_ERROR_INSUFFICIENT_STORAGE \emptydescription + * \retval #PSA_ERROR_DATA_INVALID \emptydescription + * \retval #PSA_ERROR_DATA_CORRUPT \emptydescription + * \retval #PSA_ERROR_STORAGE_FAILURE \emptydescription + * \retval #PSA_ERROR_BAD_STATE + * The library has not been previously initialized by psa_crypto_init(). + * It is implementation-dependent whether a failure to initialize + * results in this error code. + */ +psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, + const psa_key_generation_method_t *method, + size_t method_length, + mbedtls_svc_key_id_t *key); + /**@}*/ /** \defgroup interruptible_hash Interruptible sign/verify hash diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 34d072ba8..b5e942e6c 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -223,6 +223,29 @@ static inline struct psa_key_derivation_s psa_key_derivation_operation_init( return v; } +struct psa_key_generation_method_s { + /* Future versions may add other fields in this structure. */ + uint32_t flags; + uint8_t data[]; +}; + +/** The default method for key generation or key derivation. + * + * Calling psa_generate_key_ext() or psa_key_derivation_output_key_ext() + * with `method=PSA_KEY_GENERATION_METHOD_INIT` and + * `method_length=sizeof(psa_key_generation_method_t)` is equivalent to + * calling psa_generate_key() or psa_key_derivation_output_key() + * respectively. + */ +#define PSA_KEY_GENERATION_METHOD_INIT { 0 } + +static inline struct psa_key_generation_method_s psa_key_generation_method_init( + void) +{ + const struct psa_key_generation_method_s v = PSA_KEY_GENERATION_METHOD_INIT; + return v; +} + struct psa_key_policy_s { psa_key_usage_t MBEDTLS_PRIVATE(usage); psa_algorithm_t MBEDTLS_PRIVATE(alg); diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h index e2ebd8af3..35a3bdb0e 100644 --- a/include/psa/crypto_types.h +++ b/include/psa/crypto_types.h @@ -455,6 +455,30 @@ typedef uint64_t psa_key_slot_number_t; */ typedef uint16_t psa_key_derivation_step_t; +/** \brief Custom method for key generation or key derivation. + * + * This is a structure type with at least the following fields: + * + * - \c flags: an unsigned integer type. 0 for the default method. + * - \c data: a flexible array of bytes. + * + * The interpretation of this structure depend on the type of the + * created key. + * + * - #PSA_KEY_TYPE_RSA_KEY_PAIR: + * - \c flags: must be 0. + * - \c data: the public exponent, in little-endian order. + * This must be an odd integer and must not be 1. + * Implementations must support 65535, should support 3 and may + * support other values. + * When not using a driver, Mbed TLS supports values up to \c INT_MAX. + * If this is empty or if the custom method is omitted altogether, + * the default value 65537 is used. + * - Other key types: reserved for future use. \c flags must be 0. + * + */ +typedef struct psa_key_generation_method_s psa_key_generation_method_t; + /**@}*/ #endif /* PSA_CRYPTO_TYPES_H */ From 1d25a0a810313b1002e80cc27e1a5834664fbdd1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 12 Feb 2024 16:40:04 +0100 Subject: [PATCH 02/11] Refactoring: extract rsa_test_e Signed-off-by: Gilles Peskine --- tests/suites/test_suite_psa_crypto.function | 86 ++++++++++++--------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 95e7a2dbb..f88121fa5 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1255,6 +1255,54 @@ static void interruptible_signverify_get_minmax_completes(uint32_t max_ops, } #endif /* MBEDTLS_ECP_RESTARTABLE */ +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) +static int rsa_test_e(mbedtls_svc_key_id_t key, + size_t bits, + const data_t *e_arg) +{ + uint8_t *exported = NULL; + size_t exported_size = + PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits); + size_t exported_length = SIZE_MAX; + int ok = 0; + + TEST_CALLOC(exported, exported_size); + PSA_ASSERT(psa_export_public_key(key, + exported, exported_size, + &exported_length)); + uint8_t *p = exported; + uint8_t *end = exported + exported_length; + size_t len; + /* RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER } -- e + */ + TEST_EQUAL(0, mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_SEQUENCE | + MBEDTLS_ASN1_CONSTRUCTED)); + TEST_ASSERT(mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)); + TEST_EQUAL(0, mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_INTEGER)); + if (len >= 1 && p[0] == 0) { + ++p; + --len; + } + if (e_arg->len == 0) { + TEST_EQUAL(len, 3); + TEST_EQUAL(p[0], 1); + TEST_EQUAL(p[1], 0); + TEST_EQUAL(p[2], 1); + } else { + TEST_MEMORY_COMPARE(p, len, e_arg->x, e_arg->len); + } + ok = 1; + +exit: + mbedtls_free(exported); + return ok; +} +#endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -9699,10 +9747,6 @@ void generate_key_rsa(int bits_arg, psa_algorithm_t alg = PSA_ALG_RSA_PKCS1V15_SIGN_RAW; psa_status_t expected_status = expected_status_arg; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - uint8_t *exported = NULL; - size_t exported_size = - PSA_EXPORT_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_RSA_PUBLIC_KEY, bits); - size_t exported_length = SIZE_MAX; uint8_t *e_read_buffer = NULL; int is_default_public_exponent = 0; size_t e_read_size = PSA_KEY_DOMAIN_PARAMETERS_SIZE(type, bits); @@ -9715,7 +9759,6 @@ void generate_key_rsa(int bits_arg, e_read_size = 0; } TEST_CALLOC(e_read_buffer, e_read_size); - TEST_CALLOC(exported, exported_size); PSA_ASSERT(psa_crypto_init()); @@ -9759,37 +9802,7 @@ void generate_key_rsa(int bits_arg, goto exit; } - /* Export the key and check the public exponent. */ - PSA_ASSERT(psa_export_public_key(key, - exported, exported_size, - &exported_length)); - { - uint8_t *p = exported; - uint8_t *end = exported + exported_length; - size_t len; - /* RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER } -- e - */ - TEST_EQUAL(0, mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_SEQUENCE | - MBEDTLS_ASN1_CONSTRUCTED)); - TEST_ASSERT(mbedtls_test_asn1_skip_integer(&p, end, bits, bits, 1)); - TEST_EQUAL(0, mbedtls_asn1_get_tag(&p, end, &len, - MBEDTLS_ASN1_INTEGER)); - if (len >= 1 && p[0] == 0) { - ++p; - --len; - } - if (e_arg->len == 0) { - TEST_EQUAL(len, 3); - TEST_EQUAL(p[0], 1); - TEST_EQUAL(p[1], 0); - TEST_EQUAL(p[2], 1); - } else { - TEST_MEMORY_COMPARE(p, len, e_arg->x, e_arg->len); - } - } + TEST_ASSERT(rsa_test_e(key, bits, e_arg)); exit: /* @@ -9801,7 +9814,6 @@ exit: psa_destroy_key(key); PSA_DONE(); mbedtls_free(e_read_buffer); - mbedtls_free(exported); } /* END_CASE */ From f0765fa06a093df0a931974faccbff3582941541 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 12 Feb 2024 16:46:16 +0100 Subject: [PATCH 03/11] Implement psa_generate_key_ext, psa_key_derivation_output_key_ext Implement and unit-test the new functions psa_generate_key_ext() and psa_key_derivation_output_key_ext(), only for the default method. Signed-off-by: Gilles Peskine --- library/psa_crypto.c | 62 ++++++- tests/suites/test_suite_psa_crypto.data | 48 ++++++ tests/suites/test_suite_psa_crypto.function | 179 ++++++++++++++++++++ 3 files changed, 284 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4a0666bb8..6263be9c2 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6023,9 +6023,27 @@ exit: return status; } -psa_status_t psa_key_derivation_output_key(const psa_key_attributes_t *attributes, - psa_key_derivation_operation_t *operation, - mbedtls_svc_key_id_t *key) +static const psa_key_generation_method_t default_method = PSA_KEY_GENERATION_METHOD_INIT; + +static int psa_key_generation_method_is_default( + const psa_key_generation_method_t *method, + size_t method_length) +{ + if (method_length != sizeof(*method)) { + return 0; + } + if (method->flags != 0) { + return 0; + } + return 1; +} + +psa_status_t psa_key_derivation_output_key_ext( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + const psa_key_generation_method_t *method, + size_t method_length, + mbedtls_svc_key_id_t *key) { psa_status_t status; psa_key_slot_t *slot = NULL; @@ -6039,6 +6057,13 @@ psa_status_t psa_key_derivation_output_key(const psa_key_attributes_t *attribute return PSA_ERROR_INVALID_ARGUMENT; } + if (method_length < sizeof(*method)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (!psa_key_generation_method_is_default(method, method_length)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (operation->alg == PSA_ALG_NONE) { return PSA_ERROR_BAD_STATE; } @@ -6070,6 +6095,16 @@ psa_status_t psa_key_derivation_output_key(const psa_key_attributes_t *attribute return status; } +psa_status_t psa_key_derivation_output_key( + const psa_key_attributes_t *attributes, + psa_key_derivation_operation_t *operation, + mbedtls_svc_key_id_t *key) +{ + return psa_key_derivation_output_key_ext( + attributes, operation, + &default_method, sizeof(default_method), + key); +} /****************************************************************/ @@ -7523,8 +7558,10 @@ psa_status_t psa_generate_key_internal( return PSA_SUCCESS; } -psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, - mbedtls_svc_key_id_t *key) +psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, + const psa_key_generation_method_t *method, + size_t method_length, + mbedtls_svc_key_id_t *key) { psa_status_t status; psa_key_slot_t *slot = NULL; @@ -7544,6 +7581,13 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, return PSA_ERROR_INVALID_ARGUMENT; } + if (method_length < sizeof(*method)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + if (!psa_key_generation_method_is_default(method, method_length)) { + return PSA_ERROR_INVALID_ARGUMENT; + } + status = psa_start_key_creation(PSA_KEY_CREATION_GENERATE, attributes, &slot, &driver); if (status != PSA_SUCCESS) { @@ -7598,6 +7642,14 @@ exit: return status; } +psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, + mbedtls_svc_key_id_t *key) +{ + return psa_generate_key_ext(attributes, + &default_method, sizeof(default_method), + key); +} + /****************************************************************/ /* Module setup */ /****************************************************************/ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 34af94a25..bc6ca1b28 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6870,6 +6870,26 @@ PSA key derivation: PBKDF2-AES-CMAC-PRF-128-> AES-256 depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH derive_key_type:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:"706173737764":"01":"73616c74":PSA_KEY_TYPE_AES:256:"28e288c6345bb5ecf7ca70274208a3ba0f1148b5868537d5e09d3ee6813b1f52" +PSA key derivation: default method -> AES-128 +depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES +derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"":PSA_SUCCESS:"3cb25f25faacd57a90434f64d0362f2a" + +PSA key derivation: null method -> AES-128 +depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES +derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT:"" + +PSA key derivation: method too short by 1 -> AES-128 +depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES +derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:-1:"":PSA_ERROR_INVALID_ARGUMENT:"" + +PSA key derivation: method.flags=1 -> AES-128 +depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES +derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:1:"":PSA_ERROR_INVALID_ARGUMENT:"" + +PSA key derivation: method.data non-empty -> AES-128 +depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES +derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"2a":PSA_ERROR_INVALID_ARGUMENT:"" + PSA key derivation: invalid type (0) depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256 derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_NONE:128:PSA_ERROR_NOT_SUPPORTED:0 @@ -7461,6 +7481,34 @@ PSA generate key: FFDH, 1024 bits, invalid bits depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE generate_key:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0 +PSA generate key ext: RSA, null method +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: RSA, method too short by 1 +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:-1:"":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: RSA, method.flags=1 +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:1:"":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: ECC, null method +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH +generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: ECC, flags=0 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH +generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"":PSA_SUCCESS + +PSA generate key ext: ECC, flags=1 +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH +generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:1:"":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: ECC, method.data non-empty +depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH +generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT + +Key generation method initializers +key_generation_method_init: + PSA import persistent key: raw data, 8 bits depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C persistent_key_load_key_from_storage:"2a":PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:IMPORT_KEY diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index f88121fa5..05b49bd80 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1303,6 +1303,27 @@ exit: } #endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ +static int setup_key_generation_method(psa_key_generation_method_t **method, + size_t *method_length, + int64_t flags_arg, + const data_t *method_data) +{ + if (flags_arg >= 0) { + *method_length = sizeof(**method) + method_data->len; + *method = mbedtls_calloc(1, *method_length); + TEST_ASSERT(*method != NULL); + (*method)->flags = (uint32_t) flags_arg; + memcpy((*method)->data, method_data->x, method_data->len); + } else if (sizeof(**method) + flags_arg > 0) { + *method_length = sizeof(**method) + flags_arg; + *method = mbedtls_calloc(1, *method_length); + TEST_ASSERT(*method != NULL); + } + return 1; +exit: + return 0; +} + /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -9302,6 +9323,81 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void derive_key_ext(int alg_arg, + data_t *key_data, + data_t *input1, + data_t *input2, + int key_type_arg, int bits_arg, + int64_t flags_arg, /*negative for truncated method*/ + data_t *method_data, + psa_status_t expected_status, + data_t *expected_export) +{ + mbedtls_svc_key_id_t base_key = MBEDTLS_SVC_KEY_ID_INIT; + mbedtls_svc_key_id_t derived_key = MBEDTLS_SVC_KEY_ID_INIT; + const psa_algorithm_t alg = alg_arg; + const psa_key_type_t key_type = key_type_arg; + const size_t bits = bits_arg; + psa_key_generation_method_t *method = NULL; + size_t method_length = 0; + psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; + const size_t export_buffer_size = + PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits); + uint8_t *export_buffer = NULL; + psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT; + size_t export_length; + + TEST_CALLOC(export_buffer, export_buffer_size); + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&base_attributes, PSA_KEY_USAGE_DERIVE); + psa_set_key_algorithm(&base_attributes, alg); + psa_set_key_type(&base_attributes, PSA_KEY_TYPE_DERIVE); + PSA_ASSERT(psa_import_key(&base_attributes, key_data->x, key_data->len, + &base_key)); + + if (mbedtls_test_psa_setup_key_derivation_wrap( + &operation, base_key, alg, + input1->x, input1->len, + input2->x, input2->len, + PSA_KEY_DERIVATION_UNLIMITED_CAPACITY) == 0) { + goto exit; + } + + psa_set_key_usage_flags(&derived_attributes, PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&derived_attributes, 0); + psa_set_key_type(&derived_attributes, key_type); + psa_set_key_bits(&derived_attributes, bits); + if (!setup_key_generation_method(&method, &method_length, + flags_arg, method_data)) { + goto exit; + } + + TEST_EQUAL(psa_key_derivation_output_key_ext(&derived_attributes, &operation, + method, method_length, + &derived_key), + expected_status); + + if (expected_status == PSA_SUCCESS) { + PSA_ASSERT(psa_export_key(derived_key, + export_buffer, export_buffer_size, + &export_length)); + TEST_MEMORY_COMPARE(export_buffer, export_length, + expected_export->x, expected_export->len); + } + +exit: + mbedtls_free(export_buffer); + mbedtls_free(method); + psa_key_derivation_abort(&operation); + psa_destroy_key(base_key); + psa_destroy_key(derived_key); + PSA_DONE(); +} +/* END_CASE */ + /* BEGIN_CASE */ void derive_key(int alg_arg, data_t *key_data, data_t *input1, data_t *input2, @@ -9817,6 +9913,89 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void generate_key_ext(int type_arg, + int bits_arg, + int usage_arg, + int alg_arg, + int64_t flags_arg, /*negative for truncated method*/ + data_t *method_data, + int expected_status_arg) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t type = type_arg; + psa_key_usage_t usage = usage_arg; + size_t bits = bits_arg; + psa_algorithm_t alg = alg_arg; + psa_status_t expected_status = expected_status_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_generation_method_t *method = NULL; + size_t method_length = 0; + psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; + + PSA_ASSERT(psa_crypto_init()); + + psa_set_key_usage_flags(&attributes, usage); + psa_set_key_algorithm(&attributes, alg); + psa_set_key_type(&attributes, type); + psa_set_key_bits(&attributes, bits); + + if (!setup_key_generation_method(&method, &method_length, + flags_arg, method_data)) { + goto exit; + } + + /* Generate a key */ + psa_status_t status = psa_generate_key_ext(&attributes, + method, method_length, + &key); + + TEST_EQUAL(status, expected_status); + if (expected_status != PSA_SUCCESS) { + goto exit; + } + + /* Test the key information */ + PSA_ASSERT(psa_get_key_attributes(key, &got_attributes)); + TEST_EQUAL(psa_get_key_type(&got_attributes), type); + TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); + + /* Do something with the key according to its type and permitted usage. */ + if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { + goto exit; + } + +exit: + /* + * Key attributes may have been returned by psa_get_key_attributes() + * thus reset them as required. + */ + psa_reset_key_attributes(&got_attributes); + mbedtls_free(method); + psa_destroy_key(key); + PSA_DONE(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void key_generation_method_init() +{ + psa_key_generation_method_t func = psa_key_generation_method_init(); + psa_key_generation_method_t init = PSA_KEY_GENERATION_METHOD_INIT; + psa_key_generation_method_t zero; + memset(&zero, 0, sizeof(zero)); + + /* In order for sizeof(psa_key_generation_method_t) to mean + * empty data, there must not be any padding in the structure: + * the size of the structure must be the offset of the data field. */ + TEST_EQUAL(sizeof(zero), offsetof(psa_key_generation_method_t, data)); + + TEST_EQUAL(func.flags, 0); + TEST_EQUAL(init.flags, 0); + TEST_EQUAL(zero.flags, 0); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ void persistent_key_load_key_from_storage(data_t *data, int type_arg, int bits_arg, From 7a18f9645c94cfffcf78e06b2631daa88c4546ba Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 12 Feb 2024 16:48:11 +0100 Subject: [PATCH 04/11] psa_generate_key_ext: RSA: support custom public exponent Signed-off-by: Gilles Peskine --- ChangeLog.d/psa_generate_key_ext.txt | 3 + library/psa_crypto.c | 30 +++++++- library/psa_crypto_core.h | 6 ++ .../psa_crypto_driver_wrappers.h.jinja | 7 +- tests/suites/test_suite_psa_crypto.data | 73 ++++++++++++++++--- tests/suites/test_suite_psa_crypto.function | 14 +++- 6 files changed, 119 insertions(+), 14 deletions(-) create mode 100644 ChangeLog.d/psa_generate_key_ext.txt diff --git a/ChangeLog.d/psa_generate_key_ext.txt b/ChangeLog.d/psa_generate_key_ext.txt new file mode 100644 index 000000000..8340f01a3 --- /dev/null +++ b/ChangeLog.d/psa_generate_key_ext.txt @@ -0,0 +1,3 @@ +Features + * The new function psa_generate_key_ext() allows generating an RSA + key pair with a custom public exponent. diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6263be9c2..98823de4c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -7501,11 +7501,16 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation( psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes, + const psa_key_generation_method_t *method, size_t method_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_type_t type = attributes->core.type; + /* Only used for RSA */ + (void) method; + (void) method_length; + if ((attributes->domain_parameters == NULL) && (attributes->domain_parameters_size != 0)) { return PSA_ERROR_INVALID_ARGUMENT; @@ -7526,7 +7531,17 @@ psa_status_t psa_generate_key_internal( #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE) if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - return mbedtls_psa_rsa_generate_key(attributes, + /* Hack: if the method specifies a non-default e, pass it + * via the domain parameters. TODO: refactor this code so + * that mbedtls_psa_rsa_generate_key() gets e via a new + * parameter instead. */ + psa_key_attributes_t override_attributes = *attributes; + if (method_length > sizeof(*method)) { + override_attributes.domain_parameters_size = + method_length - offsetof(psa_key_generation_method_t, data); + override_attributes.domain_parameters = (uint8_t *) &method->data; + } + return mbedtls_psa_rsa_generate_key(&override_attributes, key_buffer, key_buffer_size, key_buffer_length); @@ -7584,6 +7599,14 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, if (method_length < sizeof(*method)) { return PSA_ERROR_INVALID_ARGUMENT; } + +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) + if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + if (method->flags != 0) { + return PSA_ERROR_INVALID_ARGUMENT; + } + } else +#endif if (!psa_key_generation_method_is_default(method, method_length)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -7625,8 +7648,9 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, } status = psa_driver_wrapper_generate_key(attributes, - slot->key.data, slot->key.bytes, &slot->key.bytes); - + method, method_length, + slot->key.data, slot->key.bytes, + &slot->key.bytes); if (status != PSA_SUCCESS) { psa_remove_key_data_from_memory(slot); } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index dc376d7eb..99aea9dcb 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -403,6 +403,10 @@ psa_status_t psa_export_public_key_internal( * entry point. * * \param[in] attributes The attributes for the key to generate. + * \param[in] method The generation method from + * psa_generate_key_ext(). + * This can be \c NULL if \p method_length is 0. + * \param method_length The size of \p method in bytes. * \param[out] key_buffer Buffer where the key data is to be written. * \param[in] key_buffer_size Size of \p key_buffer in bytes. * \param[out] key_buffer_length On success, the number of bytes written in @@ -417,6 +421,8 @@ psa_status_t psa_export_public_key_internal( * The size of \p key_buffer is too small. */ psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes, + const psa_key_generation_method_t *method, + size_t method_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index 924b08cd5..e6d827b0d 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -731,12 +731,16 @@ static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( static inline psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, + const psa_key_generation_method_t *method, size_t method_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime); + /* TODO: if method is non-default, we need a driver that supports + * passing a method. */ + /* Try dynamically-registered SE interface first */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) const psa_drv_se_t *drv; @@ -793,7 +797,8 @@ static inline psa_status_t psa_driver_wrapper_generate_key( /* Software fallback */ status = psa_generate_key_internal( - attributes, key_buffer, key_buffer_size, key_buffer_length ); + attributes, method, method_length, + key_buffer, key_buffer_size, key_buffer_length ); break; /* Add cases for opaque driver here */ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index bc6ca1b28..2d0cf2ce2 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7439,22 +7439,22 @@ PSA generate key: ECC, Curve448, good depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_MONTGOMERY_448 generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):448:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0 -PSA generate key: RSA, default e +PSA generate key: RSA, domain parameters: default e generate_key_rsa:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:"":PSA_SUCCESS -PSA generate key: RSA, e=3 +PSA generate key: RSA, domain parameters: e=3 generate_key_rsa:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:"03":PSA_SUCCESS -PSA generate key: RSA, e=65537 +PSA generate key: RSA, domain parameters: e=65537 generate_key_rsa:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:"010001":PSA_SUCCESS -PSA generate key: RSA, e=513 +PSA generate key: RSA, domain parameters: e=513 generate_key_rsa:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:"0201":PSA_SUCCESS -PSA generate key: RSA, e=1 +PSA generate key: RSA, domain parameters: e=1 generate_key_rsa:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:"01":PSA_ERROR_INVALID_ARGUMENT -PSA generate key: RSA, e=2 +PSA generate key: RSA, domain parameters: e=2 generate_key_rsa:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:"02":PSA_ERROR_INVALID_ARGUMENT PSA generate key: FFDH, 2048 bits, good @@ -7482,13 +7482,68 @@ depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE generate_key:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0 PSA generate key ext: RSA, null method -generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT PSA generate key ext: RSA, method too short by 1 -generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:-1:"":PSA_ERROR_INVALID_ARGUMENT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:-1:"":PSA_ERROR_INVALID_ARGUMENT PSA generate key ext: RSA, method.flags=1 -generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:1:"":PSA_ERROR_INVALID_ARGUMENT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:1:"":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: RSA, empty e +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"":PSA_SUCCESS + +PSA generate key ext: RSA, e=3 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"03":PSA_SUCCESS + +PSA generate key ext: RSA, e=3 with leading zeros +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"000003":PSA_SUCCESS + +# TODO: currently errors with NOT_SUPPORTED because e is converted to an int +# and the conversion errors out if there are too many digits without checking +# for leading zeros. This is a very minor bug. Re-enable this test when this +# bug is fixed. +#PSA generate key ext: RSA, e=3 with many leading zeros +#depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +#generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0000000000000000000000000000000003":PSA_SUCCESS + +PSA generate key ext: RSA, e=513 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0201":PSA_SUCCESS + +PSA generate key ext: RSA, e=65537 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"010001":PSA_SUCCESS + +PSA generate key ext: RSA, e=2^31-1 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:INT_MAX>=0x7fffffff +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"7fffffff":PSA_SUCCESS + +PSA generate key ext: RSA, e=2^31+3 (too large for built-in RSA) +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0x7fffffff +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"80000003":PSA_ERROR_NOT_SUPPORTED + +PSA generate key ext: RSA, e=2^64+3 (too large for built-in RSA) +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0xffffffffffffffff +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"010000000000000003":PSA_ERROR_NOT_SUPPORTED + +PSA generate key ext: RSA, e=1 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"01":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: RSA, e=0 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"00":PSA_ERROR_INVALID_ARGUMENT + +PSA generate key ext: RSA, e=2 +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"02":PSA_ERROR_INVALID_ARGUMENT PSA generate key ext: ECC, null method depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 05b49bd80..34baa1be2 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1293,7 +1293,13 @@ static int rsa_test_e(mbedtls_svc_key_id_t key, TEST_EQUAL(p[1], 0); TEST_EQUAL(p[2], 1); } else { - TEST_MEMORY_COMPARE(p, len, e_arg->x, e_arg->len); + const uint8_t *expected = e_arg->x; + size_t expected_len = e_arg->len; + while (expected_len > 0 && *expected == 0) { + ++expected; + --expected_len; + } + TEST_MEMORY_COMPARE(p, len, expected, expected_len); } ok = 1; @@ -9960,6 +9966,12 @@ void generate_key_ext(int type_arg, TEST_EQUAL(psa_get_key_type(&got_attributes), type); TEST_EQUAL(psa_get_key_bits(&got_attributes), bits); +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) + if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { + TEST_ASSERT(rsa_test_e(key, bits, method_data)); + } +#endif + /* Do something with the key according to its type and permitted usage. */ if (!mbedtls_test_psa_exercise_key(key, usage, alg)) { goto exit; From c81393b2ed29f95648ee77698490a597a1362ca6 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 14 Feb 2024 20:51:28 +0100 Subject: [PATCH 05/11] generate/derive key ext: pass method_data_length rather than method_length Instead of passing the size of the whole structure, just pass the data length and let the implementation worry about adding the size of the structure. The intent with passing the structure size was to allow the client code in a client-server implementation to know nothing about the structure and just copy the bytes to the server. But that was not really a useful consideration since the application has to know the structure layout, so it has to be available in the client implementation's headers. Passing the method data length makes life simpler for everyone by not having to worry about possible padding at the end of the structure, and removes a potential error condition (method_length < sizeof(psa_key_generation_method_t)). Signed-off-by: Gilles Peskine --- include/psa/crypto.h | 28 ++++------ include/psa/crypto_struct.h | 2 +- library/psa_crypto.c | 41 ++++++--------- library/psa_crypto_core.h | 5 +- .../psa_crypto_driver_wrappers.h.jinja | 4 +- tests/suites/test_suite_psa_crypto.data | 20 -------- tests/suites/test_suite_psa_crypto.function | 51 +++++++++---------- 7 files changed, 56 insertions(+), 95 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index d6ad969b8..da1418fa6 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -3704,8 +3704,7 @@ psa_status_t psa_key_derivation_output_bytes( * \note This function is equivalent to calling * psa_key_derivation_output_key_ext() * with the method #PSA_KEY_GENERATION_METHOD_INIT and - * `method_length == sizeof(psa_key_generation_method_t)` - * (i.e. `method->flags == 0` and `method->data` is empty). + * `method_data_length == 0` (i.e. `method->data` is empty). * * \param[in] attributes The attributes for the new key. * If the key type to be created is @@ -3777,17 +3776,14 @@ psa_status_t psa_key_derivation_output_key( * \param[in,out] operation The key derivation operation object to read from. * \param[in] method Customization parameters for the key generation. * When this is #PSA_KEY_GENERATION_METHOD_INIT - * with \p method_length = - * `sizeof(psa_key_generation_method_t)`, + * with \p method_data_length = 0, * this function is equivalent to * psa_key_derivation_output_key(). * Mbed TLS currently only supports the default * method, i.e. #PSA_KEY_GENERATION_METHOD_INIT, * for all key types. - * \param method_length Length of \p method in bytes. - * This must be - * `sizeof(psa_key_generation_method_t) + n` - * where `n` is the size of `method->data` in bytes. + * \param method_data_length + * Length of `method.data` in bytes. * \param[out] key On success, an identifier for the newly created * key. For persistent keys, this is the key * identifier defined in \p attributes. @@ -3834,7 +3830,7 @@ psa_status_t psa_key_derivation_output_key_ext( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, const psa_key_generation_method_t *method, - size_t method_length, + size_t method_data_length, mbedtls_svc_key_id_t *key); /** Compare output data from a key derivation operation to an expected value. @@ -4093,8 +4089,7 @@ psa_status_t psa_generate_random(uint8_t *output, * * \note This function is equivalent to calling psa_generate_key_ext() * with the method #PSA_KEY_GENERATION_METHOD_INIT and - * `method_length == sizeof(psa_key_generation_method_t)` - * (i.e. `method->flags == 0` and `method->data` is empty). + * `method_data_length == 0` (i.e. `method->data` is empty). * * \param[in] attributes The attributes for the new key. * \param[out] key On success, an identifier for the newly created @@ -4144,14 +4139,11 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, * \param[in] attributes The attributes for the new key. * \param[in] method Customization parameters for the key generation. * When this is #PSA_KEY_GENERATION_METHOD_INIT - * with \p method_length = - * `sizeof(psa_key_generation_method_t)`, + * with \p method_data_length = 0, * this function is equivalent to * psa_key_derivation_output_key(). - * \param method_length Length of \p method in bytes. - * This must be - * `sizeof(psa_key_generation_method_t) + n` - * where `n` is the size of `method->data` in bytes. + * \param method_data_length + * Length of `method.data` in bytes. * \param[out] key On success, an identifier for the newly created * key. For persistent keys, this is the key * identifier defined in \p attributes. @@ -4182,7 +4174,7 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, */ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, const psa_key_generation_method_t *method, - size_t method_length, + size_t method_data_length, mbedtls_svc_key_id_t *key); /**@}*/ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index b5e942e6c..248caa2be 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -233,7 +233,7 @@ struct psa_key_generation_method_s { * * Calling psa_generate_key_ext() or psa_key_derivation_output_key_ext() * with `method=PSA_KEY_GENERATION_METHOD_INIT` and - * `method_length=sizeof(psa_key_generation_method_t)` is equivalent to + * `method_data_length == 0` is equivalent to * calling psa_generate_key() or psa_key_derivation_output_key() * respectively. */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 98823de4c..3c328c4d5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6027,12 +6027,12 @@ static const psa_key_generation_method_t default_method = PSA_KEY_GENERATION_MET static int psa_key_generation_method_is_default( const psa_key_generation_method_t *method, - size_t method_length) + size_t method_data_length) { - if (method_length != sizeof(*method)) { + if (method->flags != 0) { return 0; } - if (method->flags != 0) { + if (method_data_length != 0) { return 0; } return 1; @@ -6042,7 +6042,7 @@ psa_status_t psa_key_derivation_output_key_ext( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, const psa_key_generation_method_t *method, - size_t method_length, + size_t method_data_length, mbedtls_svc_key_id_t *key) { psa_status_t status; @@ -6057,10 +6057,7 @@ psa_status_t psa_key_derivation_output_key_ext( return PSA_ERROR_INVALID_ARGUMENT; } - if (method_length < sizeof(*method)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - if (!psa_key_generation_method_is_default(method, method_length)) { + if (!psa_key_generation_method_is_default(method, method_data_length)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -6100,10 +6097,9 @@ psa_status_t psa_key_derivation_output_key( psa_key_derivation_operation_t *operation, mbedtls_svc_key_id_t *key) { - return psa_key_derivation_output_key_ext( - attributes, operation, - &default_method, sizeof(default_method), - key); + return psa_key_derivation_output_key_ext(attributes, operation, + &default_method, 0, + key); } @@ -7501,7 +7497,7 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation( psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, size_t method_length, + const psa_key_generation_method_t *method, size_t method_data_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -7509,7 +7505,7 @@ psa_status_t psa_generate_key_internal( /* Only used for RSA */ (void) method; - (void) method_length; + (void) method_data_length; if ((attributes->domain_parameters == NULL) && (attributes->domain_parameters_size != 0)) { @@ -7536,9 +7532,8 @@ psa_status_t psa_generate_key_internal( * that mbedtls_psa_rsa_generate_key() gets e via a new * parameter instead. */ psa_key_attributes_t override_attributes = *attributes; - if (method_length > sizeof(*method)) { - override_attributes.domain_parameters_size = - method_length - offsetof(psa_key_generation_method_t, data); + if (method_data_length != 0) { + override_attributes.domain_parameters_size = method_data_length; override_attributes.domain_parameters = (uint8_t *) &method->data; } return mbedtls_psa_rsa_generate_key(&override_attributes, @@ -7575,7 +7570,7 @@ psa_status_t psa_generate_key_internal( psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, const psa_key_generation_method_t *method, - size_t method_length, + size_t method_data_length, mbedtls_svc_key_id_t *key) { psa_status_t status; @@ -7596,10 +7591,6 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, return PSA_ERROR_INVALID_ARGUMENT; } - if (method_length < sizeof(*method)) { - return PSA_ERROR_INVALID_ARGUMENT; - } - #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { if (method->flags != 0) { @@ -7607,7 +7598,7 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, } } else #endif - if (!psa_key_generation_method_is_default(method, method_length)) { + if (!psa_key_generation_method_is_default(method, method_data_length)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -7648,7 +7639,7 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, } status = psa_driver_wrapper_generate_key(attributes, - method, method_length, + method, method_data_length, slot->key.data, slot->key.bytes, &slot->key.bytes); if (status != PSA_SUCCESS) { @@ -7670,7 +7661,7 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key) { return psa_generate_key_ext(attributes, - &default_method, sizeof(default_method), + &default_method, 0, key); } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 99aea9dcb..3a9b02d0d 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -405,8 +405,7 @@ psa_status_t psa_export_public_key_internal( * \param[in] attributes The attributes for the key to generate. * \param[in] method The generation method from * psa_generate_key_ext(). - * This can be \c NULL if \p method_length is 0. - * \param method_length The size of \p method in bytes. + * \param method_data_length The size of `method.data` in bytes. * \param[out] key_buffer Buffer where the key data is to be written. * \param[in] key_buffer_size Size of \p key_buffer in bytes. * \param[out] key_buffer_length On success, the number of bytes written in @@ -422,7 +421,7 @@ psa_status_t psa_export_public_key_internal( */ psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes, const psa_key_generation_method_t *method, - size_t method_length, + size_t method_data_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index e6d827b0d..b1a952b82 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -731,7 +731,7 @@ static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( static inline psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, size_t method_length, + const psa_key_generation_method_t *method, size_t method_data_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -797,7 +797,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key( /* Software fallback */ status = psa_generate_key_internal( - attributes, method, method_length, + attributes, method, method_data_length, key_buffer, key_buffer_size, key_buffer_length ); break; diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 2d0cf2ce2..1a0f08b35 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6874,14 +6874,6 @@ PSA key derivation: default method -> AES-128 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"":PSA_SUCCESS:"3cb25f25faacd57a90434f64d0362f2a" -PSA key derivation: null method -> AES-128 -depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES -derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT:"" - -PSA key derivation: method too short by 1 -> AES-128 -depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES -derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:-1:"":PSA_ERROR_INVALID_ARGUMENT:"" - PSA key derivation: method.flags=1 -> AES-128 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:1:"":PSA_ERROR_INVALID_ARGUMENT:"" @@ -7481,14 +7473,6 @@ PSA generate key: FFDH, 1024 bits, invalid bits depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE generate_key:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0 -PSA generate key ext: RSA, null method -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE -generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT - -PSA generate key ext: RSA, method too short by 1 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE -generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:-1:"":PSA_ERROR_INVALID_ARGUMENT - PSA generate key ext: RSA, method.flags=1 depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:1:"":PSA_ERROR_INVALID_ARGUMENT @@ -7545,10 +7529,6 @@ PSA generate key ext: RSA, e=2 depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"02":PSA_ERROR_INVALID_ARGUMENT -PSA generate key ext: ECC, null method -depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH -generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:-offsetof(psa_key_generation_method_t, data):"":PSA_ERROR_INVALID_ARGUMENT - PSA generate key ext: ECC, flags=0 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"":PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 34baa1be2..e946f4e60 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1310,21 +1310,25 @@ exit: #endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ static int setup_key_generation_method(psa_key_generation_method_t **method, - size_t *method_length, - int64_t flags_arg, + size_t *method_data_length, + int flags_arg, const data_t *method_data) { - if (flags_arg >= 0) { - *method_length = sizeof(**method) + method_data->len; - *method = mbedtls_calloc(1, *method_length); - TEST_ASSERT(*method != NULL); - (*method)->flags = (uint32_t) flags_arg; - memcpy((*method)->data, method_data->x, method_data->len); - } else if (sizeof(**method) + flags_arg > 0) { - *method_length = sizeof(**method) + flags_arg; - *method = mbedtls_calloc(1, *method_length); - TEST_ASSERT(*method != NULL); - } + *method_data_length = method_data->len; + /* If there are N bytes of padding at the end of + * psa_key_generation_method_t, then it's enough to allocate + * MIN(sizeof(psa_key_generation_method_t), + * offsetof(psa_key_generation_method_t, data) + method_data_length). + * + * For simplicity, here, we allocate up to N more bytes than necessary. + * In practice, the current layout of psa_key_generation_method_t + * makes padding extremely unlikely, so we don't worry about testing + * that the library code doesn't try to access these extra N bytes. + */ + *method = mbedtls_calloc(1, sizeof(**method) + *method_data_length); + TEST_ASSERT(*method != NULL); + (*method)->flags = (uint32_t) flags_arg; + memcpy((*method)->data, method_data->x, method_data->len); return 1; exit: return 0; @@ -9335,7 +9339,7 @@ void derive_key_ext(int alg_arg, data_t *input1, data_t *input2, int key_type_arg, int bits_arg, - int64_t flags_arg, /*negative for truncated method*/ + int flags_arg, data_t *method_data, psa_status_t expected_status, data_t *expected_export) @@ -9346,7 +9350,7 @@ void derive_key_ext(int alg_arg, const psa_key_type_t key_type = key_type_arg; const size_t bits = bits_arg; psa_key_generation_method_t *method = NULL; - size_t method_length = 0; + size_t method_data_length = 0; psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; const size_t export_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits); @@ -9376,13 +9380,13 @@ void derive_key_ext(int alg_arg, psa_set_key_algorithm(&derived_attributes, 0); psa_set_key_type(&derived_attributes, key_type); psa_set_key_bits(&derived_attributes, bits); - if (!setup_key_generation_method(&method, &method_length, + if (!setup_key_generation_method(&method, &method_data_length, flags_arg, method_data)) { goto exit; } TEST_EQUAL(psa_key_derivation_output_key_ext(&derived_attributes, &operation, - method, method_length, + method, method_data_length, &derived_key), expected_status); @@ -9924,7 +9928,7 @@ void generate_key_ext(int type_arg, int bits_arg, int usage_arg, int alg_arg, - int64_t flags_arg, /*negative for truncated method*/ + int flags_arg, data_t *method_data, int expected_status_arg) { @@ -9936,7 +9940,7 @@ void generate_key_ext(int type_arg, psa_status_t expected_status = expected_status_arg; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_generation_method_t *method = NULL; - size_t method_length = 0; + size_t method_data_length = 0; psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; PSA_ASSERT(psa_crypto_init()); @@ -9946,14 +9950,14 @@ void generate_key_ext(int type_arg, psa_set_key_type(&attributes, type); psa_set_key_bits(&attributes, bits); - if (!setup_key_generation_method(&method, &method_length, + if (!setup_key_generation_method(&method, &method_data_length, flags_arg, method_data)) { goto exit; } /* Generate a key */ psa_status_t status = psa_generate_key_ext(&attributes, - method, method_length, + method, method_data_length, &key); TEST_EQUAL(status, expected_status); @@ -9997,11 +10001,6 @@ void key_generation_method_init() psa_key_generation_method_t zero; memset(&zero, 0, sizeof(zero)); - /* In order for sizeof(psa_key_generation_method_t) to mean - * empty data, there must not be any padding in the structure: - * the size of the structure must be the offset of the data field. */ - TEST_EQUAL(sizeof(zero), offsetof(psa_key_generation_method_t, data)); - TEST_EQUAL(func.flags, 0); TEST_EQUAL(init.flags, 0); TEST_EQUAL(zero.flags, 0); From 69f11c8dfb9c5338fd05e5c1f2d872f295cce9ea Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 14 Feb 2024 23:07:33 +0100 Subject: [PATCH 06/11] generate key ext: skip driver invocation with non-default method In the driver wrapper for psa_generate_key() and psa_generate_key_ext(): * Invoke the built-in code if using a non-default method, even if there might be an accelerator. This is ok because we only support non-default methods for RSA and we don't support driver-only RSA, therefore a non-default method will always have built-in code behind it. * Return NOT_SUPPORTED if trying to use a non-default method with an opaque driver. Signed-off-by: Gilles Peskine --- library/psa_crypto.c | 2 +- library/psa_crypto_core.h | 12 +++++++++++ .../psa_crypto_driver_wrappers.h.jinja | 20 +++++++++++++++---- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3c328c4d5..d84d101dc 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6025,7 +6025,7 @@ exit: static const psa_key_generation_method_t default_method = PSA_KEY_GENERATION_METHOD_INIT; -static int psa_key_generation_method_is_default( +int psa_key_generation_method_is_default( const psa_key_generation_method_t *method, size_t method_data_length) { diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 3a9b02d0d..965db94df 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -396,6 +396,18 @@ psa_status_t psa_export_public_key_internal( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length); +/** Whether a key generation method is the default. + * + * Calls to a key generation driver with a non-default method + * require a driver supporting custom methods. + * + * \param[in] method The key generation method to check. + * \param method_data_length Size of `method.data` in bytes. + */ +int psa_key_generation_method_is_default( + const psa_key_generation_method_t *method, + size_t method_data_length); + /** * \brief Generate a key. * diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index b1a952b82..10843c3f4 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -738,8 +738,18 @@ static inline psa_status_t psa_driver_wrapper_generate_key( psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime); - /* TODO: if method is non-default, we need a driver that supports - * passing a method. */ +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) + int is_default_method = + psa_key_generation_method_is_default(method, method_data_length); + if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_method ) + { + /* We don't support passing a custom method to drivers yet. */ + return PSA_ERROR_NOT_SUPPORTED; + } +#else + int is_default_method = 1; + (void) is_default_method; +#endif /* Try dynamically-registered SE interface first */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -766,8 +776,10 @@ static inline psa_status_t psa_driver_wrapper_generate_key( { case PSA_KEY_LOCATION_LOCAL_STORAGE: #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - /* Transparent drivers are limited to generating asymmetric keys */ - if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) ) + /* Transparent drivers are limited to generating asymmetric keys. */ + /* We don't support passing a custom method to drivers yet. */ + if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) && + is_default_method ) { /* Cycle through all known transparent accelerators */ #if defined(PSA_CRYPTO_DRIVER_TEST) From 63072b1f94f6251b37684a3052ab4bcae4ddc03f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 15 Feb 2024 11:48:58 +0100 Subject: [PATCH 07/11] Only test custom-e RSA key generation when built in Custom-e RSA key generation is not yet supported in the test driver, and we don't support fallback from the test driver to the built-in implementation (even though we're testing with MBEDTLS_RSA_C). So for the time being, only run psa_generate_key_ext test cases for RSA with a custom public exponent when using the built-in implementation. Add a test case to validate that psa_generate_key_ext test cases for RSA with a custom public exponent returns NOT_SUPPORTED (rather than silently doing the wrong thing) when not using built-in RSA (which is subtly different from when having accelerated RSA: if both are enabled, which we currently don't do in all.sh, then this should be supported and this is validated by the test cases above). This wart will be resolved when we add support for drivers with a generate_key_ext entry point. Signed-off-by: Gilles Peskine --- tests/scripts/analyze_outcomes.py | 5 ++++ tests/suites/test_suite_psa_crypto.data | 31 ++++++++++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/scripts/analyze_outcomes.py b/tests/scripts/analyze_outcomes.py index 11e483667..20e2ab76a 100755 --- a/tests/scripts/analyze_outcomes.py +++ b/tests/scripts/analyze_outcomes.py @@ -570,6 +570,11 @@ KNOWN_TASKS = { re.compile(r'mbedtls_ct_zeroize_if .*'), re.compile(r'mbedtls_ct_memmove_left .*') ], + 'test_suite_psa_crypto': [ + # We don't support generate_key_ext entry points + # in drivers yet. + re.compile(r'PSA generate key ext: RSA, e=.*'), + ], } } }, diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 1a0f08b35..e29e466a0 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7482,11 +7482,11 @@ depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRY generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"":PSA_SUCCESS PSA generate key ext: RSA, e=3 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"03":PSA_SUCCESS PSA generate key ext: RSA, e=3 with leading zeros -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"000003":PSA_SUCCESS # TODO: currently errors with NOT_SUPPORTED because e is converted to an int @@ -7494,41 +7494,50 @@ generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS: # for leading zeros. This is a very minor bug. Re-enable this test when this # bug is fixed. #PSA generate key ext: RSA, e=3 with many leading zeros -#depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +#depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT #generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0000000000000000000000000000000003":PSA_SUCCESS PSA generate key ext: RSA, e=513 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"0201":PSA_SUCCESS PSA generate key ext: RSA, e=65537 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"010001":PSA_SUCCESS PSA generate key ext: RSA, e=2^31-1 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:INT_MAX>=0x7fffffff +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:PSA_WANT_ALG_RSA_PKCS1V15_CRYPT:INT_MAX>=0x7fffffff generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_RSA_PKCS1V15_CRYPT:0:"7fffffff":PSA_SUCCESS PSA generate key ext: RSA, e=2^31+3 (too large for built-in RSA) -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0x7fffffff +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0x7fffffff generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"80000003":PSA_ERROR_NOT_SUPPORTED PSA generate key ext: RSA, e=2^64+3 (too large for built-in RSA) -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0xffffffffffffffff +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR_GENERATE:INT_MAX<=0xffffffffffffffff generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"010000000000000003":PSA_ERROR_NOT_SUPPORTED PSA generate key ext: RSA, e=1 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"01":PSA_ERROR_INVALID_ARGUMENT PSA generate key ext: RSA, e=0 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"00":PSA_ERROR_INVALID_ARGUMENT PSA generate key ext: RSA, e=2 -depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"02":PSA_ERROR_INVALID_ARGUMENT +# Check that with a driver, we reject a custom e as unsupported, +# as opposed to silently using the default e. +# When we add proper driver support, remove this test case and remove +# the dependency on MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE from +# the positive/invalid_argument test cases. +PSA generate key ext: RSA, e=3 with driver and no fallback (not yet supported) +depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE:!MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR_GENERATE +generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:0:"03":PSA_ERROR_NOT_SUPPORTED + PSA generate key ext: ECC, flags=0 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"":PSA_SUCCESS From dc5597b3dd9487cf41429292bfd7ab7391c88e61 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Feb 2024 11:42:18 +0100 Subject: [PATCH 08/11] Fix copypasta Signed-off-by: Gilles Peskine --- include/psa/crypto.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index da1418fa6..0878836be 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -3774,7 +3774,7 @@ psa_status_t psa_key_derivation_output_key( * the policy must be the same as in the current * operation. * \param[in,out] operation The key derivation operation object to read from. - * \param[in] method Customization parameters for the key generation. + * \param[in] method Customization parameters for the key derivation. * When this is #PSA_KEY_GENERATION_METHOD_INIT * with \p method_data_length = 0, * this function is equivalent to @@ -4141,7 +4141,7 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, * When this is #PSA_KEY_GENERATION_METHOD_INIT * with \p method_data_length = 0, * this function is equivalent to - * psa_key_derivation_output_key(). + * psa_key_generation_output_key(). * \param method_data_length * Length of `method.data` in bytes. * \param[out] key On success, an identifier for the newly created From e7a7013910067fcf7a32a036991a67b66c2dbe6a Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Feb 2024 11:49:54 +0100 Subject: [PATCH 09/11] Remove initialization function for variable-length struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assigning the return value of a function that returns a struct with a flexible array member does not fill the flexible array member, which leaves a gap in the initialization that could be surprising to programmers. Also, this is a borderline case in ABI design which could cause interoperability problems. So remove this function. This gets rid of an annoying note from GCC about ABI compatibility on (at least) x86_64. ``` In file included from include/psa/crypto.h:4820, from :1: include/psa/crypto_struct.h: In function ‘psa_key_generation_method_init’: include/psa/crypto_struct.h:244:1: note: the ABI of passing struct with a flexible array member has changed in GCC 4.4 244 | { | ^ ``` Signed-off-by: Gilles Peskine --- include/psa/crypto_struct.h | 7 ------- tests/suites/test_suite_psa_crypto.function | 2 -- 2 files changed, 9 deletions(-) diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 248caa2be..f41bc8305 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -239,13 +239,6 @@ struct psa_key_generation_method_s { */ #define PSA_KEY_GENERATION_METHOD_INIT { 0 } -static inline struct psa_key_generation_method_s psa_key_generation_method_init( - void) -{ - const struct psa_key_generation_method_s v = PSA_KEY_GENERATION_METHOD_INIT; - return v; -} - struct psa_key_policy_s { psa_key_usage_t MBEDTLS_PRIVATE(usage); psa_algorithm_t MBEDTLS_PRIVATE(alg); diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index e946f4e60..6cd1e93a2 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -9996,12 +9996,10 @@ exit: /* BEGIN_CASE */ void key_generation_method_init() { - psa_key_generation_method_t func = psa_key_generation_method_init(); psa_key_generation_method_t init = PSA_KEY_GENERATION_METHOD_INIT; psa_key_generation_method_t zero; memset(&zero, 0, sizeof(zero)); - TEST_EQUAL(func.flags, 0); TEST_EQUAL(init.flags, 0); TEST_EQUAL(zero.flags, 0); } From 092ce51c470fabe0c1895048b61ad713fe342ad7 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Feb 2024 12:31:24 +0100 Subject: [PATCH 10/11] Rename "key generation method" to "key production parameters" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Key generation method" was misleading since it also applies to key derivation. Change "key generation" to "key production", which we aren't using yet and has roughly the right intuition. Change "method" to "parameters" which there seems to be a slight preference for. Discussion thread: https://github.com/Mbed-TLS/mbedtls/pull/8815#discussion_r1486524295 Identifiers renamed: psa_key_generation_method_t → psa_key_production_parameters_t psa_key_generation_method_s → psa_key_production_parameters_s PSA_KEY_GENERATION_METHOD_INIT → PSA_KEY_PRODUCTION_PARAMETERS_INIT method → params method_data_length → params_data_length default_method → default_production_parameters psa_key_generation_method_is_default → psa_key_production_parameters_are_default setup_key_generation_method → setup_key_production_parameters key_generation_method_init → key_production_parameters_init Signed-off-by: Gilles Peskine --- include/psa/crypto.h | 54 ++++++++-------- include/psa/crypto_struct.h | 10 +-- include/psa/crypto_types.h | 2 +- library/psa_crypto.c | 45 +++++++------- library/psa_crypto_core.h | 24 ++++---- .../psa_crypto_driver_wrappers.h.jinja | 22 ++++--- tests/suites/test_suite_psa_crypto.data | 4 +- tests/suites/test_suite_psa_crypto.function | 61 +++++++++---------- 8 files changed, 113 insertions(+), 109 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 0878836be..18c783cef 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -3703,8 +3703,8 @@ psa_status_t psa_key_derivation_output_bytes( * * \note This function is equivalent to calling * psa_key_derivation_output_key_ext() - * with the method #PSA_KEY_GENERATION_METHOD_INIT and - * `method_data_length == 0` (i.e. `method->data` is empty). + * with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * and `params_data_length == 0` (i.e. `params->data` is empty). * * \param[in] attributes The attributes for the new key. * If the key type to be created is @@ -3759,11 +3759,13 @@ psa_status_t psa_key_derivation_output_key( psa_key_derivation_operation_t *operation, mbedtls_svc_key_id_t *key); -/** Derive a key from an ongoing key derivation operation with a custom method. +/** Derive a key from an ongoing key derivation operation with custom + * production parameters. * * See the description of psa_key_derivation_out_key() for the operation of - * this function with the default method. - * Mbed TLS currently does not currently support any non-default methods. + * this function with the default production parameters. + * Mbed TLS currently does not currently support any non-default production + * parameters. * * \note This function is experimental and may change in future minor * versions of Mbed TLS. @@ -3774,16 +3776,16 @@ psa_status_t psa_key_derivation_output_key( * the policy must be the same as in the current * operation. * \param[in,out] operation The key derivation operation object to read from. - * \param[in] method Customization parameters for the key derivation. - * When this is #PSA_KEY_GENERATION_METHOD_INIT - * with \p method_data_length = 0, + * \param[in] params Customization parameters for the key derivation. + * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * with \p params_data_length = 0, * this function is equivalent to * psa_key_derivation_output_key(). * Mbed TLS currently only supports the default - * method, i.e. #PSA_KEY_GENERATION_METHOD_INIT, + * method, i.e. #PSA_KEY_PRODUCTION_PARAMETERS_INIT, * for all key types. - * \param method_data_length - * Length of `method.data` in bytes. + * \param params_data_length + * Length of `params->data` in bytes. * \param[out] key On success, an identifier for the newly created * key. For persistent keys, this is the key * identifier defined in \p attributes. @@ -3829,8 +3831,8 @@ psa_status_t psa_key_derivation_output_key( psa_status_t psa_key_derivation_output_key_ext( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, - const psa_key_generation_method_t *method, - size_t method_data_length, + const psa_key_production_parameters_t *params, + size_t params_data_length, mbedtls_svc_key_id_t *key); /** Compare output data from a key derivation operation to an expected value. @@ -4088,8 +4090,8 @@ psa_status_t psa_generate_random(uint8_t *output, * attributes. * * \note This function is equivalent to calling psa_generate_key_ext() - * with the method #PSA_KEY_GENERATION_METHOD_INIT and - * `method_data_length == 0` (i.e. `method->data` is empty). + * with the production parameters #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * and `params_data_length == 0` (i.e. `params->data` is empty). * * \param[in] attributes The attributes for the new key. * \param[out] key On success, an identifier for the newly created @@ -4124,12 +4126,12 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key); /** - * \brief Generate a key or key pair using a custom method. + * \brief Generate a key or key pair using custom production parameters. * * See the description of psa_generate_key() for the operation of this - * function with the default method. In addition, this function supports - * the following non-default methods, described in more detail in the - * documentation of ::psa_key_generation_method_t: + * function with the default production parameters. In addition, this function + * supports the following production customizations, described in more detail + * in the documentation of ::psa_key_production_parameters_t: * * - RSA keys: generation with a custom public exponent. * @@ -4137,13 +4139,13 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, * versions of Mbed TLS. * * \param[in] attributes The attributes for the new key. - * \param[in] method Customization parameters for the key generation. - * When this is #PSA_KEY_GENERATION_METHOD_INIT - * with \p method_data_length = 0, + * \param[in] params Customization parameters for the key generation. + * When this is #PSA_KEY_PRODUCTION_PARAMETERS_INIT + * with \p params_data_length = 0, * this function is equivalent to * psa_key_generation_output_key(). - * \param method_data_length - * Length of `method.data` in bytes. + * \param params_data_length + * Length of `params->data` in bytes. * \param[out] key On success, an identifier for the newly created * key. For persistent keys, this is the key * identifier defined in \p attributes. @@ -4173,8 +4175,8 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, * results in this error code. */ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, - size_t method_data_length, + const psa_key_production_parameters_t *params, + size_t params_data_length, mbedtls_svc_key_id_t *key); /**@}*/ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index f41bc8305..e2068e884 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -223,21 +223,21 @@ static inline struct psa_key_derivation_s psa_key_derivation_operation_init( return v; } -struct psa_key_generation_method_s { +struct psa_key_production_parameters_s { /* Future versions may add other fields in this structure. */ uint32_t flags; uint8_t data[]; }; -/** The default method for key generation or key derivation. +/** The default production parameters for key generation or key derivation. * * Calling psa_generate_key_ext() or psa_key_derivation_output_key_ext() - * with `method=PSA_KEY_GENERATION_METHOD_INIT` and - * `method_data_length == 0` is equivalent to + * with `params=PSA_KEY_PRODUCTION_PARAMETERS_INIT` and + * `params_data_length == 0` is equivalent to * calling psa_generate_key() or psa_key_derivation_output_key() * respectively. */ -#define PSA_KEY_GENERATION_METHOD_INIT { 0 } +#define PSA_KEY_PRODUCTION_PARAMETERS_INIT { 0 } struct psa_key_policy_s { psa_key_usage_t MBEDTLS_PRIVATE(usage); diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h index 35a3bdb0e..c5098073e 100644 --- a/include/psa/crypto_types.h +++ b/include/psa/crypto_types.h @@ -477,7 +477,7 @@ typedef uint16_t psa_key_derivation_step_t; * - Other key types: reserved for future use. \c flags must be 0. * */ -typedef struct psa_key_generation_method_s psa_key_generation_method_t; +typedef struct psa_key_production_parameters_s psa_key_production_parameters_t; /**@}*/ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d84d101dc..4df3dc52c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6023,16 +6023,17 @@ exit: return status; } -static const psa_key_generation_method_t default_method = PSA_KEY_GENERATION_METHOD_INIT; +static const psa_key_production_parameters_t default_production_parameters = + PSA_KEY_PRODUCTION_PARAMETERS_INIT; -int psa_key_generation_method_is_default( - const psa_key_generation_method_t *method, - size_t method_data_length) +int psa_key_production_parameters_are_default( + const psa_key_production_parameters_t *params, + size_t params_data_length) { - if (method->flags != 0) { + if (params->flags != 0) { return 0; } - if (method_data_length != 0) { + if (params_data_length != 0) { return 0; } return 1; @@ -6041,8 +6042,8 @@ int psa_key_generation_method_is_default( psa_status_t psa_key_derivation_output_key_ext( const psa_key_attributes_t *attributes, psa_key_derivation_operation_t *operation, - const psa_key_generation_method_t *method, - size_t method_data_length, + const psa_key_production_parameters_t *params, + size_t params_data_length, mbedtls_svc_key_id_t *key) { psa_status_t status; @@ -6057,7 +6058,7 @@ psa_status_t psa_key_derivation_output_key_ext( return PSA_ERROR_INVALID_ARGUMENT; } - if (!psa_key_generation_method_is_default(method, method_data_length)) { + if (!psa_key_production_parameters_are_default(params, params_data_length)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -6098,7 +6099,7 @@ psa_status_t psa_key_derivation_output_key( mbedtls_svc_key_id_t *key) { return psa_key_derivation_output_key_ext(attributes, operation, - &default_method, 0, + &default_production_parameters, 0, key); } @@ -7497,15 +7498,15 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation( psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, size_t method_data_length, + const psa_key_production_parameters_t *params, size_t params_data_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_type_t type = attributes->core.type; /* Only used for RSA */ - (void) method; - (void) method_data_length; + (void) params; + (void) params_data_length; if ((attributes->domain_parameters == NULL) && (attributes->domain_parameters_size != 0)) { @@ -7532,9 +7533,9 @@ psa_status_t psa_generate_key_internal( * that mbedtls_psa_rsa_generate_key() gets e via a new * parameter instead. */ psa_key_attributes_t override_attributes = *attributes; - if (method_data_length != 0) { - override_attributes.domain_parameters_size = method_data_length; - override_attributes.domain_parameters = (uint8_t *) &method->data; + if (params_data_length != 0) { + override_attributes.domain_parameters_size = params_data_length; + override_attributes.domain_parameters = (uint8_t *) ¶ms->data; } return mbedtls_psa_rsa_generate_key(&override_attributes, key_buffer, @@ -7569,8 +7570,8 @@ psa_status_t psa_generate_key_internal( } psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, - size_t method_data_length, + const psa_key_production_parameters_t *params, + size_t params_data_length, mbedtls_svc_key_id_t *key) { psa_status_t status; @@ -7593,12 +7594,12 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) if (attributes->core.type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - if (method->flags != 0) { + if (params->flags != 0) { return PSA_ERROR_INVALID_ARGUMENT; } } else #endif - if (!psa_key_generation_method_is_default(method, method_data_length)) { + if (!psa_key_production_parameters_are_default(params, params_data_length)) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -7639,7 +7640,7 @@ psa_status_t psa_generate_key_ext(const psa_key_attributes_t *attributes, } status = psa_driver_wrapper_generate_key(attributes, - method, method_data_length, + params, params_data_length, slot->key.data, slot->key.bytes, &slot->key.bytes); if (status != PSA_SUCCESS) { @@ -7661,7 +7662,7 @@ psa_status_t psa_generate_key(const psa_key_attributes_t *attributes, mbedtls_svc_key_id_t *key) { return psa_generate_key_ext(attributes, - &default_method, 0, + &default_production_parameters, 0, key); } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 965db94df..6db533cd7 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -396,17 +396,17 @@ psa_status_t psa_export_public_key_internal( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length); -/** Whether a key generation method is the default. +/** Whether a key production parameters structure is the default. * - * Calls to a key generation driver with a non-default method - * require a driver supporting custom methods. + * Calls to a key generation driver with non-default production parameters + * require a driver supporting custom production parameters. * - * \param[in] method The key generation method to check. - * \param method_data_length Size of `method.data` in bytes. + * \param[in] params The key production parameters to check. + * \param params_data_length Size of `params->data` in bytes. */ -int psa_key_generation_method_is_default( - const psa_key_generation_method_t *method, - size_t method_data_length); +int psa_key_production_parameters_are_default( + const psa_key_production_parameters_t *params, + size_t params_data_length); /** * \brief Generate a key. @@ -415,9 +415,9 @@ int psa_key_generation_method_is_default( * entry point. * * \param[in] attributes The attributes for the key to generate. - * \param[in] method The generation method from + * \param[in] params The production parameters from * psa_generate_key_ext(). - * \param method_data_length The size of `method.data` in bytes. + * \param params_data_length The size of `params->data` in bytes. * \param[out] key_buffer Buffer where the key data is to be written. * \param[in] key_buffer_size Size of \p key_buffer in bytes. * \param[out] key_buffer_length On success, the number of bytes written in @@ -432,8 +432,8 @@ int psa_key_generation_method_is_default( * The size of \p key_buffer is too small. */ psa_status_t psa_generate_key_internal(const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, - size_t method_data_length, + const psa_key_production_parameters_t *params, + size_t params_data_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length); diff --git a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja index 10843c3f4..4f9764d1c 100644 --- a/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja +++ b/scripts/data_files/driver_templates/psa_crypto_driver_wrappers.h.jinja @@ -731,7 +731,7 @@ static inline psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( static inline psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, - const psa_key_generation_method_t *method, size_t method_data_length, + const psa_key_production_parameters_t *params, size_t params_data_length, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -739,16 +739,17 @@ static inline psa_status_t psa_driver_wrapper_generate_key( PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime); #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) - int is_default_method = - psa_key_generation_method_is_default(method, method_data_length); - if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_method ) + int is_default_production = + psa_key_production_parameters_are_default(params, params_data_length); + if( location != PSA_KEY_LOCATION_LOCAL_STORAGE && !is_default_production ) { - /* We don't support passing a custom method to drivers yet. */ + /* We don't support passing custom production parameters + * to drivers yet. */ return PSA_ERROR_NOT_SUPPORTED; } #else - int is_default_method = 1; - (void) is_default_method; + int is_default_production = 1; + (void) is_default_production; #endif /* Try dynamically-registered SE interface first */ @@ -777,9 +778,10 @@ static inline psa_status_t psa_driver_wrapper_generate_key( case PSA_KEY_LOCATION_LOCAL_STORAGE: #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) /* Transparent drivers are limited to generating asymmetric keys. */ - /* We don't support passing a custom method to drivers yet. */ + /* We don't support passing custom production parameters + * to drivers yet. */ if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) && - is_default_method ) + is_default_production ) { /* Cycle through all known transparent accelerators */ #if defined(PSA_CRYPTO_DRIVER_TEST) @@ -809,7 +811,7 @@ static inline psa_status_t psa_driver_wrapper_generate_key( /* Software fallback */ status = psa_generate_key_internal( - attributes, method, method_data_length, + attributes, params, params_data_length, key_buffer, key_buffer_size, key_buffer_length ); break; diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index e29e466a0..8139469e9 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7550,8 +7550,8 @@ PSA generate key ext: ECC, method.data non-empty depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT -Key generation method initializers -key_generation_method_init: +Key production parameters initializers +key_production_parameters_init: PSA import persistent key: raw data, 8 bits depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 6cd1e93a2..b40b5f8db 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1309,26 +1309,25 @@ exit: } #endif /* PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE */ -static int setup_key_generation_method(psa_key_generation_method_t **method, - size_t *method_data_length, - int flags_arg, - const data_t *method_data) +static int setup_key_production_parameters( + psa_key_production_parameters_t **params, size_t *params_data_length, + int flags_arg, const data_t *params_data) { - *method_data_length = method_data->len; + *params_data_length = params_data->len; /* If there are N bytes of padding at the end of - * psa_key_generation_method_t, then it's enough to allocate - * MIN(sizeof(psa_key_generation_method_t), - * offsetof(psa_key_generation_method_t, data) + method_data_length). + * psa_key_production_parameters_t, then it's enough to allocate + * MIN(sizeof(psa_key_production_parameters_t), + * offsetof(psa_key_production_parameters_t, data) + params_data_length). * * For simplicity, here, we allocate up to N more bytes than necessary. - * In practice, the current layout of psa_key_generation_method_t + * In practice, the current layout of psa_key_production_parameters_t * makes padding extremely unlikely, so we don't worry about testing * that the library code doesn't try to access these extra N bytes. */ - *method = mbedtls_calloc(1, sizeof(**method) + *method_data_length); - TEST_ASSERT(*method != NULL); - (*method)->flags = (uint32_t) flags_arg; - memcpy((*method)->data, method_data->x, method_data->len); + *params = mbedtls_calloc(1, sizeof(**params) + *params_data_length); + TEST_ASSERT(*params != NULL); + (*params)->flags = (uint32_t) flags_arg; + memcpy((*params)->data, params_data->x, params_data->len); return 1; exit: return 0; @@ -9340,7 +9339,7 @@ void derive_key_ext(int alg_arg, data_t *input2, int key_type_arg, int bits_arg, int flags_arg, - data_t *method_data, + data_t *params_data, psa_status_t expected_status, data_t *expected_export) { @@ -9349,8 +9348,8 @@ void derive_key_ext(int alg_arg, const psa_algorithm_t alg = alg_arg; const psa_key_type_t key_type = key_type_arg; const size_t bits = bits_arg; - psa_key_generation_method_t *method = NULL; - size_t method_data_length = 0; + psa_key_production_parameters_t *params = NULL; + size_t params_data_length = 0; psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; const size_t export_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE(key_type, bits); @@ -9380,13 +9379,13 @@ void derive_key_ext(int alg_arg, psa_set_key_algorithm(&derived_attributes, 0); psa_set_key_type(&derived_attributes, key_type); psa_set_key_bits(&derived_attributes, bits); - if (!setup_key_generation_method(&method, &method_data_length, - flags_arg, method_data)) { + if (!setup_key_production_parameters(¶ms, ¶ms_data_length, + flags_arg, params_data)) { goto exit; } TEST_EQUAL(psa_key_derivation_output_key_ext(&derived_attributes, &operation, - method, method_data_length, + params, params_data_length, &derived_key), expected_status); @@ -9400,7 +9399,7 @@ void derive_key_ext(int alg_arg, exit: mbedtls_free(export_buffer); - mbedtls_free(method); + mbedtls_free(params); psa_key_derivation_abort(&operation); psa_destroy_key(base_key); psa_destroy_key(derived_key); @@ -9929,7 +9928,7 @@ void generate_key_ext(int type_arg, int usage_arg, int alg_arg, int flags_arg, - data_t *method_data, + data_t *params_data, int expected_status_arg) { mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; @@ -9939,8 +9938,8 @@ void generate_key_ext(int type_arg, psa_algorithm_t alg = alg_arg; psa_status_t expected_status = expected_status_arg; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_generation_method_t *method = NULL; - size_t method_data_length = 0; + psa_key_production_parameters_t *params = NULL; + size_t params_data_length = 0; psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; PSA_ASSERT(psa_crypto_init()); @@ -9950,14 +9949,14 @@ void generate_key_ext(int type_arg, psa_set_key_type(&attributes, type); psa_set_key_bits(&attributes, bits); - if (!setup_key_generation_method(&method, &method_data_length, - flags_arg, method_data)) { + if (!setup_key_production_parameters(¶ms, ¶ms_data_length, + flags_arg, params_data)) { goto exit; } /* Generate a key */ psa_status_t status = psa_generate_key_ext(&attributes, - method, method_data_length, + params, params_data_length, &key); TEST_EQUAL(status, expected_status); @@ -9972,7 +9971,7 @@ void generate_key_ext(int type_arg, #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE) if (type == PSA_KEY_TYPE_RSA_KEY_PAIR) { - TEST_ASSERT(rsa_test_e(key, bits, method_data)); + TEST_ASSERT(rsa_test_e(key, bits, params_data)); } #endif @@ -9987,17 +9986,17 @@ exit: * thus reset them as required. */ psa_reset_key_attributes(&got_attributes); - mbedtls_free(method); + mbedtls_free(params); psa_destroy_key(key); PSA_DONE(); } /* END_CASE */ /* BEGIN_CASE */ -void key_generation_method_init() +void key_production_parameters_init() { - psa_key_generation_method_t init = PSA_KEY_GENERATION_METHOD_INIT; - psa_key_generation_method_t zero; + psa_key_production_parameters_t init = PSA_KEY_PRODUCTION_PARAMETERS_INIT; + psa_key_production_parameters_t zero; memset(&zero, 0, sizeof(zero)); TEST_EQUAL(init.flags, 0); From 23605d19d9849c394dd4fe95cf0f84d94081651e Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Tue, 20 Feb 2024 17:10:56 +0100 Subject: [PATCH 11/11] More renaming: method -> production parameters Signed-off-by: Gilles Peskine --- include/psa/crypto.h | 3 ++- include/psa/crypto_types.h | 8 ++++---- tests/suites/test_suite_psa_crypto.data | 10 +++++----- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/psa/crypto.h b/include/psa/crypto.h index 18c783cef..e54af34c6 100644 --- a/include/psa/crypto.h +++ b/include/psa/crypto.h @@ -3782,7 +3782,8 @@ psa_status_t psa_key_derivation_output_key( * this function is equivalent to * psa_key_derivation_output_key(). * Mbed TLS currently only supports the default - * method, i.e. #PSA_KEY_PRODUCTION_PARAMETERS_INIT, + * production parameters, i.e. + * #PSA_KEY_PRODUCTION_PARAMETERS_INIT, * for all key types. * \param params_data_length * Length of `params->data` in bytes. diff --git a/include/psa/crypto_types.h b/include/psa/crypto_types.h index c5098073e..31ea68640 100644 --- a/include/psa/crypto_types.h +++ b/include/psa/crypto_types.h @@ -455,11 +455,11 @@ typedef uint64_t psa_key_slot_number_t; */ typedef uint16_t psa_key_derivation_step_t; -/** \brief Custom method for key generation or key derivation. +/** \brief Custom parameters for key generation or key derivation. * * This is a structure type with at least the following fields: * - * - \c flags: an unsigned integer type. 0 for the default method. + * - \c flags: an unsigned integer type. 0 for the default production parameters. * - \c data: a flexible array of bytes. * * The interpretation of this structure depend on the type of the @@ -472,8 +472,8 @@ typedef uint16_t psa_key_derivation_step_t; * Implementations must support 65535, should support 3 and may * support other values. * When not using a driver, Mbed TLS supports values up to \c INT_MAX. - * If this is empty or if the custom method is omitted altogether, - * the default value 65537 is used. + * If this is empty or if the custom production parameters are omitted + * altogether, the default value 65537 is used. * - Other key types: reserved for future use. \c flags must be 0. * */ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 8139469e9..e9570b1d6 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -6870,15 +6870,15 @@ PSA key derivation: PBKDF2-AES-CMAC-PRF-128-> AES-256 depends_on:PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128:PSA_WANT_ALG_CMAC:PSA_WANT_KEY_TYPE_AES:!MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH derive_key_type:PSA_ALG_PBKDF2_AES_CMAC_PRF_128:"706173737764":"01":"73616c74":PSA_KEY_TYPE_AES:256:"28e288c6345bb5ecf7ca70274208a3ba0f1148b5868537d5e09d3ee6813b1f52" -PSA key derivation: default method -> AES-128 +PSA key derivation: default params -> AES-128 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"":PSA_SUCCESS:"3cb25f25faacd57a90434f64d0362f2a" -PSA key derivation: method.flags=1 -> AES-128 +PSA key derivation: params.flags=1 -> AES-128 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:1:"":PSA_ERROR_INVALID_ARGUMENT:"" -PSA key derivation: method.data non-empty -> AES-128 +PSA key derivation: params.data non-empty -> AES-128 depends_on:PSA_WANT_ALG_HKDF:PSA_WANT_ALG_SHA_256:PSA_WANT_KEY_TYPE_AES derive_key_ext:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_AES:128:0:"2a":PSA_ERROR_INVALID_ARGUMENT:"" @@ -7473,7 +7473,7 @@ PSA generate key: FFDH, 1024 bits, invalid bits depends_on:PSA_WANT_ALG_FFDH:PSA_WANT_KEY_TYPE_DH_KEY_PAIR_GENERATE generate_key:PSA_KEY_TYPE_DH_KEY_PAIR(PSA_DH_FAMILY_RFC7919):1024:PSA_KEY_USAGE_EXPORT:PSA_ALG_FFDH:PSA_ERROR_NOT_SUPPORTED:0 -PSA generate key ext: RSA, method.flags=1 +PSA generate key ext: RSA, params.flags=1 depends_on:PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE generate_key_ext:PSA_KEY_TYPE_RSA_KEY_PAIR:PSA_VENDOR_RSA_GENERATE_MIN_KEY_BITS:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:0:1:"":PSA_ERROR_INVALID_ARGUMENT @@ -7546,7 +7546,7 @@ PSA generate key ext: ECC, flags=1 depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:1:"":PSA_ERROR_INVALID_ARGUMENT -PSA generate key ext: ECC, method.data non-empty +PSA generate key ext: ECC, params.data non-empty depends_on:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE:PSA_WANT_ECC_SECP_R1_256:PSA_WANT_ALG_ECDH generate_key_ext:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:0:"2a":PSA_ERROR_INVALID_ARGUMENT