LCOV - code coverage report
Current view: top level - externals/mbedtls/library - psa_crypto_mac.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 69.6 % 135 94
Test Date: 2026-03-12 12:01:18 Functions: 71.4 % 14 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 35.7 % 84 30

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  *  PSA MAC layer on top of Mbed TLS software crypto
       3                 :             :  */
       4                 :             : /*
       5                 :             :  *  Copyright The Mbed TLS Contributors
       6                 :             :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       7                 :             :  */
       8                 :             : 
       9                 :             : #include "common.h"
      10                 :             : 
      11                 :             : #if defined(MBEDTLS_PSA_CRYPTO_C)
      12                 :             : 
      13                 :             : #include <psa/crypto.h>
      14                 :             : #include "psa_crypto_core.h"
      15                 :             : #include "psa_crypto_cipher.h"
      16                 :             : #include "psa_crypto_mac.h"
      17                 :             : #include <mbedtls/md.h>
      18                 :             : 
      19                 :             : #include <mbedtls/error.h>
      20                 :             : #include "mbedtls/constant_time.h"
      21                 :             : #include <string.h>
      22                 :             : 
      23                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
      24                 :         154 : static psa_status_t psa_hmac_abort_internal(
      25                 :             :     mbedtls_psa_hmac_operation_t *hmac)
      26                 :             : {
      27                 :         154 :     mbedtls_platform_zeroize(hmac->opad, sizeof(hmac->opad));
      28                 :         154 :     return psa_hash_abort(&hmac->hash_ctx);
      29                 :             : }
      30                 :             : 
      31                 :         154 : static psa_status_t psa_hmac_setup_internal(
      32                 :             :     mbedtls_psa_hmac_operation_t *hmac,
      33                 :             :     const uint8_t *key,
      34                 :             :     size_t key_length,
      35                 :             :     psa_algorithm_t hash_alg)
      36                 :             : {
      37                 :         154 :     uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
      38                 :         154 :     size_t i;
      39         [ -  + ]:         154 :     size_t hash_size = PSA_HASH_LENGTH(hash_alg);
      40   [ -  -  -  -  :         154 :     size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
          +  -  -  -  -  
             -  -  -  -  
                      - ]
      41                 :         154 :     psa_status_t status;
      42                 :             : 
      43                 :         154 :     hmac->alg = hash_alg;
      44                 :             : 
      45                 :             :     /* Sanity checks on block_size, to guarantee that there won't be a buffer
      46                 :             :      * overflow below. This should never trigger if the hash algorithm
      47                 :             :      * is implemented correctly. */
      48                 :             :     /* The size checks against the ipad and opad buffers cannot be written
      49                 :             :      * `block_size > sizeof( ipad ) || block_size > sizeof( hmac->opad )`
      50                 :             :      * because that triggers -Wlogical-op on GCC 7.3. */
      51         [ -  - ]:         154 :     if (block_size > sizeof(ipad)) {
      52                 :           0 :         return PSA_ERROR_NOT_SUPPORTED;
      53                 :             :     }
      54                 :         154 :     if (block_size > sizeof(hmac->opad)) {
      55                 :             :         return PSA_ERROR_NOT_SUPPORTED;
      56                 :             :     }
      57         [ -  + ]:         154 :     if (block_size < hash_size) {
      58                 :             :         return PSA_ERROR_NOT_SUPPORTED;
      59                 :             :     }
      60                 :             : 
      61         [ -  + ]:         154 :     if (key_length > block_size) {
      62                 :           0 :         status = psa_hash_compute(hash_alg, key, key_length,
      63                 :             :                                   ipad, sizeof(ipad), &key_length);
      64         [ #  # ]:           0 :         if (status != PSA_SUCCESS) {
      65                 :           0 :             goto cleanup;
      66                 :             :         }
      67                 :             :     }
      68                 :             :     /* A 0-length key is not commonly used in HMAC when used as a MAC,
      69                 :             :      * but it is permitted. It is common when HMAC is used in HKDF, for
      70                 :             :      * example. Don't call `memcpy` in the 0-length because `key` could be
      71                 :             :      * an invalid pointer which would make the behavior undefined. */
      72         [ +  - ]:         154 :     else if (key_length != 0) {
      73                 :         154 :         memcpy(ipad, key, key_length);
      74                 :             :     }
      75                 :             : 
      76                 :             :     /* ipad contains the key followed by garbage. Xor and fill with 0x36
      77                 :             :      * to create the ipad value. */
      78         [ +  + ]:        4434 :     for (i = 0; i < key_length; i++) {
      79                 :        4280 :         ipad[i] ^= 0x36;
      80                 :             :     }
      81                 :         154 :     memset(ipad + key_length, 0x36, block_size - key_length);
      82                 :             : 
      83                 :             :     /* Copy the key material from ipad to opad, flipping the requisite bits,
      84                 :             :      * and filling the rest of opad with the requisite constant. */
      85         [ +  + ]:        4434 :     for (i = 0; i < key_length; i++) {
      86                 :        4280 :         hmac->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
      87                 :             :     }
      88                 :         154 :     memset(hmac->opad + key_length, 0x5C, block_size - key_length);
      89                 :             : 
      90                 :         154 :     status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
      91         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
      92                 :           0 :         goto cleanup;
      93                 :             :     }
      94                 :             : 
      95                 :         154 :     status = psa_hash_update(&hmac->hash_ctx, ipad, block_size);
      96                 :             : 
      97                 :         154 : cleanup:
      98                 :         154 :     mbedtls_platform_zeroize(ipad, sizeof(ipad));
      99                 :             : 
     100                 :         154 :     return status;
     101                 :             : }
     102                 :             : 
     103                 :         154 : static psa_status_t psa_hmac_update_internal(
     104                 :             :     mbedtls_psa_hmac_operation_t *hmac,
     105                 :             :     const uint8_t *data,
     106                 :             :     size_t data_length)
     107                 :             : {
     108                 :         154 :     return psa_hash_update(&hmac->hash_ctx, data, data_length);
     109                 :             : }
     110                 :             : 
     111                 :         154 : static psa_status_t psa_hmac_finish_internal(
     112                 :             :     mbedtls_psa_hmac_operation_t *hmac,
     113                 :             :     uint8_t *mac,
     114                 :             :     size_t mac_size)
     115                 :             : {
     116                 :         154 :     uint8_t tmp[PSA_HASH_MAX_SIZE];
     117                 :         154 :     psa_algorithm_t hash_alg = hmac->alg;
     118                 :         154 :     size_t hash_size = 0;
     119         [ -  + ]:         154 :     size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
     120                 :         154 :     psa_status_t status;
     121                 :             : 
     122                 :         154 :     status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
     123         [ +  - ]:         154 :     if (status != PSA_SUCCESS) {
     124                 :             :         return status;
     125                 :             :     }
     126                 :             :     /* From here on, tmp needs to be wiped. */
     127                 :             : 
     128                 :         154 :     status = psa_hash_setup(&hmac->hash_ctx, hash_alg);
     129         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
     130                 :           0 :         goto exit;
     131                 :             :     }
     132                 :             : 
     133                 :         154 :     status = psa_hash_update(&hmac->hash_ctx, hmac->opad, block_size);
     134         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
     135                 :           0 :         goto exit;
     136                 :             :     }
     137                 :             : 
     138                 :         154 :     status = psa_hash_update(&hmac->hash_ctx, tmp, hash_size);
     139         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
     140                 :           0 :         goto exit;
     141                 :             :     }
     142                 :             : 
     143                 :         154 :     status = psa_hash_finish(&hmac->hash_ctx, tmp, sizeof(tmp), &hash_size);
     144         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
     145                 :           0 :         goto exit;
     146                 :             :     }
     147                 :             : 
     148                 :         154 :     memcpy(mac, tmp, mac_size);
     149                 :             : 
     150                 :         154 : exit:
     151                 :         154 :     mbedtls_platform_zeroize(tmp, hash_size);
     152                 :         154 :     return status;
     153                 :             : }
     154                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
     155                 :             : 
     156                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     157                 :             : static psa_status_t cmac_setup(mbedtls_psa_mac_operation_t *operation,
     158                 :             :                                const psa_key_attributes_t *attributes,
     159                 :             :                                const uint8_t *key_buffer)
     160                 :             : {
     161                 :             :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     162                 :             : 
     163                 :             : #if defined(PSA_WANT_KEY_TYPE_DES)
     164                 :             :     /* Mbed TLS CMAC does not accept 3DES with only two keys, nor does it accept
     165                 :             :      * to do CMAC with pure DES, so return NOT_SUPPORTED here. */
     166                 :             :     if (psa_get_key_type(attributes) == PSA_KEY_TYPE_DES &&
     167                 :             :         (psa_get_key_bits(attributes) == 64 ||
     168                 :             :          psa_get_key_bits(attributes) == 128)) {
     169                 :             :         return PSA_ERROR_NOT_SUPPORTED;
     170                 :             :     }
     171                 :             : #endif
     172                 :             : 
     173                 :             :     const mbedtls_cipher_info_t *cipher_info =
     174                 :             :         mbedtls_cipher_info_from_psa(
     175                 :             :             PSA_ALG_CMAC,
     176                 :             :             psa_get_key_type(attributes),
     177                 :             :             psa_get_key_bits(attributes),
     178                 :             :             NULL);
     179                 :             : 
     180                 :             :     if (cipher_info == NULL) {
     181                 :             :         return PSA_ERROR_NOT_SUPPORTED;
     182                 :             :     }
     183                 :             : 
     184                 :             :     ret = mbedtls_cipher_setup(&operation->ctx.cmac, cipher_info);
     185                 :             :     if (ret != 0) {
     186                 :             :         goto exit;
     187                 :             :     }
     188                 :             : 
     189                 :             :     ret = mbedtls_cipher_cmac_starts(&operation->ctx.cmac,
     190                 :             :                                      key_buffer,
     191                 :             :                                      psa_get_key_bits(attributes));
     192                 :             : exit:
     193                 :             :     return mbedtls_to_psa_error(ret);
     194                 :             : }
     195                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     196                 :             : 
     197                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC) || \
     198                 :             :     defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     199                 :             : 
     200                 :             : /* Initialize this driver's MAC operation structure. Once this function has been
     201                 :             :  * called, mbedtls_psa_mac_abort can run and will do the right thing. */
     202                 :         154 : static psa_status_t mac_init(
     203                 :             :     mbedtls_psa_mac_operation_t *operation,
     204                 :             :     psa_algorithm_t alg)
     205                 :             : {
     206                 :         154 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     207                 :             : 
     208                 :         154 :     operation->alg = alg;
     209                 :             : 
     210                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     211                 :             :     if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
     212                 :             :         mbedtls_cipher_init(&operation->ctx.cmac);
     213                 :             :         status = PSA_SUCCESS;
     214                 :             :     } else
     215                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     216                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
     217         [ +  - ]:         154 :     if (PSA_ALG_IS_HMAC(operation->alg)) {
     218                 :             :         /* We'll set up the hash operation later in psa_hmac_setup_internal. */
     219                 :         154 :         operation->ctx.hmac.alg = 0;
     220                 :         154 :         status = PSA_SUCCESS;
     221                 :             :     } else
     222                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
     223                 :             :     {
     224                 :             :         (void) operation;
     225                 :             :         status = PSA_ERROR_NOT_SUPPORTED;
     226                 :             :     }
     227                 :             : 
     228                 :         154 :     if (status != PSA_SUCCESS) {
     229                 :           0 :         memset(operation, 0, sizeof(*operation));
     230                 :             :     }
     231                 :         154 :     return status;
     232                 :             : }
     233                 :             : 
     234                 :         154 : psa_status_t mbedtls_psa_mac_abort(mbedtls_psa_mac_operation_t *operation)
     235                 :             : {
     236         [ -  + ]:         154 :     if (operation->alg == 0) {
     237                 :             :         /* The object has (apparently) been initialized but it is not
     238                 :             :          * in use. It's ok to call abort on such an object, and there's
     239                 :             :          * nothing to do. */
     240                 :             :         return PSA_SUCCESS;
     241                 :             :     } else
     242                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     243                 :             :     if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
     244                 :             :         mbedtls_cipher_free(&operation->ctx.cmac);
     245                 :             :     } else
     246                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     247                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
     248         [ +  - ]:         154 :     if (PSA_ALG_IS_HMAC(operation->alg)) {
     249                 :         154 :         psa_hmac_abort_internal(&operation->ctx.hmac);
     250                 :             :     } else
     251                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
     252                 :             :     {
     253                 :             :         /* Sanity check (shouldn't happen: operation->alg should
     254                 :             :          * always have been initialized to a valid value). */
     255                 :           0 :         goto bad_state;
     256                 :             :     }
     257                 :             : 
     258                 :         154 :     operation->alg = 0;
     259                 :             : 
     260                 :         154 :     return PSA_SUCCESS;
     261                 :             : 
     262                 :           0 : bad_state:
     263                 :             :     /* If abort is called on an uninitialized object, we can't trust
     264                 :             :      * anything. Wipe the object in case it contains confidential data.
     265                 :             :      * This may result in a memory leak if a pointer gets overwritten,
     266                 :             :      * but it's too late to do anything about this. */
     267                 :           0 :     memset(operation, 0, sizeof(*operation));
     268                 :           0 :     return PSA_ERROR_BAD_STATE;
     269                 :             : }
     270                 :             : 
     271                 :         154 : static psa_status_t psa_mac_setup(mbedtls_psa_mac_operation_t *operation,
     272                 :             :                                   const psa_key_attributes_t *attributes,
     273                 :             :                                   const uint8_t *key_buffer,
     274                 :             :                                   size_t key_buffer_size,
     275                 :             :                                   psa_algorithm_t alg)
     276                 :             : {
     277                 :         154 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     278                 :             : 
     279                 :             :     /* A context must be freshly initialized before it can be set up. */
     280         [ +  - ]:         154 :     if (operation->alg != 0) {
     281                 :             :         return PSA_ERROR_BAD_STATE;
     282                 :             :     }
     283                 :             : 
     284                 :         154 :     status = mac_init(operation, alg);
     285         [ +  - ]:         154 :     if (status != PSA_SUCCESS) {
     286                 :             :         return status;
     287                 :             :     }
     288                 :             : 
     289                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     290                 :             :     if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
     291                 :             :         /* Key buffer size for CMAC is dictated by the key bits set on the
     292                 :             :          * attributes, and previously validated by the core on key import. */
     293                 :             :         (void) key_buffer_size;
     294                 :             :         status = cmac_setup(operation, attributes, key_buffer);
     295                 :             :     } else
     296                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     297                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
     298         [ +  - ]:         154 :     if (PSA_ALG_IS_HMAC(alg)) {
     299                 :         154 :         status = psa_hmac_setup_internal(&operation->ctx.hmac,
     300                 :             :                                          key_buffer,
     301                 :             :                                          key_buffer_size,
     302                 :         154 :                                          PSA_ALG_HMAC_GET_HASH(alg));
     303                 :             :     } else
     304                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
     305                 :             :     {
     306                 :             :         (void) attributes;
     307                 :             :         (void) key_buffer;
     308                 :             :         (void) key_buffer_size;
     309                 :             :         status = PSA_ERROR_NOT_SUPPORTED;
     310                 :             :     }
     311                 :             : 
     312         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
     313                 :           0 :         mbedtls_psa_mac_abort(operation);
     314                 :             :     }
     315                 :             : 
     316                 :             :     return status;
     317                 :             : }
     318                 :             : 
     319                 :           0 : psa_status_t mbedtls_psa_mac_sign_setup(
     320                 :             :     mbedtls_psa_mac_operation_t *operation,
     321                 :             :     const psa_key_attributes_t *attributes,
     322                 :             :     const uint8_t *key_buffer,
     323                 :             :     size_t key_buffer_size,
     324                 :             :     psa_algorithm_t alg)
     325                 :             : {
     326                 :           0 :     return psa_mac_setup(operation, attributes,
     327                 :             :                          key_buffer, key_buffer_size, alg);
     328                 :             : }
     329                 :             : 
     330                 :           0 : psa_status_t mbedtls_psa_mac_verify_setup(
     331                 :             :     mbedtls_psa_mac_operation_t *operation,
     332                 :             :     const psa_key_attributes_t *attributes,
     333                 :             :     const uint8_t *key_buffer,
     334                 :             :     size_t key_buffer_size,
     335                 :             :     psa_algorithm_t alg)
     336                 :             : {
     337                 :           0 :     return psa_mac_setup(operation, attributes,
     338                 :             :                          key_buffer, key_buffer_size, alg);
     339                 :             : }
     340                 :             : 
     341                 :         154 : psa_status_t mbedtls_psa_mac_update(
     342                 :             :     mbedtls_psa_mac_operation_t *operation,
     343                 :             :     const uint8_t *input,
     344                 :             :     size_t input_length)
     345                 :             : {
     346         [ +  - ]:         154 :     if (operation->alg == 0) {
     347                 :             :         return PSA_ERROR_BAD_STATE;
     348                 :             :     }
     349                 :             : 
     350                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     351                 :             :     if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
     352                 :             :         return mbedtls_to_psa_error(
     353                 :             :             mbedtls_cipher_cmac_update(&operation->ctx.cmac,
     354                 :             :                                        input, input_length));
     355                 :             :     } else
     356                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     357                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
     358         [ +  - ]:         154 :     if (PSA_ALG_IS_HMAC(operation->alg)) {
     359                 :         154 :         return psa_hmac_update_internal(&operation->ctx.hmac,
     360                 :             :                                         input, input_length);
     361                 :             :     } else
     362                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
     363                 :             :     {
     364                 :             :         /* This shouldn't happen if `operation` was initialized by
     365                 :             :          * a setup function. */
     366                 :             :         (void) input;
     367                 :             :         (void) input_length;
     368                 :             :         return PSA_ERROR_BAD_STATE;
     369                 :             :     }
     370                 :             : }
     371                 :             : 
     372                 :         154 : static psa_status_t psa_mac_finish_internal(
     373                 :             :     mbedtls_psa_mac_operation_t *operation,
     374                 :             :     uint8_t *mac, size_t mac_size)
     375                 :             : {
     376                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_CMAC)
     377                 :             :     if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
     378                 :             :         uint8_t tmp[PSA_BLOCK_CIPHER_BLOCK_MAX_SIZE];
     379                 :             :         int ret = mbedtls_cipher_cmac_finish(&operation->ctx.cmac, tmp);
     380                 :             :         if (ret == 0) {
     381                 :             :             memcpy(mac, tmp, mac_size);
     382                 :             :         }
     383                 :             :         mbedtls_platform_zeroize(tmp, sizeof(tmp));
     384                 :             :         return mbedtls_to_psa_error(ret);
     385                 :             :     } else
     386                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     387                 :             : #if defined(MBEDTLS_PSA_BUILTIN_ALG_HMAC)
     388         [ +  - ]:         154 :     if (PSA_ALG_IS_HMAC(operation->alg)) {
     389                 :         154 :         return psa_hmac_finish_internal(&operation->ctx.hmac,
     390                 :             :                                         mac, mac_size);
     391                 :             :     } else
     392                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC */
     393                 :             :     {
     394                 :             :         /* This shouldn't happen if `operation` was initialized by
     395                 :             :          * a setup function. */
     396                 :             :         (void) operation;
     397                 :             :         (void) mac;
     398                 :             :         (void) mac_size;
     399                 :             :         return PSA_ERROR_BAD_STATE;
     400                 :             :     }
     401                 :             : }
     402                 :             : 
     403                 :           0 : psa_status_t mbedtls_psa_mac_sign_finish(
     404                 :             :     mbedtls_psa_mac_operation_t *operation,
     405                 :             :     uint8_t *mac,
     406                 :             :     size_t mac_size,
     407                 :             :     size_t *mac_length)
     408                 :             : {
     409                 :           0 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     410                 :             : 
     411         [ #  # ]:           0 :     if (operation->alg == 0) {
     412                 :             :         return PSA_ERROR_BAD_STATE;
     413                 :             :     }
     414                 :             : 
     415                 :           0 :     status = psa_mac_finish_internal(operation, mac, mac_size);
     416         [ #  # ]:           0 :     if (status == PSA_SUCCESS) {
     417                 :           0 :         *mac_length = mac_size;
     418                 :             :     }
     419                 :             : 
     420                 :             :     return status;
     421                 :             : }
     422                 :             : 
     423                 :           0 : psa_status_t mbedtls_psa_mac_verify_finish(
     424                 :             :     mbedtls_psa_mac_operation_t *operation,
     425                 :             :     const uint8_t *mac,
     426                 :             :     size_t mac_length)
     427                 :             : {
     428                 :           0 :     uint8_t actual_mac[PSA_MAC_MAX_SIZE];
     429                 :           0 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     430                 :             : 
     431         [ #  # ]:           0 :     if (operation->alg == 0) {
     432                 :             :         return PSA_ERROR_BAD_STATE;
     433                 :             :     }
     434                 :             : 
     435                 :             :     /* Consistency check: requested MAC length fits our local buffer */
     436         [ #  # ]:           0 :     if (mac_length > sizeof(actual_mac)) {
     437                 :             :         return PSA_ERROR_INVALID_ARGUMENT;
     438                 :             :     }
     439                 :             : 
     440                 :           0 :     status = psa_mac_finish_internal(operation, actual_mac, mac_length);
     441         [ #  # ]:           0 :     if (status != PSA_SUCCESS) {
     442                 :           0 :         goto cleanup;
     443                 :             :     }
     444                 :             : 
     445         [ #  # ]:           0 :     if (mbedtls_ct_memcmp(mac, actual_mac, mac_length) != 0) {
     446                 :           0 :         status = PSA_ERROR_INVALID_SIGNATURE;
     447                 :             :     }
     448                 :             : 
     449                 :           0 : cleanup:
     450                 :           0 :     mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
     451                 :             : 
     452                 :           0 :     return status;
     453                 :             : }
     454                 :             : 
     455                 :         154 : psa_status_t mbedtls_psa_mac_compute(
     456                 :             :     const psa_key_attributes_t *attributes,
     457                 :             :     const uint8_t *key_buffer,
     458                 :             :     size_t key_buffer_size,
     459                 :             :     psa_algorithm_t alg,
     460                 :             :     const uint8_t *input,
     461                 :             :     size_t input_length,
     462                 :             :     uint8_t *mac,
     463                 :             :     size_t mac_size,
     464                 :             :     size_t *mac_length)
     465                 :             : {
     466                 :         154 :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
     467                 :         154 :     mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT;
     468                 :             :     /* Make sure the whole operation is zeroed.
     469                 :             :      * PSA_MAC_OPERATION_INIT does not necessarily do it fully,
     470                 :             :      * since one field is a union and initializing a union does not
     471                 :             :      * necessarily initialize all of its members.
     472                 :             :      * In multipart operations, this is done in the API functions,
     473                 :             :      * before driver dispatch, since it needs to be done before calling
     474                 :             :      * the driver entry point. Here, we bypass the multipart API,
     475                 :             :      * so it's our job. */
     476                 :         154 :     memset(&operation, 0, sizeof(operation));
     477                 :             : 
     478                 :         154 :     status = psa_mac_setup(&operation,
     479                 :             :                            attributes, key_buffer, key_buffer_size,
     480                 :             :                            alg);
     481         [ -  + ]:         154 :     if (status != PSA_SUCCESS) {
     482                 :           0 :         goto exit;
     483                 :             :     }
     484                 :             : 
     485         [ +  - ]:         154 :     if (input_length > 0) {
     486                 :         154 :         status = mbedtls_psa_mac_update(&operation, input, input_length);
     487         [ -  + ]:         154 :         if (status != PSA_SUCCESS) {
     488                 :           0 :             goto exit;
     489                 :             :         }
     490                 :             :     }
     491                 :             : 
     492                 :         154 :     status = psa_mac_finish_internal(&operation, mac, mac_size);
     493         [ -  + ]:         154 :     if (status == PSA_SUCCESS) {
     494                 :         154 :         *mac_length = mac_size;
     495                 :             :     }
     496                 :             : 
     497                 :           0 : exit:
     498                 :         154 :     mbedtls_psa_mac_abort(&operation);
     499                 :             : 
     500                 :         154 :     return status;
     501                 :             : }
     502                 :             : 
     503                 :             : #endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || MBEDTLS_PSA_BUILTIN_ALG_CMAC */
     504                 :             : 
     505                 :             : #endif /* MBEDTLS_PSA_CRYPTO_C */
        

Generated by: LCOV version 2.0-1