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_CHACHA_H 9 #define CC3XX_CHACHA_H 10 11 #include "cc3xx_error.h" 12 #include "cc3xx_config.h" 13 #include "cc3xx_dma.h" 14 #if defined(CC3XX_CONFIG_CHACHA_POLY1305_ENABLE) 15 #include "cc3xx_poly1305.h" 16 #endif /* CC3XX_CONFIG_CHACHA_POLY1305_ENABLE */ 17 18 #include <stdint.h> 19 #include <stddef.h> 20 #include <stdbool.h> 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 #define CC3XX_CHACHA_KEY_SIZE 32 27 28 #define CC3XX_CHACHA_BLOCK_SIZE 64 29 30 typedef enum { 31 CC3XX_CHACHA_MODE_CHACHA = 0b0, 32 CC3XX_CHACHA_MODE_CHACHA_POLY1305 = 0b1, 33 } cc3xx_chacha_mode_t; 34 35 typedef enum { 36 CC3XX_CHACHA_DIRECTION_ENCRYPT = 0b0U, 37 CC3XX_CHACHA_DIRECTION_DECRYPT = 0b1U, 38 } cc3xx_chacha_direction_t; 39 40 struct cc3xx_chacha_state_t { 41 cc3xx_chacha_direction_t direction; 42 cc3xx_chacha_mode_t mode; 43 bool iv_is_96_bit; 44 uint32_t key[8]; 45 46 size_t crypted_len; 47 size_t authed_len; 48 49 uint64_t counter; 50 uint32_t iv[3]; 51 52 struct cc3xx_dma_state_t dma_state; 53 #if defined(CC3XX_CONFIG_CHACHA_POLY1305_ENABLE) 54 struct cc3xx_poly1305_state_t poly_state; 55 #endif /* CC3XX_CONFIG_CHACHA_POLY1305_ENABLE */ 56 }; 57 58 /** 59 * @brief Initialize a CHACHA20 operation. 60 61 * @param[in] direction Whether the operation should encrypt or decrypt. 62 * @param[in] mode Which AES mode should be used. 63 * @param[in] key Buffer containing the key material. Must be 64 * CC3XX_CHACHA_KEY_SIZE in size. 65 * @param[in] initial_counter The initial counter value. 66 * @param[in] iv The CHACHA IV. May be either 8 or 12 bytes. 67 * @param[in] iv_len The size of the IV input. 68 * 69 * @return CC3XX_ERR_SUCCESS on success, another 70 * cc3xx_err_t on error. 71 */ 72 cc3xx_err_t cc3xx_lowlevel_chacha20_init( 73 cc3xx_chacha_direction_t direction, 74 cc3xx_chacha_mode_t mode, 75 const uint32_t *key, 76 uint64_t initial_counter, 77 const uint32_t *iv, size_t iv_len); 78 79 /** 80 * @brief Get the current state of the CHACHA operation. 81 * Allows for restartable CHACHA operations. 82 83 * @param[out] state The cc3xx_chacha20_state_t to write the state 84 * into. 85 */ 86 void cc3xx_lowlevel_chacha20_get_state(struct cc3xx_chacha_state_t *state); 87 88 /** 89 * @brief Set the current state of the CHACHA operation. 90 * Allows for restartable CHACHA operations. 91 * 92 * @note This funtion initializes the hardware, there is 93 * no need to seperately call cc3xx_chacha20_init. 94 95 * @param[in] state The cc3xx_chacha20_state_t to read the state 96 * from. 97 * 98 * @return CC3XX_ERR_SUCCESS on success, another 99 * cc3xx_err_t on error. 100 */ 101 cc3xx_err_t cc3xx_lowlevel_chacha20_set_state(const struct cc3xx_chacha_state_t *state); 102 103 /** 104 * @brief Get the amount of bytes that have been output 105 * 106 * @return Amount of bytes of output that has been written 107 * (which it not necessarily the same amount of 108 * input that has been submitted, due to DMA 109 * buffering) 110 */ 111 size_t cc3xx_lowlevel_chacha20_get_current_output_size(void); 112 113 /** 114 * @brief Set the buffer that the CHACHA engine will 115 * output into. 116 * 117 * @param[out] out The buffer to output into. 118 * @param[in] out_len The size of the buffer to output into. If this 119 * is smaller than the size of the data passed to 120 * cc3xx_chacha20_update, that function will fail 121 * with an error. 122 */ 123 void cc3xx_lowlevel_chacha20_set_output_buffer(uint8_t *out, size_t out_len); 124 125 /** 126 * @brief Input data to be encrypted/decrypted into an 127 * CHACHA operation. 128 129 * @param[in] in A pointer to the data to be input. 130 * @param[in] in_len The size of the data to be input. 131 * 132 * @return CC3XX_ERR_SUCCESS on success, another 133 * cc3xx_err_t on error. 134 */ 135 cc3xx_err_t cc3xx_lowlevel_chacha20_update(const uint8_t* in, size_t in_len); 136 137 /** 138 * @brief Input data to be authenticated, but not 139 * encrypted or decrypted into a CHACHA operation. 140 * 141 * @note This function is a no-op unless the mode is 142 * CC3XX_CHACHA_MODE_CHACHA_POLY1305. 143 * 144 * @note This function must not be called after 145 * cc3xx_chacha20_update has been called, until a 146 * new operation is started. 147 148 * @param[in] in A pointer to the data to be input. 149 * @param[in] in_len The size of the data to be input. 150 */ 151 void cc3xx_lowlevel_chacha20_update_authed_data(const uint8_t* in, size_t in_len); 152 153 /** 154 * @brief Finish a CHACHA operation. Calling this will 155 * encrypt/decrypt the final data. 156 * 157 * @param[in,out] tag The buffer to write the tag into or read and 158 * compare the tag from, depending on direction. 159 * Can be NULL if not using 160 * CC3XX_CHACHA_MODE_CHACHA_POLY1305. 161 * 162 * @param[out] size The size of the output that has been written. 163 * 164 * @return CC3XX_ERR_SUCCESS on success / tag comparison 165 * succeeded, another cc3xx_err_t on error. 166 */ 167 cc3xx_err_t cc3xx_lowlevel_chacha20_finish(uint32_t *tag, size_t *size); 168 169 /** 170 * @brief Uninitialize the CHACHA engine. 171 * 172 * @note The CHACHA engine is not implicitly 173 * uninitialized on an error. 174 * 175 */ 176 void cc3xx_lowlevel_chacha20_uninit(void); 177 178 #ifdef __cplusplus 179 } 180 #endif 181 182 #endif /* CC3XX_CHACHA_H */ 183