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