1 /* 2 * Copyright (c) 2021-2023, The TrustedFirmware-M Contributors. 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_lowlevel_aes_init( 131 cc3xx_aes_direction_t direction, 132 cc3xx_aes_mode_t mode, cc3xx_aes_key_id_t key_id, 133 const uint32_t *key, cc3xx_aes_keysize_t key_size, 134 const uint32_t *iv, size_t iv_len); 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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_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_lowlevel_aes_uninit(void); 251 252 #ifdef __cplusplus 253 } 254 #endif 255 256 #endif /* CC3XX_AES_H */ 257