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