chachapoly 15.8 KB
Newer Older
ROOL's avatar
ROOL committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
/**
 * \file chachapoly.h
 *
 * \brief   This file contains the AEAD-ChaCha20-Poly1305 definitions and
 *          functions.
 *
 *          ChaCha20-Poly1305 is an algorithm for Authenticated Encryption
 *          with Associated Data (AEAD) that can be used to encrypt and
 *          authenticate data. It is based on ChaCha20 and Poly1305 by Daniel
 *          Bernstein and was standardized in RFC 7539.
 *
 * \author Daniel King <damaki.gh@gmail.com>
 */

/*  Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  This file is part of Mbed TLS (https://tls.mbed.org)
 */

#ifndef MBEDTLS_CHACHAPOLY_H
#define MBEDTLS_CHACHAPOLY_H

#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

/* for shared error codes */
#include "poly1305.h"

#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE            -0x0054 /**< The requested operation is not permitted in the current state. */
#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED          -0x0056 /**< Authenticated decryption failed: data was not authentic. */

#ifdef __cplusplus
extern "C" {
#endif

typedef enum
{
    MBEDTLS_CHACHAPOLY_ENCRYPT,     /**< The mode value for performing encryption. */
    MBEDTLS_CHACHAPOLY_DECRYPT      /**< The mode value for performing decryption. */
}
mbedtls_chachapoly_mode_t;

#if !defined(MBEDTLS_CHACHAPOLY_ALT)

#include "chacha20.h"

ROOL's avatar
ROOL committed
63
typedef struct mbedtls_chachapoly_context
ROOL's avatar
ROOL committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
{
    mbedtls_chacha20_context chacha20_ctx;  /**< The ChaCha20 context. */
    mbedtls_poly1305_context poly1305_ctx;  /**< The Poly1305 context. */
    uint64_t aad_len;                       /**< The length (bytes) of the Additional Authenticated Data. */
    uint64_t ciphertext_len;                /**< The length (bytes) of the ciphertext. */
    int state;                              /**< The current state of the context. */
    mbedtls_chachapoly_mode_t mode;         /**< Cipher mode (encrypt or decrypt). */
}
mbedtls_chachapoly_context;

#else /* !MBEDTLS_CHACHAPOLY_ALT */
#include "chachapoly_alt.h"
#endif /* !MBEDTLS_CHACHAPOLY_ALT */

/**
 * \brief           This function initializes the specified ChaCha20-Poly1305 context.
 *
 *                  It must be the first API called before using
 *                  the context. It must be followed by a call to
 *                  \c mbedtls_chachapoly_setkey() before any operation can be
 *                  done, and to \c mbedtls_chachapoly_free() once all
 *                  operations with that context have been finished.
 *
 *                  In order to encrypt or decrypt full messages at once, for
 *                  each message you should make a single call to
 *                  \c mbedtls_chachapoly_crypt_and_tag() or
 *                  \c mbedtls_chachapoly_auth_decrypt().
 *
 *                  In order to encrypt messages piecewise, for each
 *                  message you should make a call to
 *                  \c mbedtls_chachapoly_starts(), then 0 or more calls to
 *                  \c mbedtls_chachapoly_update_aad(), then 0 or more calls to
 *                  \c mbedtls_chachapoly_update(), then one call to
 *                  \c mbedtls_chachapoly_finish().
 *
 * \warning         Decryption with the piecewise API is discouraged! Always
 *                  use \c mbedtls_chachapoly_auth_decrypt() when possible!
 *
 *                  If however this is not possible because the data is too
 *                  large to fit in memory, you need to:
 *
 *                  - call \c mbedtls_chachapoly_starts() and (if needed)
 *                  \c mbedtls_chachapoly_update_aad() as above,
 *                  - call \c mbedtls_chachapoly_update() multiple times and
 *                  ensure its output (the plaintext) is NOT used in any other
 *                  way than placing it in temporary storage at this point,
 *                  - call \c mbedtls_chachapoly_finish() to compute the
 *                  authentication tag and compared it in constant time to the
 *                  tag received with the ciphertext.
 *
 *                  If the tags are not equal, you must immediately discard
 *                  all previous outputs of \c mbedtls_chachapoly_update(),
 *                  otherwise you can now safely use the plaintext.
 *
ROOL's avatar
ROOL committed
118
 * \param ctx       The ChachaPoly context to initialize. Must not be \c NULL.
ROOL's avatar
ROOL committed
119 120 121 122
 */
void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx );

/**
ROOL's avatar
ROOL committed
123 124
 * \brief           This function releases and clears the specified
 *                  ChaCha20-Poly1305 context.
ROOL's avatar
ROOL committed
125
 *
ROOL's avatar
ROOL committed
126 127
 * \param ctx       The ChachaPoly context to clear. This may be \c NULL, in which
 *                  case this function is a no-op.
ROOL's avatar
ROOL committed
128 129 130 131
 */
void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx );

/**
ROOL's avatar
ROOL committed
132 133
 * \brief           This function sets the ChaCha20-Poly1305
 *                  symmetric encryption key.
ROOL's avatar
ROOL committed
134 135
 *
 * \param ctx       The ChaCha20-Poly1305 context to which the key should be
ROOL's avatar
ROOL committed
136 137
 *                  bound. This must be initialized.
 * \param key       The \c 256 Bit (\c 32 Bytes) key.
ROOL's avatar
ROOL committed
138 139
 *
 * \return          \c 0 on success.
ROOL's avatar
ROOL committed
140
 * \return          A negative error code on failure.
ROOL's avatar
ROOL committed
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
 */
int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
                               const unsigned char key[32] );

/**
 * \brief           This function starts a ChaCha20-Poly1305 encryption or
 *                  decryption operation.
 *
 * \warning         You must never use the same nonce twice with the same key.
 *                  This would void any confidentiality and authenticity
 *                  guarantees for the messages encrypted with the same nonce
 *                  and key.
 *
 * \note            If the context is being used for AAD only (no data to
 *                  encrypt or decrypt) then \p mode can be set to any value.
 *
 * \warning         Decryption with the piecewise API is discouraged, see the
 *                  warning on \c mbedtls_chachapoly_init().
 *
ROOL's avatar
ROOL committed
160 161 162 163
 * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
 *                  and bound to a key.
 * \param nonce     The nonce/IV to use for the message.
 *                  This must be a redable buffer of length \c 12 Bytes.
ROOL's avatar
ROOL committed
164 165 166 167
 * \param mode      The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or
 *                  #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning).
 *
 * \return          \c 0 on success.
ROOL's avatar
ROOL committed
168
 * \return          A negative error code on failure.
ROOL's avatar
ROOL committed
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
 */
int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
                               const unsigned char nonce[12],
                               mbedtls_chachapoly_mode_t mode );

/**
 * \brief           This function feeds additional data to be authenticated
 *                  into an ongoing ChaCha20-Poly1305 operation.
 *
 *                  The Additional Authenticated Data (AAD), also called
 *                  Associated Data (AD) is only authenticated but not
 *                  encrypted nor included in the encrypted output. It is
 *                  usually transmitted separately from the ciphertext or
 *                  computed locally by each party.
 *
 * \note            This function is called before data is encrypted/decrypted.
 *                  I.e. call this function to process the AAD before calling
 *                  \c mbedtls_chachapoly_update().
 *
 *                  You may call this function multiple times to process
 *                  an arbitrary amount of AAD. It is permitted to call
 *                  this function 0 times, if no AAD is used.
 *
 *                  This function cannot be called any more if data has
 *                  been processed by \c mbedtls_chachapoly_update(),
 *                  or if the context has been finished.
 *
 * \warning         Decryption with the piecewise API is discouraged, see the
 *                  warning on \c mbedtls_chachapoly_init().
 *
ROOL's avatar
ROOL committed
199 200 201
 * \param ctx       The ChaCha20-Poly1305 context. This must be initialized
 *                  and bound to a key.
 * \param aad_len   The length in Bytes of the AAD. The length has no
ROOL's avatar
ROOL committed
202 203
 *                  restrictions.
 * \param aad       Buffer containing the AAD.
ROOL's avatar
ROOL committed
204
 *                  This pointer can be \c NULL if `aad_len == 0`.
ROOL's avatar
ROOL committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
 *
 * \return          \c 0 on success.
 * \return          #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA
 *                  if \p ctx or \p aad are NULL.
 * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
 *                  if the operations has not been started or has been
 *                  finished, or if the AAD has been finished.
 */
int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
                                   const unsigned char *aad,
                                   size_t aad_len );

/**
 * \brief           Thus function feeds data to be encrypted or decrypted
 *                  into an on-going ChaCha20-Poly1305
 *                  operation.
 *
 *                  The direction (encryption or decryption) depends on the
 *                  mode that was given when calling
 *                  \c mbedtls_chachapoly_starts().
 *
 *                  You may call this function multiple times to process
 *                  an arbitrary amount of data. It is permitted to call
 *                  this function 0 times, if no data is to be encrypted
 *                  or decrypted.
 *
 * \warning         Decryption with the piecewise API is discouraged, see the
 *                  warning on \c mbedtls_chachapoly_init().
 *
ROOL's avatar
ROOL committed
234
 * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
ROOL's avatar
ROOL committed
235 236
 * \param len       The length (in bytes) of the data to encrypt or decrypt.
 * \param input     The buffer containing the data to encrypt or decrypt.
ROOL's avatar
ROOL committed
237 238 239 240
 *                  This pointer can be \c NULL if `len == 0`.
 * \param output    The buffer to where the encrypted or decrypted data is
 *                  written. This must be able to hold \p len bytes.
 *                  This pointer can be \c NULL if `len == 0`.
ROOL's avatar
ROOL committed
241 242 243 244 245
 *
 * \return          \c 0 on success.
 * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
 *                  if the operation has not been started or has been
 *                  finished.
ROOL's avatar
ROOL committed
246
 * \return          Another negative error code on other kinds of failure.
ROOL's avatar
ROOL committed
247 248 249 250 251 252 253 254 255 256
 */
int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
                               size_t len,
                               const unsigned char *input,
                               unsigned char *output );

/**
 * \brief           This function finished the ChaCha20-Poly1305 operation and
 *                  generates the MAC (authentication tag).
 *
ROOL's avatar
ROOL committed
257
 * \param ctx       The ChaCha20-Poly1305 context to use. This must be initialized.
ROOL's avatar
ROOL committed
258 259 260 261 262 263 264 265 266
 * \param mac       The buffer to where the 128-bit (16 bytes) MAC is written.
 *
 * \warning         Decryption with the piecewise API is discouraged, see the
 *                  warning on \c mbedtls_chachapoly_init().
 *
 * \return          \c 0 on success.
 * \return          #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE
 *                  if the operation has not been started or has been
 *                  finished.
ROOL's avatar
ROOL committed
267
 * \return          Another negative error code on other kinds of failure.
ROOL's avatar
ROOL committed
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
 */
int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
                               unsigned char mac[16] );

/**
 * \brief           This function performs a complete ChaCha20-Poly1305
 *                  authenticated encryption with the previously-set key.
 *
 * \note            Before using this function, you must set the key with
 *                  \c mbedtls_chachapoly_setkey().
 *
 * \warning         You must never use the same nonce twice with the same key.
 *                  This would void any confidentiality and authenticity
 *                  guarantees for the messages encrypted with the same nonce
 *                  and key.
 *
 * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
ROOL's avatar
ROOL committed
285
 *                  This must be initialized.
ROOL's avatar
ROOL committed
286 287
 * \param length    The length (in bytes) of the data to encrypt or decrypt.
 * \param nonce     The 96-bit (12 bytes) nonce/IV to use.
ROOL's avatar
ROOL committed
288 289
 * \param aad       The buffer containing the additional authenticated
 *                  data (AAD). This pointer can be \c NULL if `aad_len == 0`.
ROOL's avatar
ROOL committed
290 291
 * \param aad_len   The length (in bytes) of the AAD data to process.
 * \param input     The buffer containing the data to encrypt or decrypt.
ROOL's avatar
ROOL committed
292 293 294 295 296
 *                  This pointer can be \c NULL if `ilen == 0`.
 * \param output    The buffer to where the encrypted or decrypted data
 *                  is written. This pointer can be \c NULL if `ilen == 0`.
 * \param tag       The buffer to where the computed 128-bit (16 bytes) MAC
 *                  is written. This must not be \c NULL.
ROOL's avatar
ROOL committed
297 298
 *
 * \return          \c 0 on success.
ROOL's avatar
ROOL committed
299
 * \return          A negative error code on failure.
ROOL's avatar
ROOL committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
 */
int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
                                        size_t length,
                                        const unsigned char nonce[12],
                                        const unsigned char *aad,
                                        size_t aad_len,
                                        const unsigned char *input,
                                        unsigned char *output,
                                        unsigned char tag[16] );

/**
 * \brief           This function performs a complete ChaCha20-Poly1305
 *                  authenticated decryption with the previously-set key.
 *
 * \note            Before using this function, you must set the key with
 *                  \c mbedtls_chachapoly_setkey().
 *
 * \param ctx       The ChaCha20-Poly1305 context to use (holds the key).
ROOL's avatar
ROOL committed
318 319
 * \param length    The length (in Bytes) of the data to decrypt.
 * \param nonce     The \c 96 Bit (\c 12 bytes) nonce/IV to use.
ROOL's avatar
ROOL committed
320
 * \param aad       The buffer containing the additional authenticated data (AAD).
ROOL's avatar
ROOL committed
321
 *                  This pointer can be \c NULL if `aad_len == 0`.
ROOL's avatar
ROOL committed
322 323
 * \param aad_len   The length (in bytes) of the AAD data to process.
 * \param tag       The buffer holding the authentication tag.
ROOL's avatar
ROOL committed
324
 *                  This must be a readable buffer of length \c 16 Bytes.
ROOL's avatar
ROOL committed
325
 * \param input     The buffer containing the data to decrypt.
ROOL's avatar
ROOL committed
326
 *                  This pointer can be \c NULL if `ilen == 0`.
ROOL's avatar
ROOL committed
327
 * \param output    The buffer to where the decrypted data is written.
ROOL's avatar
ROOL committed
328
 *                  This pointer can be \c NULL if `ilen == 0`.
ROOL's avatar
ROOL committed
329 330 331 332
 *
 * \return          \c 0 on success.
 * \return          #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED
 *                  if the data was not authentic.
ROOL's avatar
ROOL committed
333
 * \return          Another negative error code on other kinds of failure.
ROOL's avatar
ROOL committed
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
 */
int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
                                     size_t length,
                                     const unsigned char nonce[12],
                                     const unsigned char *aad,
                                     size_t aad_len,
                                     const unsigned char tag[16],
                                     const unsigned char *input,
                                     unsigned char *output );

#if defined(MBEDTLS_SELF_TEST)
/**
 * \brief           The ChaCha20-Poly1305 checkup routine.
 *
 * \return          \c 0 on success.
 * \return          \c 1 on failure.
 */
int mbedtls_chachapoly_self_test( int verbose );
#endif /* MBEDTLS_SELF_TEST */

#ifdef __cplusplus
}
#endif

#endif /* MBEDTLS_CHACHAPOLY_H */