1 /*
2  * Copyright (c) 2023, The TrustedFirmware-M Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef __CC3XX_HMAC_H__
9 #define __CC3XX_HMAC_H__
10 
11 #include <stdint.h>
12 #include "cc3xx_error.h"
13 #include "cc3xx_hash.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief The size in Bytes, i.e. B, associated to the HMAC block size
21  *
22  */
23 #define CC3XX_HMAC_BLOCK_SIZE (64)
24 
25 /**
26  * @brief Contains the state of the HMAC operation
27  *
28  */
29 struct cc3xx_hmac_state_t {
30     uint8_t key[CC3XX_HMAC_BLOCK_SIZE];
31     struct cc3xx_hash_state_t hash; /* Allows to restart low-level hash */
32     cc3xx_hash_alg_t alg; /* Based on the hashing algorithm, sizes change */
33     size_t tag_len; /* Expected tag len, depending on the truncated length algorithm */
34 } __attribute__((aligned(4)));
35 
36 /**
37  * @brief Sets the key for the HMAC operation on the state
38  *
39  * @param[out] state    A pointer to a state structure
40  * @param[in]  key      Buffer containing the key
41  * @param[in]  key_size Size in bytes of the buffer \param key
42  * @param[in]  alg      Underlying hashing algorithm
43  * @return cc3xx_err_t
44  */
45 cc3xx_err_t cc3xx_lowlevel_hmac_set_key(
46     struct cc3xx_hmac_state_t *state,
47     const uint8_t *key,
48     size_t key_size,
49     cc3xx_hash_alg_t alg);
50 
51 /**
52  * @brief Set tag length for truncated HMAC algorithms. This must be called
53  *        after cc3xx_hmac_set_key is called, otherwise the default hash
54  *        length will be used instead
55  *
56  * @param[out] state   A pointer to a state structure
57  * @param[in]  tag_len Desired tag length
58  */
59 void cc3xx_lowlevel_hmac_set_tag_length(
60     struct cc3xx_hmac_state_t *state,
61     size_t tag_len);
62 
63 /**
64  * @brief Update the HMAC operation with a new chunk of data to authenticate
65  *
66  * @param[in,out] state       A pointer to a state structure
67  * @param[in]     data        Buffer containing the data to use for the update
68  * @param[in]     data_length Size in bytes of the buffer \param data
69  * @return cc3xx_err_t
70  */
71 cc3xx_err_t cc3xx_lowlevel_hmac_update(
72     struct cc3xx_hmac_state_t *state,
73     const uint8_t *data,
74     size_t data_length);
75 
76 /**
77  * @brief Finalize the HMAC operation by producing the authentication tag
78  *
79  * @param[in,out] state    A pointer to a state structure
80  * @param[out]    tag      Output buffer
81  * @param[in]     tag_size Size in bytes of the buffer \param tag
82  * @param[out]    tag_len  Length of the generated tag
83  * @return cc3xx_err_t
84  */
85 cc3xx_err_t cc3xx_lowlevel_hmac_finish(
86     struct cc3xx_hmac_state_t *state,
87     uint32_t *tag,
88     size_t tag_size,
89     size_t *tag_len);
90 
91 /**
92  * @brief Perform the computation of HMAC as an integrated operation. When
93  *        this function is normally called by the PSA MAC API layer, the
94  *        cc3xx_psa_api_config.h must have the configuration option named
95  *        \ref CC3XX_CONFIG_ENABLE_MAC_INTEGRATED_API must be set, otherwise
96  *        the MAC layer resorts to using multipart APIs to implement single part
97  *
98  * @param[in]  tag_len     Desired tag length (i.e. truncates the hash output to leftmost N bits)
99  * @param[in]  key         Buffer containing the key material
100  * @param[in]  key_size    Size in bytes of the key to be used
101  * @param[in]  alg         Hash algorithm to be used in HMAC, as a \ref cc3xx_hash_alg_t type
102  * @param[in]  data        Data to be authenticated
103  * @param[in]  data_length Size in bytes of the data to be authenticated
104  * @param[out] tag         Buffer that contains the MAC produced if the operation succeeds
105  * @param[in]  tag_size    Size in byte of the \ref tag buffer
106  * @param[out] tag_length  Size in bytes of the produced tag (i.e. depends on the underlying hash)
107  * @return cc3xx_err_t
108  */
109 cc3xx_err_t cc3xx_lowlevel_hmac_compute(
110     size_t tag_len,
111     const uint8_t *key,
112     size_t key_size,
113     cc3xx_hash_alg_t alg,
114     const uint8_t *data,
115     size_t data_length,
116     uint32_t *tag,
117     size_t tag_size,
118     size_t *tag_length);
119 
120 #ifdef __cplusplus
121 }
122 #endif
123 
124 #endif /* __CC3XX_HMAC_H__ */
125