.. _macs:

Message authentication codes (MAC)
==================================

.. _mac-algorithms:

MAC algorithms
--------------

.. macro:: PSA_ALG_HMAC
    :definition: /* specification-defined value */

    .. summary::
        Macro to build an HMAC algorithm.

    .. param:: hash_alg
        A hash algorithm (``PSA_ALG_XXX`` value such that :code:`PSA_ALG_IS_HASH(hash_alg)` is true).

    .. return::
        The corresponding HMAC algorithm.

        Unspecified if ``hash_alg`` is not a supported hash algorithm.

    For example, :code:`PSA_ALG_HMAC(PSA_ALG_SHA_256)` is HMAC-SHA-256.

.. macro:: PSA_ALG_TRUNCATED_MAC
    :definition: /* specification-defined value */

    .. summary::
        Macro to build a truncated MAC algorithm.

    .. param:: mac_alg
        A MAC algorithm identifier (value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_MAC(alg)` is true). This can be a truncated or untruncated MAC algorithm.
    .. param:: mac_length
        Desired length of the truncated MAC in bytes. This must be at most the full length of the MAC and must be at least an implementation-specified minimum. The implementation-specified minimum must not be zero.

    .. return::
        The corresponding MAC algorithm with the specified length.

        Unspecified if ``alg`` is not a supported MAC algorithm or if ``mac_length`` is too small or too large for the specified MAC algorithm.

    A truncated MAC algorithm is identical to the corresponding MAC algorithm except that the MAC value for the truncated algorithm consists of only the first ``mac_length`` bytes of the MAC value for the untruncated algorithm.

    .. note::
        This macro might allow constructing algorithm identifiers that are not valid, either because the specified length is larger than the untruncated MAC or because the specified length is smaller than permitted by the implementation.

    .. note::
        It is implementation-defined whether a truncated MAC that is truncated to the same length as the MAC of the untruncated algorithm is considered identical to the untruncated algorithm for policy comparison purposes.

    The full-length MAC algorithm can be recovered using `PSA_ALG_FULL_LENGTH_MAC()`.

.. macro:: PSA_ALG_CBC_MAC
    :definition: ((psa_algorithm_t)0x03c00100)

    .. summary::
        The CBC-MAC construction over a block cipher.

    .. warning::
        CBC-MAC is insecure in many cases. A more secure mode, such as `PSA_ALG_CMAC`, is recommended.

.. macro:: PSA_ALG_CMAC
    :definition: ((psa_algorithm_t)0x03c00200)

    .. summary::
        The CMAC construction over a block cipher.

Single-part MAC functions
-------------------------

.. function:: psa_mac_compute

    .. summary::
        Calculate the message authentication code (MAC) of a message.

    .. param:: psa_key_id_t key
        Identifier of the key to use for the operation.
        It must allow the usage `PSA_KEY_USAGE_SIGN_MESSAGE`.
    .. param:: psa_algorithm_t alg
        The MAC algorithm to compute (``PSA_ALG_XXX`` value such that :code:`PSA_ALG_IS_MAC(alg)` is true).
    .. param:: const uint8_t * input
        Buffer containing the input message.
    .. param:: size_t input_length
        Size of the ``input`` buffer in bytes.
    .. param:: uint8_t * mac
        Buffer where the MAC value is to be written.
    .. param:: size_t mac_size
        Size of the ``mac`` buffer in bytes.
        This must be appropriate for the selected algorithm and key:

        * The exact MAC size is :code:`PSA_MAC_LENGTH(key_type, key_bits, alg)` where ``key_type`` and ``key_bits`` are attributes of the key used to compute the MAC.
        * `PSA_MAC_MAX_SIZE` evaluates to the maximum MAC size of any supported MAC algorithm.

    .. param:: size_t * mac_length
        On success, the number of bytes that make up the MAC value.

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        Success.
    .. retval:: PSA_ERROR_INVALID_HANDLE
    .. retval:: PSA_ERROR_NOT_PERMITTED
        The key does not have the `PSA_KEY_USAGE_SIGN_MESSAGE` flag, or it does not permit the requested algorithm.
    .. retval:: PSA_ERROR_INVALID_ARGUMENT
        ``key`` is not compatible with ``alg``.
    .. retval:: PSA_ERROR_NOT_SUPPORTED
        ``alg`` is not supported or is not a MAC algorithm.
    .. retval:: PSA_ERROR_BUFFER_TOO_SMALL
        The size of the ``mac`` buffer is too small.
        `PSA_MAC_LENGTH()` or `PSA_MAC_MAX_SIZE` can be used to determine the required buffer size.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_CORRUPT
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_INVALID
        The key could not be retrieved from storage.
    .. 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.

    .. note::
        To verify the MAC of a message against an expected value, use `psa_mac_verify()` instead. Beware that comparing integrity or authenticity data such as MAC values with a function such as ``memcmp()`` is risky because the time taken by the comparison might leak information about the MAC value which could allow an attacker to guess a valid MAC and thereby bypass security controls.

.. function:: psa_mac_verify

    .. summary::
        Calculate the MAC of a message and compare it with a reference value.

    .. param:: psa_key_id_t key
        Identifier of the key to use for the operation.
        It must allow the usage `PSA_KEY_USAGE_VERIFY_MESSAGE`.
    .. param:: psa_algorithm_t alg
        The MAC algorithm to compute (``PSA_ALG_XXX`` value such that :code:`PSA_ALG_IS_MAC(alg)` is true).
    .. param:: const uint8_t * input
        Buffer containing the input message.
    .. param:: size_t input_length
        Size of the ``input`` buffer in bytes.
    .. param:: const uint8_t * mac
        Buffer containing the expected MAC value.
    .. param:: size_t mac_length
        Size of the ``mac`` buffer in bytes.

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        The expected MAC is identical to the actual MAC of the input.
    .. retval:: PSA_ERROR_INVALID_SIGNATURE
        The MAC of the message was calculated successfully, but it differs from the expected value.
    .. retval:: PSA_ERROR_INVALID_HANDLE
    .. retval:: PSA_ERROR_NOT_PERMITTED
        The key does not have the `PSA_KEY_USAGE_VERIFY_MESSAGE` flag, or it does not permit the requested algorithm.
    .. retval:: PSA_ERROR_INVALID_ARGUMENT
        ``key`` is not compatible with ``alg``.
    .. retval:: PSA_ERROR_NOT_SUPPORTED
        ``alg`` is not supported or is not a MAC algorithm.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_CORRUPT
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_INVALID
        The key could not be retrieved from storage.
    .. 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.

Multi-part MAC operations
-------------------------

.. typedef:: /* implementation-defined type */ psa_mac_operation_t

    .. summary::
        The type of the state object for multi-part MAC operations.

    Before calling any function on a MAC operation object, the application must initialize it by any of the following means:

    * Set the object to all-bits-zero, for example:

      .. autocode::
          psa_mac_operation_t operation;
          memset(&operation, 0, sizeof(operation));

    * Initialize the object to logical zero values by declaring the object as static or global without an explicit initializer, for example:

      .. autocode::
          static psa_mac_operation_t operation;

    * Initialize the object to the initializer `PSA_MAC_OPERATION_INIT`, for example:

      .. autocode::
          psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;

    * Assign the result of the function `psa_mac_operation_init()` to the object, for example:

      .. autocode::
          psa_mac_operation_t operation;
          operation = psa_mac_operation_init();

    This is an implementation-defined type. Applications that make assumptions about the content of this object will result in in implementation-specific behavior, and are non-portable.

.. macro:: PSA_MAC_OPERATION_INIT
    :definition: /* implementation-defined value */

    .. summary::
        This macro returns a suitable initializer for a MAC operation object of type `psa_mac_operation_t`.

.. function:: psa_mac_operation_init

    .. summary::
        Return an initial value for a MAC operation object.

    .. return:: psa_mac_operation_t

.. function:: psa_mac_sign_setup

    .. summary::
        Set up a multi-part MAC calculation operation.

    .. param:: psa_mac_operation_t * operation
        The operation object to set up. It must have been initialized as per the documentation for `psa_mac_operation_t` and not yet in use.
    .. param:: psa_key_id_t key
        Identifier of the key to use for the operation. It must remain valid until the operation terminates.
        It must allow the usage `PSA_KEY_USAGE_SIGN_MESSAGE`.
    .. param:: psa_algorithm_t alg
        The MAC algorithm to compute (``PSA_ALG_XXX`` value such that :code:`PSA_ALG_IS_MAC(alg)` is true).

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        Success.
    .. retval:: PSA_ERROR_INVALID_HANDLE
    .. retval:: PSA_ERROR_NOT_PERMITTED
        The key does not have the `PSA_KEY_USAGE_SIGN_MESSAGE` flag, or it does not permit the requested algorithm.
    .. retval:: PSA_ERROR_INVALID_ARGUMENT
        ``key`` is not compatible with ``alg``.
    .. retval:: PSA_ERROR_NOT_SUPPORTED
        ``alg`` is not supported or is not a MAC algorithm.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_CORRUPT
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_INVALID
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_BAD_STATE
        The operation state is not valid: it must be inactive.
    .. 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.

    This function sets up the calculation of the message authentication code (MAC) of a byte string. To verify the MAC of a message against an expected value, use `psa_mac_verify_setup()` instead.

    The sequence of operations to calculate a MAC is as follows:

    #. Allocate an operation object which will be passed to all the functions listed here.
    #. Initialize the operation object with one of the methods described in the documentation for `psa_mac_operation_t`, e.g. `PSA_MAC_OPERATION_INIT`.
    #. Call `psa_mac_sign_setup()` to specify the algorithm and key.
    #. Call `psa_mac_update()` zero, one or more times, passing a fragment of the message each time. The MAC that is calculated is the MAC of the concatenation of these messages in order.
    #. At the end of the message, call `psa_mac_sign_finish()` to finish calculating the MAC value and retrieve it.

    If an error occurs at any step after a call to `psa_mac_sign_setup()`, the operation will need to be reset by a call to `psa_mac_abort()`. The application can call `psa_mac_abort()` at any time after the operation has been initialized.

    After a successful call to `psa_mac_sign_setup()`, the application must eventually terminate the operation through one of the following methods:

    * A successful call to `psa_mac_sign_finish()`.
    * A call to `psa_mac_abort()`.

.. function:: psa_mac_verify_setup

    .. summary::
        Set up a multi-part MAC verification operation.

    .. param:: psa_mac_operation_t * operation
        The operation object to set up. It must have been initialized as per the documentation for `psa_mac_operation_t` and not yet in use.
    .. param:: psa_key_id_t key
        Identifier of the key to use for the operation. It must remain valid until the operation terminates.
        It must allow the usage `PSA_KEY_USAGE_VERIFY_MESSAGE`.
    .. param:: psa_algorithm_t alg
        The MAC algorithm to compute (``PSA_ALG_XXX`` value such that :code:`PSA_ALG_IS_MAC(alg)` is true).

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        Success.
    .. retval:: PSA_ERROR_INVALID_HANDLE
    .. retval:: PSA_ERROR_NOT_PERMITTED
        The key does not have the `PSA_KEY_USAGE_VERIFY_MESSAGE` flag, or it does not permit the requested algorithm.
    .. retval:: PSA_ERROR_INVALID_ARGUMENT
        ``key`` is not compatible with ``alg``.
    .. retval:: PSA_ERROR_NOT_SUPPORTED
        ``alg`` is not supported or is not a MAC algorithm.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
        The key could not be retrieved from storage
    .. retval:: PSA_ERROR_DATA_CORRUPT
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_DATA_INVALID
        The key could not be retrieved from storage.
    .. retval:: PSA_ERROR_BAD_STATE
        The operation state is not valid: it must be inactive.
    .. 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.

    This function sets up the verification of the message authentication code (MAC) of a byte string against an expected value.

    The sequence of operations to verify a MAC is as follows:

    #. Allocate an operation object which will be passed to all the functions listed here.
    #. Initialize the operation object with one of the methods described in the documentation for `psa_mac_operation_t`, e.g. `PSA_MAC_OPERATION_INIT`.
    #. Call `psa_mac_verify_setup()` to specify the algorithm and key.
    #. Call `psa_mac_update()` zero, one or more times, passing a fragment of the message each time. The MAC that is calculated is the MAC of the concatenation of these messages in order.
    #. At the end of the message, call `psa_mac_verify_finish()` to finish calculating the actual MAC of the message and verify it against the expected value.

    If an error occurs at any step after a call to `psa_mac_verify_setup()`, the operation will need to be reset by a call to `psa_mac_abort()`. The application can call `psa_mac_abort()` at any time after the operation has been initialized.

    After a successful call to `psa_mac_verify_setup()`, the application must eventually terminate the operation through one of the following methods:

    * A successful call to `psa_mac_verify_finish()`.
    * A call to `psa_mac_abort()`.

.. function:: psa_mac_update

    .. summary::
        Add a message fragment to a multi-part MAC operation.

    .. param:: psa_mac_operation_t * operation
        Active MAC operation.
    .. param:: const uint8_t * input
        Buffer containing the message fragment to add to the MAC calculation.
    .. param:: size_t input_length
        Size of the ``input`` buffer in bytes.

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        Success.
    .. retval:: PSA_ERROR_BAD_STATE
        The operation state is not valid: it must be active.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
    .. retval:: PSA_ERROR_DATA_CORRUPT
    .. retval:: PSA_ERROR_DATA_INVALID
    .. 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.

    The application must call `psa_mac_sign_setup()` or `psa_mac_verify_setup()` before calling this function.

    If this function returns an error status, the operation enters an error state and must be aborted by calling `psa_mac_abort()`.

.. function:: psa_mac_sign_finish

    .. summary::
        Finish the calculation of the MAC of a message.

    .. param:: psa_mac_operation_t * operation
        Active MAC operation.
    .. param:: uint8_t * mac
        Buffer where the MAC value is to be written.
    .. param:: size_t mac_size
        Size of the ``mac`` buffer in bytes.
        This must be appropriate for the selected algorithm and key:

        * The exact MAC size is :code:`PSA_MAC_LENGTH(key_type, key_bits, alg)` where ``key_type`` and ``key_bits`` are attributes of the key, and ``alg`` is the algorithm used to compute the MAC.
        * `PSA_MAC_MAX_SIZE` evaluates to the maximum MAC size of any supported MAC algorithm.

    .. param:: size_t * mac_length
        On success, the number of bytes that make up the MAC value. This is always :code:`PSA_MAC_FINAL_SIZE(key_type, key_bits, alg)` where ``key_type`` and ``key_bits`` are the type and bit-size respectively of the key and ``alg`` is the MAC algorithm that is calculated.

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        Success.
    .. retval:: PSA_ERROR_BAD_STATE
        The operation state is not valid: it must be an active mac sign operation.
    .. retval:: PSA_ERROR_BUFFER_TOO_SMALL
        The size of the ``mac`` buffer is too small.
        `PSA_MAC_LENGTH()` or `PSA_MAC_MAX_SIZE` can be used to determine the required buffer size.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
    .. retval:: PSA_ERROR_DATA_CORRUPT
    .. retval:: PSA_ERROR_DATA_INVALID
    .. 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.

    The application must call `psa_mac_sign_setup()` before calling this function. This function calculates the MAC of the message formed by concatenating the inputs passed to preceding calls to `psa_mac_update()`.

    When this function returns successfully, the operation becomes inactive. If this function returns an error status, the operation enters an error state and must be aborted by calling `psa_mac_abort()`.

    .. warning::
        It is not recommended to use this function when a specific value is expected for the MAC. Call `psa_mac_verify_finish()` instead with the expected MAC value.

        Comparing integrity or authenticity data such as MAC values with a function such as ``memcmp()`` is risky because the time taken by the comparison might leak information about the hashed data which could allow an attacker to guess a valid MAC and thereby bypass security controls.

.. function:: psa_mac_verify_finish

    .. summary::
        Finish the calculation of the MAC of a message and compare it with an expected value.

    .. param:: psa_mac_operation_t * operation
        Active MAC operation.
    .. param:: const uint8_t * mac
        Buffer containing the expected MAC value.
    .. param:: size_t mac_length
        Size of the ``mac`` buffer in bytes.

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
        The expected MAC is identical to the actual MAC of the message.
    .. retval:: PSA_ERROR_INVALID_SIGNATURE
        The MAC of the message was calculated successfully, but it differs from the expected MAC.
    .. retval:: PSA_ERROR_BAD_STATE
        The operation state is not valid: it must be an active mac verify operation.
    .. retval:: PSA_ERROR_INSUFFICIENT_MEMORY
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. retval:: PSA_ERROR_STORAGE_FAILURE
    .. retval:: PSA_ERROR_DATA_CORRUPT
    .. retval:: PSA_ERROR_DATA_INVALID
    .. 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.

    The application must call `psa_mac_verify_setup()` before calling this function. This function calculates the MAC of the message formed by concatenating the inputs passed to preceding calls to `psa_mac_update()`. It then compares the calculated MAC with the expected MAC passed as a parameter to this function.

    When this function returns successfully, the operation becomes inactive. If this function returns an error status, the operation enters an error state and must be aborted by calling `psa_mac_abort()`.

    .. note::
        Implementations must make the best effort to ensure that the comparison between the actual MAC and the expected MAC is performed in constant time.

.. function:: psa_mac_abort

    .. summary::
        Abort a MAC operation.

    .. param:: psa_mac_operation_t * operation
        Initialized MAC operation.

    .. return:: psa_status_t
    .. retval:: PSA_SUCCESS
    .. retval:: PSA_ERROR_COMMUNICATION_FAILURE
    .. retval:: PSA_ERROR_HARDWARE_FAILURE
    .. retval:: PSA_ERROR_CORRUPTION_DETECTED
    .. 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.

    Aborting an operation frees all associated resources except for the ``operation`` object itself. Once aborted, the operation object can be reused for another operation by calling `psa_mac_sign_setup()` or `psa_mac_verify_setup()` again.

    This function can be called any time after the operation object has been initialized by one of the methods described in `psa_mac_operation_t`.

    In particular, calling `psa_mac_abort()` after the operation has been terminated by a call to `psa_mac_abort()`, `psa_mac_sign_finish()` or `psa_mac_verify_finish()` is safe and has no effect.

Support macros
--------------

.. macro:: PSA_ALG_IS_HMAC
    :definition: /* specification-defined value */

    .. summary::
        Whether the specified algorithm is an HMAC algorithm.

    .. param:: alg
        An algorithm identifier (value of type `psa_algorithm_t`).

    .. return::
        ``1`` if ``alg`` is an HMAC algorithm, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier.

    HMAC is a family of MAC algorithms that are based on a hash function.

.. macro:: PSA_ALG_IS_BLOCK_CIPHER_MAC
    :definition: /* specification-defined value */

    .. summary::
        Whether the specified algorithm is a MAC algorithm based on a block cipher.

    .. param:: alg
        An algorithm identifier (value of type `psa_algorithm_t`).

    .. return::
        ``1`` if ``alg`` is a MAC algorithm based on a block cipher, ``0`` otherwise. This macro can return either ``0`` or ``1`` if ``alg`` is not a supported algorithm identifier.

.. macro:: PSA_ALG_FULL_LENGTH_MAC
    :definition: /* specification-defined value */

    .. summary::
        Macro to construct the MAC algorithm with a full length MAC, from a truncated MAC algorithm.

    .. param:: mac_alg
        A MAC algorithm identifier (value of type `psa_algorithm_t` such that :code:`PSA_ALG_IS_MAC(alg)` is true). This can be a truncated or untruncated MAC algorithm.

    .. return::
        The corresponding MAC algorithm with a full length MAC.

        Unspecified if ``alg`` is not a supported MAC algorithm.

.. macro:: PSA_MAC_LENGTH
    :definition: /* implementation-defined value */

    .. summary::
        The size of the output of `psa_mac_compute()` and `psa_mac_sign_finish()`, in bytes.

    .. param:: key_type
        The type of the MAC key.
    .. param:: key_bits
        The size of the MAC key in bits.
    .. param:: alg
        A MAC algorithm (``PSA_ALG_XXX`` value such that :code:`PSA_ALG_IS_MAC(alg)` is true).

    .. return::
        The MAC length for the specified algorithm with the specified key parameters.

        ``0`` if the MAC algorithm is not recognized.

        Either ``0`` or the correct length for a MAC algorithm that the implementation recognizes, but does not support.

        Unspecified if the key parameters are not consistent with the algorithm.

    This is also the MAC length that `psa_mac_verify()` and `psa_mac_verify_finish()` expects.

    See also `PSA_MAC_MAX_SIZE`.

.. macro:: PSA_MAC_MAX_SIZE
    :definition: /* implementation-defined value */

    .. summary::
        Maximum size of a MAC.

    This macro must expand to a compile-time constant integer.
    It is recommended that this value is the maximum size of a MAC supported by the implementation, in bytes. The value must not be smaller than this maximum.

    See also `PSA_MAC_LENGTH()`.
