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