1 /*
2  * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef CC3XX_AES_H
9 #define CC3XX_AES_H
10 
11 #include "cc3xx_error.h"
12 #include "cc3xx_config.h"
13 #include "cc3xx_dma.h"
14 
15 #include <stdint.h>
16 #include <stddef.h>
17 #include <stdbool.h>
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #define AES_IV_LEN 16
24 #define AES_CTR_LEN 16
25 #define AES_GCM_FIELD_POINT_SIZE 16
26 #define AES_TAG_MAX_LEN 16
27 
28 #define AES_BLOCK_SIZE 16
29 #define AES_MAX_KEY_LEN 32
30 
31 typedef enum {
32     CC3XX_AES_DIRECTION_ENCRYPT = 0b0U,
33     CC3XX_AES_DIRECTION_DECRYPT = 0b1U,
34 } cc3xx_aes_direction_t;
35 
36 typedef enum {
37     CC3XX_AES_MODE_ECB      = 0b0000U,
38     CC3XX_AES_MODE_CBC      = 0b0001U,
39     CC3XX_AES_MODE_CTR      = 0b0010U,
40     CC3XX_AES_MODE_GCM      = 0b1010U,
41     CC3XX_AES_MODE_CMAC     = 0b0111U,
42     CC3XX_AES_MODE_CCM      = 0b1011U,
43 } cc3xx_aes_mode_t;
44 
45 typedef enum {
46     CC3XX_AES_KEYSIZE_128 = 0b00U,
47     CC3XX_AES_KEYSIZE_192 = 0b01U,
48     CC3XX_AES_KEYSIZE_256 = 0b10U,
49 } cc3xx_aes_keysize_t;
50 
51 typedef enum {
52     CC3XX_AES_KEY_ID_HUK      = 0x0U,  /*!< Hardware unique key. Also referred to as RKEK */
53     CC3XX_AES_KEY_ID_KRTL     = 0x1U,  /*!< RTL Key */
54     CC3XX_AES_KEY_ID_KCP      = 0x2U,  /*!< DM provisioning key */
55     CC3XX_AES_KEY_ID_KCE      = 0x3U,  /*!< DM code encryption key */
56     CC3XX_AES_KEY_ID_KPICV    = 0x4U,  /*!< CM provisioning key */
57     CC3XX_AES_KEY_ID_KCEICV   = 0x5U,  /*!< CM code encryption key */
58     CC3XX_AES_KEY_ID_GUK      = 0xFU,  /*!< Group unique key. See CCA spec for information */
59     CC3XX_AES_KEY_ID_USER_KEY = 0xFFU, /*!< Key input into registers manually */
60 } cc3xx_aes_key_id_t;
61 
62 /* Note that parts of the AES state that can be reconstructed without the data
63  * input by the _update functions is not kept at this layer, and must be
64  * preserved by the restartable layer.
65  */
66 struct cc3xx_aes_state_t {
67     cc3xx_aes_mode_t mode;
68     cc3xx_aes_direction_t direction;
69 
70     uint32_t iv[AES_IV_LEN / sizeof(uint32_t)];
71 #if defined(CC3XX_CONFIG_AES_CCM_ENABLE) && defined(CC3XX_CONFIG_AES_TUNNELLING_ENABLE)
72     uint32_t tun1_iv[AES_IV_LEN / sizeof(uint32_t)];
73 #endif /* defined(CC3XX_CONFIG_AES_CCM_ENABLE) && defined(CC3XX_CONFIG_AES_TUNNELLING_ENABLE) */
74     uint32_t ctr[AES_CTR_LEN / sizeof(uint32_t)];
75 
76     size_t crypted_length;
77     size_t authed_length;
78 #ifdef CC3XX_CONFIG_AES_CCM_ENABLE
79     size_t aes_to_crypt_len;
80     size_t aes_to_auth_len;
81 #endif /* CC3XX_CONFIG_AES_CCM_ENABLE */
82 
83 #ifdef CC3XX_CONFIG_AES_GCM_ENABLE
84     uint32_t gcm_field_point[AES_GCM_FIELD_POINT_SIZE / sizeof(uint32_t)];
85     uint32_t ghash_key[AES_GCM_FIELD_POINT_SIZE / sizeof(uint32_t)];
86 #endif /* CC3XX_CONFIG_AES_GCM_ENABLE */
87 #if defined(CC3XX_CONFIG_AES_GCM_ENABLE) || defined(CC3XX_CONFIG_AES_CCM_ENABLE)
88     uint32_t counter_0[AES_CTR_LEN / sizeof(uint32_t)];
89 #endif /* defined(CC3XX_CONFIG_AES_GCM_ENABLE) || defined(CC3XX_CONFIG_AES_CCM_ENABLE) */
90 
91 #ifdef CC3XX_CONFIG_AES_CCM_ENABLE
92     uint32_t ccm_initial_iv_buf[AES_CTR_LEN / sizeof(uint32_t)];
93     size_t ccm_initial_iv_size;
94 #endif /* CC3XX_CONFIG_AES_CCM_ENABLE */
95 
96 #if defined(CC3XX_CONFIG_AES_CCM_ENABLE) \
97     || defined (CC3XX_CONFIG_AES_GCM_ENABLE) \
98     || defined (CC3XX_CONFIG_AES_CMAC_ENABLE)
99     size_t aes_tag_len;
100 #endif
101 
102     cc3xx_aes_key_id_t key_id;
103     cc3xx_aes_keysize_t key_size;
104 
105     struct cc3xx_dma_state_t dma_state;
106 
107     bool state_contains_key;
108     /* The key buf goes at the end, so that we can copy it in a DPA-resistant
109      * manner.
110      */
111     uint32_t key_buf[AES_MAX_KEY_LEN / sizeof(uint32_t)];
112 };
113 
114 /**
115  * @brief                        Initialize an AES operation.
116 
117  * @param[in]  direction         Whether the operation should encrypt or decrypt.
118  * @param[in]  mode              Which AES mode should be used.
119  * @param[in]  key_id            Which user/hardware key should be used.
120  * @param[in]  key               If key_id is set to CC3XX_AES_KEY_ID_USER_KEY,
121  *                               this buffer contains the key material.
122  * @param[in]  key_size          The size of the key being used.
123  * @param[in]  iv                The inital IV/CTR value for the mode. For modes
124  *                               without an IV/CTR, this may be NULL.
125  * @param[in]  iv_len            The size of the IV input.
126  *
127  * @return                       CC3XX_ERR_SUCCESS on success, another
128  *                               cc3xx_err_t on error.
129  */
130 cc3xx_err_t cc3xx_aes_init(cc3xx_aes_direction_t direction,
131                            cc3xx_aes_mode_t mode, cc3xx_aes_key_id_t key_id,
132                            const uint32_t *key, cc3xx_aes_keysize_t key_size,
133                            const uint32_t *iv, size_t iv_len);
134 
135 
136 /**
137  * @brief                        Get the current state of the AES operation.
138  *                               Allows for restartable AES operations.
139 
140  * @param[out] state            The cc3xx_aes_state_t to write the state into.
141  */
142 void cc3xx_aes_get_state(struct cc3xx_aes_state_t *state);
143 /**
144  * @brief                        Set the current state of the AES operation.
145  *                               Allows for restartable AES operations.
146  *
147  * @note                         This funtion initializes the hardware, there is
148  *                               no need to seperately call cc3xx_aes_init.
149 
150  * @param[in]  state            The cc3xx_aes_state_t to read the state from.
151  *
152  * @return                       CC3XX_ERR_SUCCESS on success, another
153  *                               cc3xx_err_t on error.
154  */
155 cc3xx_err_t cc3xx_aes_set_state(const struct cc3xx_aes_state_t *state);
156 
157 /**
158  * @brief                        Set the length of the tag produced or verfied
159  *                               by AEAD/MAC modes.
160  *
161  * @note                         This function is a no-op in non-AEAD/MAC modes.
162  *
163  * @param[in]  tag_len           The length of the tag.
164  */
165 void cc3xx_aes_set_tag_len(uint32_t tag_len);
166 
167 /**
168  * @brief                        Set the length of the data that will be input.
169  *
170  * @note                         This function is a no-op in all but CCM mode.
171  *
172  * @param[in]  to_crypt_len      How many bytes of data will be encrypted.
173  * @param[in]  to_auth_len       How many bytes of data will be authenticated,
174  *                               but not encrypted.
175  */
176 void cc3xx_aes_set_data_len(uint32_t to_crypt_len, uint32_t to_auth_len);
177 
178 /**
179  * @brief                        Get the amount of bytes that have been output
180  *
181  * @return                       Amount of bytes of output that has been written
182  *                               (which it not necessarily the same amount of
183  *                               input that has been submitted, due to DMA
184  *                               buffering)
185  */
186 size_t cc3xx_aes_get_current_output_size(void);
187 
188 /**
189  * @brief                        Set the buffer that the AES engine will output
190  *                               into.
191  *
192  * @param[out] out               The buffer to output into.
193  * @param[in]  out_len           The size of the buffer to output into. If this
194  *                               is smaller than the size of the data passed to
195  *                               cc3xx_aes_update, that function will fail with
196  *                               an error.
197  */
198 void cc3xx_aes_set_output_buffer(uint8_t *out, size_t out_len);
199 
200 /**
201  * @brief                        Input data to be encrypted/decrypted into an
202  *                               AES operation.
203 
204  * @param[in]  in                A pointer to the data to be input.
205  * @param[in]  in_len            The size of the data to be input.
206  */
207 cc3xx_err_t cc3xx_aes_update(const uint8_t* in, size_t in_len);
208 
209 /**
210  * @brief                        Input data to be authenticated, but not
211  *                               encrypted or decrypted into an AEAD/MAC
212  *                               operation.
213  *
214  * @note                         This function must not be called after
215  *                               cc3xx_aes_update has been called, until a new
216  *                               operation is started.
217 
218  * @param[in]  in                A pointer to the data to be input.
219  * @param[in]  in_len            The size of the data to be input.
220  *
221  * @return                       CC3XX_ERR_SUCCESS on success, another
222  *                               cc3xx_err_t on error.
223  */
224 void cc3xx_aes_update_authed_data(const uint8_t* in, size_t in_len);
225 
226 /**
227  * @brief                        Finish an AES operation. Calling this will
228  *                               encrypt/decrypt the final data.
229  *
230  * @param[in,out]  tag           The buffer to write the tag into or read and
231  *                               compare the tag from, depending on direction.
232  *                               The tag size will be 16 if not explicitly set,
233  *                               and the buffer must be sized appropriately. Can
234  *                               be NULL if using a non-AEAD/MAC mode.
235  *
236  * @param[out]     size          The size of the output that has been written.
237  *
238  * @return                       CC3XX_ERR_SUCCESS on success / tag comparison
239  *                               succeeded, another cc3xx_err_t on error.
240  */
241 cc3xx_err_t cc3xx_aes_finish(uint32_t *tag, size_t *size);
242 
243 /**
244  * @brief                       Uninitialize the AES engine.
245  *
246  * @note                        The AES engine is not implicitly uninitialized
247  *                              on an error.
248  *
249  */
250 void cc3xx_aes_uninit(void);
251 
252 #ifdef __cplusplus
253 }
254 #endif
255 
256 #endif /* CC3XX_AES_H */
257