Short initializers for multipart operation structures

For each multipart or interruptible operation, define an initializer
function that simulates the minimum that `my_op_t op = {0}` guarantees in C.
That is, initialize most fields to 0, but set the fields that are unions to
a nonzero value. This simulates platforms where initializing a union to
`{0}` only initializes the first member, and thus reading from another
member can yield a nonzero value. In our operation structures, the union's
first member is an unused `dummy`, and the other members are
driver-specific, so we just make the whole union nonzero and this has to be
good enough for the setup functions in the core to cope.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine
2025-02-05 18:54:26 +01:00
parent 2000db4295
commit bdccf4178f
2 changed files with 117 additions and 0 deletions
+29
View File
@@ -145,6 +145,35 @@ const char *mbedtls_test_helper_is_psa_leaking(void);
while (0)
/** Initializer that doesn't set the embedded union to zero.
*
* Use this to validate that our code correctly handles platforms where
* `{0}` does not initialize a union to all-bits-zero, only the first member.
* Such behavior is uncommon, but compliant (see discussion in
* https://github.com/Mbed-TLS/mbedtls/issues/9814).
* You can portably simulate that behavior by using the `xxx_init_short()`
* initializer function instead of `{0}` or an official initializer
* `xxx_init()` or `XXX_INIT`.
*/
psa_hash_operation_t psa_hash_operation_init_short(void);
psa_mac_operation_t psa_mac_operation_init_short(void);
psa_cipher_operation_t psa_cipher_operation_init_short(void);
psa_aead_operation_t psa_aead_operation_init_short(void);
psa_key_derivation_operation_t psa_key_derivation_operation_init_short(void);
psa_pake_operation_t psa_pake_operation_init_short(void);
psa_sign_hash_interruptible_operation_t psa_sign_hash_interruptible_operation_init_short(void);
psa_verify_hash_interruptible_operation_t psa_verify_hash_interruptible_operation_init_short(void);
#if defined(PSA_KEY_AGREEMENT_IOP_INIT)
psa_key_agreement_iop_t psa_key_agreement_iop_init_short(void);
#endif
#if defined(PSA_GENERATE_KEY_IOP_INIT)
psa_generate_key_iop_t psa_generate_key_iop_init_short(void);
#endif
#if defined(PSA_EXPORT_PUBLIC_KEY_IOP_INIT)
psa_export_public_key_iop_t psa_export_public_key_iop_init_short(void);
#endif
#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
psa_status_t mbedtls_test_record_status(psa_status_t status,
+88
View File
@@ -98,6 +98,94 @@ const char *mbedtls_test_helper_is_psa_leaking(void)
return NULL;
}
psa_hash_operation_t psa_hash_operation_init_short(void)
{
psa_hash_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
psa_mac_operation_t psa_mac_operation_init_short(void)
{
psa_mac_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
psa_cipher_operation_t psa_cipher_operation_init_short(void)
{
psa_cipher_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
psa_aead_operation_t psa_aead_operation_init_short(void)
{
psa_aead_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
psa_key_derivation_operation_t psa_key_derivation_operation_init_short(void)
{
psa_key_derivation_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
psa_pake_operation_t psa_pake_operation_init_short(void)
{
psa_pake_operation_t operation = {0};
memset(&operation.computation_stage, '!', sizeof(operation.computation_stage));
memset(&operation.data, '!', sizeof(operation.data));
return operation;
}
psa_sign_hash_interruptible_operation_t psa_sign_hash_interruptible_operation_init_short(void)
{
psa_sign_hash_interruptible_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
psa_verify_hash_interruptible_operation_t psa_verify_hash_interruptible_operation_init_short(void)
{
psa_verify_hash_interruptible_operation_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
#if defined(PSA_KEY_AGREEMENT_IOP_INIT)
psa_key_agreement_iop_t psa_key_agreement_iop_init_short(void)
{
psa_key_agreement_iop_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
#endif
#if defined(PSA_GENERATE_KEY_IOP_INIT)
psa_generate_key_iop_t psa_generate_key_iop_init_short(void)
{
psa_generate_key_iop_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
#endif
#if defined(PSA_EXPORT_PUBLIC_KEY_IOP_INIT)
psa_export_public_key_iop_t psa_export_public_key_iop_init_short(void)
{
psa_export_public_key_iop_t operation = {0};
memset(&operation.ctx, '!', sizeof(operation.ctx));
return operation;
}
#endif
#if defined(RECORD_PSA_STATUS_COVERAGE_LOG)
/** Name of the file where return statuses are logged by #RECORD_STATUS. */
#define STATUS_LOG_FILE_NAME "statuses.log"