1 /**
2  * \file chachapoly.h
3  *
4  * \brief   This file contains the AEAD-ChaCha20-Poly1305 definitions and
5  *          functions.
6  *
7  *          ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
8  *          with Associated Data (AEAD) that can be used to encrypt and
9  *          authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
10  *          Bernstein and was standardized in RFC 7539.
11  *
12  * \author Daniel King <damaki.gh@gmail.com>
13  */
14 
15 /*
16  *  Copyright The Mbed TLS Contributors
17  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
18  */
19 
20 #ifndef MBEDTLS_CHACHAPOLY_H
21 #define MBEDTLS_CHACHAPOLY_H
22 #include "mbedtls/private_access.h"
23 
24 #include "mbedtls/build_info.h"
25 
26 /* for shared error codes */
27 #include "mbedtls/poly1305.h"
28 
29 /** The requested operation is not permitted in the current state. */
30 #define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054
31 /** Authenticated decryption failed: data was not authentic. */
32 #define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 typedef enum {
39     MBEDTLS_CHACHAPOLY_ENCRYPT,     /**< The mode value for performing encryption. */
40     MBEDTLS_CHACHAPOLY_DECRYPT      /**< The mode value for performing decryption. */
41 }
42 mbedtls_chachapoly_mode_t;
43 
44 #if !defined(MBEDTLS_CHACHAPOLY_ALT)
45 
46 #include "mbedtls/chacha20.h"
47 
48 typedef struct mbedtls_chachapoly_context {
49     mbedtls_chacha20_context MBEDTLS_PRIVATE(chacha20_ctx);  /**< The ChaCha20 context. */
50     mbedtls_poly1305_context MBEDTLS_PRIVATE(poly1305_ctx);  /**< The Poly1305 context. */
51     uint64_t MBEDTLS_PRIVATE(aad_len);                       /**< The length (bytes) of the Additional Authenticated Data. */
52     uint64_t MBEDTLS_PRIVATE(ciphertext_len);                /**< The length (bytes) of the ciphertext. */
53     int MBEDTLS_PRIVATE(state);                              /**< The current state of the context. */
54     mbedtls_chachapoly_mode_t MBEDTLS_PRIVATE(mode);         /**< Cipher mode (encrypt or decrypt). */
55 }
56 mbedtls_chachapoly_context;
57 
58 #else /* !MBEDTLS_CHACHAPOLY_ALT */
59 #include "chachapoly_alt.h"
60 #endif /* !MBEDTLS_CHACHAPOLY_ALT */
61 
62 /**
63  * \brief           This function initializes the specified ChaCha20-Poly1305 context.
64  *
65  *                  It must be the first API called before using
66  *                  the context. It must be followed by a call to
67  *                  \c mbedtls_chachapoly_setkey() before any operation can be
68  *                  done, and to \c mbedtls_chachapoly_free() once all
69  *                  operations with that context have been finished.
70  *
71  *                  In order to encrypt or decrypt full messages at once, for
72  *                  each message you should make a single call to
73  *                  \c mbedtls_chachapoly_crypt_and_tag() or
74  *                  \c mbedtls_chachapoly_auth_decrypt().
75  *
76  *                  In order to encrypt messages piecewise, for each
77  *                  message you should make a call to
78  *                  \c mbedtls_chachapoly_starts(), then 0 or more calls to
79  *                  \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
80  *                  \c mbedtls_chachapoly_update(), then one call to
81  *                  \c mbedtls_chachapoly_finish().
82  *
83  * \warning         Decryption with the piecewise API is discouraged! Always
84  *                  use \c mbedtls_chachapoly_auth_decrypt() when possible!
85  *
86  *                  If however this is not possible because the data is too
87  *                  large to fit in memory, you need to:
88  *
89  *                  - call \c mbedtls_chachapoly_starts() and (if needed)
90  *                  \c mbedtls_chachapoly_update_aad() as above,
91  *                  - call \c mbedtls_chachapoly_update() multiple times and
92  *                  ensure its output (the plaintext) is NOT used in any other
93  *                  way than placing it in temporary storage at this point,
94  *                  - call \c mbedtls_chachapoly_finish() to compute the
95  *                  authentication tag and compared it in constant time to the
96  *                  tag received with the ciphertext.
97  *
98  *                  If the tags are not equal, you must immediately discard
99  *                  all previous outputs of \c mbedtls_chachapoly_update(),
100  *                  otherwise you can now safely use the plaintext.
101  *
102  * \param ctx       The ChachaPoly context to initialize. Must not be \c NULL.
103  */
104 void mbedtls_chachapoly_init(mbedtls_chachapoly_context *ctx);
105 
106 /**
107  * \brief           This function releases and clears the specified
108  *                  ChaCha20-Poly1305 context.
109  *
110  * \param ctx       The ChachaPoly context to clear. This may be \c NULL, in which
111  *                  case this function is a no-op.
112  */
113 void mbedtls_chachapoly_free(mbedtls_chachapoly_context *ctx);
114 
115 /**
116  * \brief           This function sets the ChaCha20-Poly1305
117  *                  symmetric encryption key.
118  *
119  * \param ctx       The ChaCha20-Poly1305 context to which the key should be
120  *                  bound. This must be initialized.
121  * \param key       The \c 256 Bit (\c 32 Bytes) key.
122  *
123  * \return          \c 0 on success.
124  * \return          A negative error code on failure.
125  */
126 int mbedtls_chachapoly_setkey(mbedtls_chachapoly_context *ctx,
127                               const unsigned char key[32]);
128 
129 /**
130  * \brief           This function starts a ChaCha20-Poly1305 encryption or
131  *                  decryption operation.
132  *
133  * \warning         You must never use the same nonce twice with the same key.
134  *                  This would void any confidentiality and authenticity
135  *                  guarantees for the messages encrypted with the same nonce
136  *                  and key.
137  *
138  * \note            If the context is being used for AAD only (no data to
139  *                  encrypt or decrypt) then \p mode can be set to any value.
140  *
141  * \warning         Decryption with the piecewise API is discouraged, see the
142  *                  warning on \c mbedtls_chachapoly_init().
143  *
144  * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
145  *                  and bound to a key.
146  * \param nonce     The nonce/IV to use for the message.
147  *                  This must be a readable buffer of length \c 12 Bytes.
148  * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
149  *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
150  *
151  * \return          \c 0 on success.
152  * \return          A negative error code on failure.
153  */
154 int mbedtls_chachapoly_starts(mbedtls_chachapoly_context *ctx,
155                               const unsigned char nonce[12],
156                               mbedtls_chachapoly_mode_t mode);
157 
158 /**
159  * \brief           This function feeds additional data to be authenticated
160  *                  into an ongoing ChaCha20-Poly1305 operation.
161  *
162  *                  The Additional Authenticated Data (AAD), also called
163  *                  Associated Data (AD) is only authenticated but not
164  *                  encrypted nor included in the encrypted output. It is
165  *                  usually transmitted separately from the ciphertext or
166  *                  computed locally by each party.
167  *
168  * \note            This function is called before data is encrypted/decrypted.
169  *                  I.e. call this function to process the AAD before calling
170  *                  \c mbedtls_chachapoly_update().
171  *
172  *                  You may call this function multiple times to process
173  *                  an arbitrary amount of AAD. It is permitted to call
174  *                  this function 0 times, if no AAD is used.
175  *
176  *                  This function cannot be called any more if data has
177  *                  been processed by \c mbedtls_chachapoly_update(),
178  *                  or if the context has been finished.
179  *
180  * \warning         Decryption with the piecewise API is discouraged, see the
181  *                  warning on \c mbedtls_chachapoly_init().
182  *
183  * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
184  *                  and bound to a key.
185  * \param aad_len   The length in Bytes of the AAD. The length has no
186  *                  restrictions.
187  * \param aad       Buffer containing the AAD.
188  *                  This pointer can be \c NULL if `aad_len == 0`.
189  *
190  * \return          \c 0 on success.
191  * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
192  *                  if \p ctx or \p aad are NULL.
193  * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
194  *                  if the operations has not been started or has been
195  *                  finished, or if the AAD has been finished.
196  */
197 int mbedtls_chachapoly_update_aad(mbedtls_chachapoly_context *ctx,
198                                   const unsigned char *aad,
199                                   size_t aad_len);
200 
201 /**
202  * \brief           Thus function feeds data to be encrypted or decrypted
203  *                  into an on-going ChaCha20-Poly1305
204  *                  operation.
205  *
206  *                  The direction (encryption or decryption) depends on the
207  *                  mode that was given when calling
208  *                  \c mbedtls_chachapoly_starts().
209  *
210  *                  You may call this function multiple times to process
211  *                  an arbitrary amount of data. It is permitted to call
212  *                  this function 0 times, if no data is to be encrypted
213  *                  or decrypted.
214  *
215  * \warning         Decryption with the piecewise API is discouraged, see the
216  *                  warning on \c mbedtls_chachapoly_init().
217  *
218  * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
219  * \param len       The length (in bytes) of the data to encrypt or decrypt.
220  * \param input     The buffer containing the data to encrypt or decrypt.
221  *                  This pointer can be \c NULL if `len == 0`.
222  * \param output    The buffer to where the encrypted or decrypted data is
223  *                  written. This must be able to hold \p len bytes.
224  *                  This pointer can be \c NULL if `len == 0`.
225  *
226  * \return          \c 0 on success.
227  * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
228  *                  if the operation has not been started or has been
229  *                  finished.
230  * \return          Another negative error code on other kinds of failure.
231  */
232 int mbedtls_chachapoly_update(mbedtls_chachapoly_context *ctx,
233                               size_t len,
234                               const unsigned char *input,
235                               unsigned char *output);
236 
237 /**
238  * \brief           This function finished the ChaCha20-Poly1305 operation and
239  *                  generates the MAC (authentication tag).
240  *
241  * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
242  * \param mac       The buffer to where the 128-bit (16 bytes) MAC is written.
243  *
244  * \warning         Decryption with the piecewise API is discouraged, see the
245  *                  warning on \c mbedtls_chachapoly_init().
246  *
247  * \return          \c 0 on success.
248  * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
249  *                  if the operation has not been started or has been
250  *                  finished.
251  * \return          Another negative error code on other kinds of failure.
252  */
253 int mbedtls_chachapoly_finish(mbedtls_chachapoly_context *ctx,
254                               unsigned char mac[16]);
255 
256 /**
257  * \brief           This function performs a complete ChaCha20-Poly1305
258  *                  authenticated encryption with the previously-set key.
259  *
260  * \note            Before using this function, you must set the key with
261  *                  \c mbedtls_chachapoly_setkey().
262  *
263  * \warning         You must never use the same nonce twice with the same key.
264  *                  This would void any confidentiality and authenticity
265  *                  guarantees for the messages encrypted with the same nonce
266  *                  and key.
267  *
268  * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
269  *                  This must be initialized.
270  * \param length    The length (in bytes) of the data to encrypt or decrypt.
271  * \param nonce     The 96-bit (12 bytes) nonce/IV to use.
272  * \param aad       The buffer containing the additional authenticated
273  *                  data (AAD). This pointer can be \c NULL if `aad_len == 0`.
274  * \param aad_len   The length (in bytes) of the AAD data to process.
275  * \param input     The buffer containing the data to encrypt or decrypt.
276  *                  This pointer can be \c NULL if `ilen == 0`.
277  * \param output    The buffer to where the encrypted or decrypted data
278  *                  is written. This pointer can be \c NULL if `ilen == 0`.
279  * \param tag       The buffer to where the computed 128-bit (16 bytes) MAC
280  *                  is written. This must not be \c NULL.
281  *
282  * \return          \c 0 on success.
283  * \return          A negative error code on failure.
284  */
285 int mbedtls_chachapoly_encrypt_and_tag(mbedtls_chachapoly_context *ctx,
286                                        size_t length,
287                                        const unsigned char nonce[12],
288                                        const unsigned char *aad,
289                                        size_t aad_len,
290                                        const unsigned char *input,
291                                        unsigned char *output,
292                                        unsigned char tag[16]);
293 
294 /**
295  * \brief           This function performs a complete ChaCha20-Poly1305
296  *                  authenticated decryption with the previously-set key.
297  *
298  * \note            Before using this function, you must set the key with
299  *                  \c mbedtls_chachapoly_setkey().
300  *
301  * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
302  * \param length    The length (in Bytes) of the data to decrypt.
303  * \param nonce     The \c 96 Bit (\c 12 bytes) nonce/IV to use.
304  * \param aad       The buffer containing the additional authenticated data (AAD).
305  *                  This pointer can be \c NULL if `aad_len == 0`.
306  * \param aad_len   The length (in bytes) of the AAD data to process.
307  * \param tag       The buffer holding the authentication tag.
308  *                  This must be a readable buffer of length \c 16 Bytes.
309  * \param input     The buffer containing the data to decrypt.
310  *                  This pointer can be \c NULL if `ilen == 0`.
311  * \param output    The buffer to where the decrypted data is written.
312  *                  This pointer can be \c NULL if `ilen == 0`.
313  *
314  * \return          \c 0 on success.
315  * \return          #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
316  *                  if the data was not authentic.
317  * \return          Another negative error code on other kinds of failure.
318  */
319 int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx,
320                                     size_t length,
321                                     const unsigned char nonce[12],
322                                     const unsigned char *aad,
323                                     size_t aad_len,
324                                     const unsigned char tag[16],
325                                     const unsigned char *input,
326                                     unsigned char *output);
327 
328 #if defined(MBEDTLS_SELF_TEST)
329 /**
330  * \brief           The ChaCha20-Poly1305 checkup routine.
331  *
332  * \return          \c 0 on success.
333  * \return          \c 1 on failure.
334  */
335 int mbedtls_chachapoly_self_test(int verbose);
336 #endif /* MBEDTLS_SELF_TEST */
337 
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 #endif /* MBEDTLS_CHACHAPOLY_H */
343