Initialize MAC context in internal functions for one-shot MAC

In functions that bypass the API functions and call an internal MAC setup
function directly, make sure to initialize the driver-specific part of the
context. This is a union, and initializing the union to `{0}` only
guarantees that the first member of the union is initialized, not
necessarily the member used by the driver. Most compilers do initialize the
whole union to all-bits-zero, but some don't. With compilers that don't, the
lack of initialization caused failures of the affected operations. This
affected one-shot MAC operations using the built-in implementation.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c
index 8fe6218..7f625c5 100644
--- a/library/psa_crypto_mac.c
+++ b/library/psa_crypto_mac.c
@@ -465,6 +465,15 @@
 {
     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
+    /* Make sure the whole the operation is zeroed.
+     * PSA_MAC_OPERATION_INIT does not necessarily do it fully,
+     * since one field is a union and initializing a union does not
+     * necessarily initialize all of its members.
+     * In multipart operations, this is done in the API functions,
+     * before driver dispatch, since it needs to be done before calling
+     * the driver entry point. Here, we bypass the multipart API,
+     * so it's our job. */
+    memset(&operation, 0, sizeof(operation));
 
     status = psa_mac_setup(&operation,
                            attributes, key_buffer, key_buffer_size,