From a98ff5eadfc6dbbc4f5e0ecf1ac22ab81a877675 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Sun, 15 May 2016 17:28:08 -0300 Subject: [PATCH 01/42] Initial implementation of ChaCha20 --- include/mbedtls/chacha20.h | 169 +++++++ include/mbedtls/config.h | 10 + include/mbedtls/error.h | 1 + library/CMakeLists.txt | 1 + library/Makefile | 3 +- library/chacha20.c | 551 ++++++++++++++++++++++ library/error.c | 9 + library/version_features.c | 6 + programs/test/benchmark.c | 14 +- scripts/generate_errors.pl | 2 +- tests/CMakeLists.txt | 1 + tests/Makefile | 6 +- tests/suites/test_suite_chacha20.data | 2 + tests/suites/test_suite_chacha20.function | 14 + 14 files changed, 784 insertions(+), 5 deletions(-) create mode 100644 include/mbedtls/chacha20.h create mode 100644 library/chacha20.c create mode 100644 tests/suites/test_suite_chacha20.data create mode 100644 tests/suites/test_suite_chacha20.function diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h new file mode 100644 index 000000000..ab10a96a8 --- /dev/null +++ b/include/mbedtls/chacha20.h @@ -0,0 +1,169 @@ +/** + * \file chacha20.h + * + * \brief ChaCha20 cipher. + * + * \author Daniel King + * + * Copyright (C) 2006-2016, ARM Limited, 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_CHACHA20_H +#define MBEDTLS_CHACHA20_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if !defined(MBEDTLS_CHACHA20_ALT) + +#include +#include + +#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x003B /**< Invalid input parameter(s). */ + +typedef struct +{ + uint32_t initial_state[16]; /*! Holds the initial state (before round operations) */ + uint32_t working_state[16]; /*! Holds the working state (after round operations) */ + uint8_t keystream8[64]; /*! Holds leftover keystream bytes */ + size_t keystream_bytes_used; /*! Number of keystream bytes currently used */ +} +mbedtls_chacha20_context; + +/** + * \brief Initialize ChaCha20 context + * + * \param ctx ChaCha20 context to be initialized + */ +void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ); + +/** + * \brief Clear ChaCha20 context + * + * \param ctx ChaCha20 context to be cleared + */ +void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ); + +/** + * \brief Set the ChaCha20 key. + * + * \note The nonce and counter must be set after calling this function, + * before data can be encrypted/decrypted. The nonce and + * counter are set by calling mbedtls_chacha20_starts. + * + * \see mbedtls_chacha20_starts + * + * \param ctx The context to setup. + * \param key Buffer containing the 256-bit key. Must be 32 bytes in length. + * + * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA is returned if ctx or key + * is NULL, or if key_bits is not 128 or 256. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, + const unsigned char key[32] ); + +/** + * \brief Set the ChaCha20 nonce and initial counter value. + * + * \note A ChaCha20 context can be re-used with the same key by + * calling this function to change the nonce and/or initial + * counter value. + * + * \param ctx The ChaCha20 context. + * \param nonce Buffer containing the 96-bit nonce. Must be 12 bytes in size. + * \param counter Initial counter value to use. This is usually 0. + * + * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA is returned if ctx or + * nonce is NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, + const unsigned char nonce[12], + uint32_t counter ); + +/** + * \brief Encrypt or decrypt data. + * + * This function is used to both encrypt and decrypt data. + * + * \note The \p input and \p output buffers may overlap, but only + * if input >= output (i.e. only if input points ahead of + * the output pointer). + * + * \note mbedtls_chacha20_setkey and mbedtls_chacha20_starts must be + * called at least once to setup the context before this function + * can be called. + * + * \param ctx The ChaCha20 context. + * \param size The length (in bytes) to process. This can have any length. + * \param input Buffer containing the input data. + * \param output Buffer containing the output data. + * + * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or + * output pointers are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_chacha20_process( mbedtls_chacha20_context *ctx, + size_t size, + const unsigned char *input, + unsigned char *output ); + +#else /* MBEDTLS_CHACHA20_ALT */ +#include "chacha20_alt.h" +#endif /* MBEDTLS_CHACHA20_ALT */ + +/** + * \brief Encrypt or decrypt a message using ChaCha20. + * + * This function is used the same way for encrypting and + * decrypting data. It's not necessary to specify which + * operation is being performed. + * + * \note The \p input and \p output buffers may overlap, but only + * if input >= output (i.e. only if input points ahead of + * the output pointer). + * + * \param key Buffer containing the 256-bit key. Must be 32 bytes in length. + * \param nonce Buffer containing the 96-bit nonce. Must be 12 bytes in length. + * \param counter The initial counter value. This is usually 0. + * \param data_len The number of bytes to process. + * \param input Buffer containing the input data (data to encrypt or decrypt). + * \param output Buffer to where the processed data is written. + * + * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if key, nonce, input, + * or output is NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_chacha20_crypt( const unsigned char key[32], + const unsigned char nonce[12], + uint32_t counter, + size_t data_len, + const unsigned char* input, + unsigned char* output ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_chacha20_self_test( int verbose ); + +#endif /* MBEDTLS_CHACHA20_H */ diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 7c9acb230..4c8fc3c36 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -274,6 +274,7 @@ //#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT //#define MBEDTLS_CMAC_ALT //#define MBEDTLS_DES_ALT //#define MBEDTLS_DHM_ALT @@ -1861,6 +1862,15 @@ */ #define MBEDTLS_CERTS_C +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +#define MBEDTLS_CHACHA20_C + /** * \def MBEDTLS_CIPHER_C * diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 8b4d3a875..ace0c47a6 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -76,6 +76,7 @@ * SHA1 1 0x0035-0x0035 * SHA256 1 0x0037-0x0037 * SHA512 1 0x0039-0x0039 + * CHACHA20 1 0x003B-0x003B * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 6177ca2b4..78bab7fc7 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -13,6 +13,7 @@ set(src_crypto blowfish.c camellia.c ccm.c + chacha20.c cipher.c cipher_wrap.c cmac.c diff --git a/library/Makefile b/library/Makefile index b155c720e..4fab59846 100644 --- a/library/Makefile +++ b/library/Makefile @@ -50,7 +50,8 @@ endif OBJS_CRYPTO= aes.o aesni.o arc4.o \ asn1parse.o asn1write.o base64.o \ bignum.o blowfish.o camellia.o \ - ccm.o cipher.o cipher_wrap.o \ + ccm.o chacha20.o \ + cipher.o cipher_wrap.o \ cmac.o ctr_drbg.o des.o \ dhm.o ecdh.o ecdsa.o \ ecjpake.o ecp.o \ diff --git a/library/chacha20.c b/library/chacha20.c new file mode 100644 index 000000000..75fd9e915 --- /dev/null +++ b/library/chacha20.c @@ -0,0 +1,551 @@ +/** + * \file chacha20.c + * + * \brief ChaCha20 cipher. + * + * \author Daniel King + * + * Copyright (C) 2006-2016, ARM Limited, 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) + */ +#include "mbedtls/chacha20.h" + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CHACHA20_C) + +#if !defined(MBEDTLS_CHACHA20_ALT) + +#include +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#define BYTES_TO_U32_LE( data, offset ) \ + ( (uint32_t)data[offset] | \ + (uint32_t)( (uint32_t)data[(offset) + 1] << 8 ) | \ + (uint32_t)( (uint32_t)data[(offset) + 2] << 16 ) | \ + (uint32_t)( (uint32_t)data[(offset) + 3] << 24 ) \ + ) + +#define ROTL32( value, amount ) ( (uint32_t)( value << amount ) | ( value >> ( 32 - amount ) ) ) + +#define CHACHA20_CTR_INDEX ( 12U ) + +#define CHACHA20_BLOCK_SIZE_BYTES ( 4U * 16U ) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/** + * \brief ChaCha20 quarter round operation. + * + * The quarter round is defined as follows (from RFC 7539): + * 1. a += b; d ^= a; d <<<= 16; + * 2. c += d; b ^= c; b <<<= 12; + * 3. a += b; d ^= a; d <<<= 8; + * 4. c += d; b ^= c; b <<<= 7; + * + * \param state ChaCha20 state to modify. + * \param a The index of 'a' in the state. + * \param b The index of 'b' in the state. + * \param c The index of 'c' in the state. + * \param d The index of 'd' in the state. + */ +static inline void mbedtls_chacha20_quarter_round( uint32_t state[16], + size_t a, + size_t b, + size_t c, + size_t d ) +{ + /* a += b; d ^= a; d <<<= 16; */ + state[a] += state[b]; + state[d] ^= state[a]; + state[d] = ROTL32( state[d], 16 ); + + /* c += d; b ^= c; b <<<= 12 */ + state[c] += state[d]; + state[b] ^= state[c]; + state[b] = ROTL32( state[b], 12 ); + + /* a += b; d ^= a; d <<<= 8; */ + state[a] += state[b]; + state[d] ^= state[a]; + state[d] = ROTL32( state[d], 8 ); + + /* c += d; b ^= c; b <<<= 7; */ + state[c] += state[d]; + state[b] ^= state[c]; + state[b] = ROTL32( state[b], 7 ); +} + +/** + * \brief Perform the ChaCha20 inner block operation. + * + * This function performs two rounds: the column round and the + * diagonal round. + * + * \param state The ChaCha20 state to update. + */ +static void mbedtls_chacha20_inner_block( uint32_t state[16] ) +{ + mbedtls_chacha20_quarter_round( state, 0, 4, 8, 12 ); + mbedtls_chacha20_quarter_round( state, 1, 5, 9, 13 ); + mbedtls_chacha20_quarter_round( state, 2, 6, 10, 14 ); + mbedtls_chacha20_quarter_round( state, 3, 7, 11, 15 ); + + mbedtls_chacha20_quarter_round( state, 0, 5, 10, 15 ); + mbedtls_chacha20_quarter_round( state, 1, 6, 11, 12 ); + mbedtls_chacha20_quarter_round( state, 2, 7, 8, 13 ); + mbedtls_chacha20_quarter_round( state, 3, 4, 9, 14 ); +} + +/** + * \brief Generates a keystream block. + * + * \param initial_state The initial ChaCha20 state (containing the key, nonce, counter). + * \param working_state This state is used as a temporary working area. + * \param keystream Generated keystream bytes are written to this buffer. + */ +static void mbedtls_chacha20_block( mbedtls_chacha20_context *ctx, + unsigned char keystream[64] ) +{ + size_t i; + size_t offset; + + memcpy( ctx->working_state, + ctx->initial_state, + sizeof(ctx->initial_state) ); + + for ( i = 0U; i < 10U; i++ ) + { + mbedtls_chacha20_inner_block( ctx->working_state ); + } + + ctx->working_state[0] += ctx->initial_state[0]; + ctx->working_state[1] += ctx->initial_state[1]; + ctx->working_state[2] += ctx->initial_state[2]; + ctx->working_state[3] += ctx->initial_state[3]; + ctx->working_state[4] += ctx->initial_state[4]; + ctx->working_state[5] += ctx->initial_state[5]; + ctx->working_state[6] += ctx->initial_state[6]; + ctx->working_state[7] += ctx->initial_state[7]; + ctx->working_state[8] += ctx->initial_state[8]; + ctx->working_state[9] += ctx->initial_state[9]; + ctx->working_state[10] += ctx->initial_state[10]; + ctx->working_state[11] += ctx->initial_state[11]; + ctx->working_state[12] += ctx->initial_state[12]; + ctx->working_state[13] += ctx->initial_state[13]; + ctx->working_state[14] += ctx->initial_state[14]; + ctx->working_state[15] += ctx->initial_state[15]; + + for ( i = 0U; i < 16; i++ ) + { + offset = i * 4U; + + keystream[offset ] = (unsigned char) ctx->working_state[i]; + keystream[offset + 1U] = (unsigned char)( ctx->working_state[i] >> 8 ); + keystream[offset + 2U] = (unsigned char)( ctx->working_state[i] >> 16 ); + keystream[offset + 3U] = (unsigned char)( ctx->working_state[i] >> 24 ); + } +} + +void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) +{ + if ( ctx != NULL ) + { + mbedtls_zeroize( ctx->initial_state, sizeof( ctx->initial_state ) ); + mbedtls_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); + mbedtls_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); + + /* Initially, there's no keystream bytes available */ + ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; + } +} + +void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) +{ + if ( ctx != NULL ) + { + mbedtls_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); + } +} + +int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, + const unsigned char key[32] ) +{ + if ( ( ctx == NULL ) || ( key == NULL ) ) + { + return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + } + + /* ChaCha20 constants - the string "expand 32-byte k" */ + ctx->initial_state[0] = 0x61707865; + ctx->initial_state[1] = 0x3320646e; + ctx->initial_state[2] = 0x79622d32; + ctx->initial_state[3] = 0x6b206574; + + /* Set key */ + ctx->initial_state[4] = BYTES_TO_U32_LE( key, 0 ); + ctx->initial_state[5] = BYTES_TO_U32_LE( key, 4 ); + ctx->initial_state[6] = BYTES_TO_U32_LE( key, 8 ); + ctx->initial_state[7] = BYTES_TO_U32_LE( key, 12 ); + ctx->initial_state[8] = BYTES_TO_U32_LE( key, 16 ); + ctx->initial_state[9] = BYTES_TO_U32_LE( key, 20 ); + ctx->initial_state[10] = BYTES_TO_U32_LE( key, 24 ); + ctx->initial_state[11] = BYTES_TO_U32_LE( key, 28 ); + + return( 0 ); +} + +int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, + const unsigned char nonce[12], + uint32_t counter ) +{ + if ( ( ctx == NULL ) || ( nonce == NULL ) ) + { + return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + } + + /* Counter */ + ctx->initial_state[12] = counter; + + /* Nonce */ + ctx->initial_state[13] = BYTES_TO_U32_LE( nonce, 0 ); + ctx->initial_state[14] = BYTES_TO_U32_LE( nonce, 4 ); + ctx->initial_state[15] = BYTES_TO_U32_LE( nonce, 8 ); + + return( 0 ); +} + +int mbedtls_chacha20_process( mbedtls_chacha20_context *ctx, + size_t size, + const unsigned char *input, + unsigned char *output ) +{ + size_t offset = 0U; + size_t i; + + if ( ( ctx == NULL ) || ( input == NULL ) || ( output == NULL ) ) + { + return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + } + + /* Use leftover keystream bytes, if available */ + while ( ( size > 0U ) && ( ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) ) + { + output[offset] = input[offset] ^ ctx->keystream8[ctx->keystream_bytes_used]; + + ctx->keystream_bytes_used++; + offset++; + size--; + } + + /* Process full blocks */ + while ( size >= CHACHA20_BLOCK_SIZE_BYTES ) + { + mbedtls_chacha20_block( ctx, &output[offset] ); + + for ( i = 0U; i < 64U; i += 8U ) + { + output[offset + i ] ^= input[offset + i ]; + output[offset + i + 1U] ^= input[offset + i + 1U]; + output[offset + i + 2U] ^= input[offset + i + 2U]; + output[offset + i + 3U] ^= input[offset + i + 3U]; + output[offset + i + 4U] ^= input[offset + i + 4U]; + output[offset + i + 5U] ^= input[offset + i + 5U]; + output[offset + i + 6U] ^= input[offset + i + 6U]; + output[offset + i + 7U] ^= input[offset + i + 7U]; + } + + /* Increment counter */ + ctx->initial_state[CHACHA20_CTR_INDEX]++; + + offset += 64U; + size -= 64U; + } + + /* Last (partial) block */ + if ( size > 0U ) + { + mbedtls_chacha20_block( ctx, ctx->keystream8 ); + + for ( i = 0U; i < size; i++) + { + output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; + } + + ctx->keystream_bytes_used = size; + + /* Increment counter */ + ctx->initial_state[CHACHA20_CTR_INDEX]++; + } + + return 0; +} + +#endif /* !MBEDTLS_CHACHA20_ALT */ + +int mbedtls_chacha20_crypt( const unsigned char key[32], + const unsigned char nonce[12], + uint32_t counter, + size_t data_len, + const unsigned char* input, + unsigned char* output ) +{ + mbedtls_chacha20_context ctx; + int result; + + mbedtls_chacha20_init( &ctx ); + + result = mbedtls_chacha20_setkey( &ctx, key ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_chacha20_starts( &ctx, nonce, counter ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_chacha20_process( &ctx, data_len, input, output ); + +cleanup: + mbedtls_chacha20_free( &ctx ); + return result; +} + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char test_keys[2][32] = +{ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + } +}; + +static const unsigned char test_nonces[2][12] = +{ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02 + } +}; + +static const uint32_t test_counters[2] = +{ + 0U, + 1U +}; + +static const unsigned char test_input[2][375] = +{ + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + { + 0x41, 0x6e, 0x79, 0x20, 0x73, 0x75, 0x62, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x49, 0x45, + 0x54, 0x46, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6e, + 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x6f, 0x72, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6f, 0x72, + 0x20, 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, + 0x20, 0x61, 0x6e, 0x20, 0x49, 0x45, 0x54, 0x46, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, + 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x20, + 0x6f, 0x72, 0x20, 0x52, 0x46, 0x43, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x6d, 0x61, 0x64, 0x65, 0x20, 0x77, 0x69, + 0x74, 0x68, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x20, 0x69, 0x73, 0x20, + 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x20, 0x61, 0x6e, 0x20, 0x22, 0x49, + 0x45, 0x54, 0x46, 0x20, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x2e, 0x20, 0x53, 0x75, 0x63, 0x68, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x20, 0x6f, 0x72, 0x61, 0x6c, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, + 0x54, 0x46, 0x20, 0x73, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x65, 0x6c, 0x6c, 0x20, 0x61, 0x73, 0x20, + 0x77, 0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x20, 0x63, + 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x6d, 0x61, + 0x64, 0x65, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, + 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x6f, + 0x72, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x2c, + 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f + } +}; + +static const unsigned char test_output[2][375] = +{ + { + 0x76, 0xb8, 0xe0, 0xad, 0xa0, 0xf1, 0x3d, 0x90, + 0x40, 0x5d, 0x6a, 0xe5, 0x53, 0x86, 0xbd, 0x28, + 0xbd, 0xd2, 0x19, 0xb8, 0xa0, 0x8d, 0xed, 0x1a, + 0xa8, 0x36, 0xef, 0xcc, 0x8b, 0x77, 0x0d, 0xc7, + 0xda, 0x41, 0x59, 0x7c, 0x51, 0x57, 0x48, 0x8d, + 0x77, 0x24, 0xe0, 0x3f, 0xb8, 0xd8, 0x4a, 0x37, + 0x6a, 0x43, 0xb8, 0xf4, 0x15, 0x18, 0xa1, 0x1c, + 0xc3, 0x87, 0xb6, 0x69, 0xb2, 0xee, 0x65, 0x86 + }, + { + 0xa3, 0xfb, 0xf0, 0x7d, 0xf3, 0xfa, 0x2f, 0xde, + 0x4f, 0x37, 0x6c, 0xa2, 0x3e, 0x82, 0x73, 0x70, + 0x41, 0x60, 0x5d, 0x9f, 0x4f, 0x4f, 0x57, 0xbd, + 0x8c, 0xff, 0x2c, 0x1d, 0x4b, 0x79, 0x55, 0xec, + 0x2a, 0x97, 0x94, 0x8b, 0xd3, 0x72, 0x29, 0x15, + 0xc8, 0xf3, 0xd3, 0x37, 0xf7, 0xd3, 0x70, 0x05, + 0x0e, 0x9e, 0x96, 0xd6, 0x47, 0xb7, 0xc3, 0x9f, + 0x56, 0xe0, 0x31, 0xca, 0x5e, 0xb6, 0x25, 0x0d, + 0x40, 0x42, 0xe0, 0x27, 0x85, 0xec, 0xec, 0xfa, + 0x4b, 0x4b, 0xb5, 0xe8, 0xea, 0xd0, 0x44, 0x0e, + 0x20, 0xb6, 0xe8, 0xdb, 0x09, 0xd8, 0x81, 0xa7, + 0xc6, 0x13, 0x2f, 0x42, 0x0e, 0x52, 0x79, 0x50, + 0x42, 0xbd, 0xfa, 0x77, 0x73, 0xd8, 0xa9, 0x05, + 0x14, 0x47, 0xb3, 0x29, 0x1c, 0xe1, 0x41, 0x1c, + 0x68, 0x04, 0x65, 0x55, 0x2a, 0xa6, 0xc4, 0x05, + 0xb7, 0x76, 0x4d, 0x5e, 0x87, 0xbe, 0xa8, 0x5a, + 0xd0, 0x0f, 0x84, 0x49, 0xed, 0x8f, 0x72, 0xd0, + 0xd6, 0x62, 0xab, 0x05, 0x26, 0x91, 0xca, 0x66, + 0x42, 0x4b, 0xc8, 0x6d, 0x2d, 0xf8, 0x0e, 0xa4, + 0x1f, 0x43, 0xab, 0xf9, 0x37, 0xd3, 0x25, 0x9d, + 0xc4, 0xb2, 0xd0, 0xdf, 0xb4, 0x8a, 0x6c, 0x91, + 0x39, 0xdd, 0xd7, 0xf7, 0x69, 0x66, 0xe9, 0x28, + 0xe6, 0x35, 0x55, 0x3b, 0xa7, 0x6c, 0x5c, 0x87, + 0x9d, 0x7b, 0x35, 0xd4, 0x9e, 0xb2, 0xe6, 0x2b, + 0x08, 0x71, 0xcd, 0xac, 0x63, 0x89, 0x39, 0xe2, + 0x5e, 0x8a, 0x1e, 0x0e, 0xf9, 0xd5, 0x28, 0x0f, + 0xa8, 0xca, 0x32, 0x8b, 0x35, 0x1c, 0x3c, 0x76, + 0x59, 0x89, 0xcb, 0xcf, 0x3d, 0xaa, 0x8b, 0x6c, + 0xcc, 0x3a, 0xaf, 0x9f, 0x39, 0x79, 0xc9, 0x2b, + 0x37, 0x20, 0xfc, 0x88, 0xdc, 0x95, 0xed, 0x84, + 0xa1, 0xbe, 0x05, 0x9c, 0x64, 0x99, 0xb9, 0xfd, + 0xa2, 0x36, 0xe7, 0xe8, 0x18, 0xb0, 0x4b, 0x0b, + 0xc3, 0x9c, 0x1e, 0x87, 0x6b, 0x19, 0x3b, 0xfe, + 0x55, 0x69, 0x75, 0x3f, 0x88, 0x12, 0x8c, 0xc0, + 0x8a, 0xaa, 0x9b, 0x63, 0xd1, 0xa1, 0x6f, 0x80, + 0xef, 0x25, 0x54, 0xd7, 0x18, 0x9c, 0x41, 0x1f, + 0x58, 0x69, 0xca, 0x52, 0xc5, 0xb8, 0x3f, 0xa3, + 0x6f, 0xf2, 0x16, 0xb9, 0xc1, 0xd3, 0x00, 0x62, + 0xbe, 0xbc, 0xfd, 0x2d, 0xc5, 0xbc, 0xe0, 0x91, + 0x19, 0x34, 0xfd, 0xa7, 0x9a, 0x86, 0xf6, 0xe6, + 0x98, 0xce, 0xd7, 0x59, 0xc3, 0xff, 0x9b, 0x64, + 0x77, 0x33, 0x8f, 0x3d, 0xa4, 0xf9, 0xcd, 0x85, + 0x14, 0xea, 0x99, 0x82, 0xcc, 0xaf, 0xb3, 0x41, + 0xb2, 0x38, 0x4d, 0xd9, 0x02, 0xf3, 0xd1, 0xab, + 0x7a, 0xc6, 0x1d, 0xd2, 0x9c, 0x6f, 0x21, 0xba, + 0x5b, 0x86, 0x2f, 0x37, 0x30, 0xe3, 0x7c, 0xfd, + 0xc4, 0xfd, 0x80, 0x6c, 0x22, 0xf2, 0x21 + } +}; + +static const size_t test_lengths[2] = +{ + 64U, + 375U +}; + +int mbedtls_chacha20_self_test( int verbose ) +{ + unsigned char output[381]; + size_t i; + int result; + + for ( i = 0U; i < 2U; i++ ) + { + result = mbedtls_chacha20_crypt( test_keys[i], + test_nonces[i], + test_counters[i], + test_lengths[i], + test_input[i], + output ); + if ( result != 0) + { + if ( verbose != 0 ) + { + mbedtls_printf( "ChaCha20 test %zi error code: %i\n", i, result ); + } + + return( -1 ); + } + + if ( 0 != memcmp( output, test_output[i], test_lengths[i] ) ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "ChaCha20 test %zi failed\n", i ); + } + + return( -1 ); + } + } + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* !MBEDTLS_CHACHA20_C */ diff --git a/library/error.c b/library/error.c index 222d85b62..2aaf359ef 100644 --- a/library/error.c +++ b/library/error.c @@ -69,6 +69,10 @@ #include "mbedtls/ccm.h" #endif +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + #if defined(MBEDTLS_CIPHER_C) #include "mbedtls/cipher.h" #endif @@ -653,6 +657,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "CCM - CCM hardware accelerator failed" ); #endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CHACHA20_C) + if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" ); +#endif /* MBEDTLS_CHACHA20_C */ + #if defined(MBEDTLS_CMAC_C) if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) ) mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" ); diff --git a/library/version_features.c b/library/version_features.c index a452caf5e..febd506b7 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -99,6 +99,9 @@ static const char *features[] = { #if defined(MBEDTLS_CCM_ALT) "MBEDTLS_CCM_ALT", #endif /* MBEDTLS_CCM_ALT */ +#if defined(MBEDTLS_CHACHA20_ALT) + "MBEDTLS_CHACHA20_ALT", +#endif /* MBEDTLS_CHACHA20_ALT */ #if defined(MBEDTLS_CMAC_ALT) "MBEDTLS_CMAC_ALT", #endif /* MBEDTLS_CMAC_ALT */ @@ -537,6 +540,9 @@ static const char *features[] = { #if defined(MBEDTLS_CERTS_C) "MBEDTLS_CERTS_C", #endif /* MBEDTLS_CERTS_C */ +#if defined(MBEDTLS_CHACHA20_C) + "MBEDTLS_CHACHA20_C", +#endif /* MBEDTLS_CHACHA20_C */ #if defined(MBEDTLS_CIPHER_C) "MBEDTLS_CIPHER_C", #endif /* MBEDTLS_CIPHER_C */ diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index cecf3e363..bc473cf86 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -59,6 +59,7 @@ int main( void ) #include "mbedtls/aes.h" #include "mbedtls/blowfish.h" #include "mbedtls/camellia.h" +#include "mbedtls/chacha20.h" #include "mbedtls/gcm.h" #include "mbedtls/ccm.h" #include "mbedtls/cmac.h" @@ -93,7 +94,7 @@ int main( void ) #define OPTIONS \ "md4, md5, ripemd160, sha1, sha256, sha512,\n" \ - "arc4, des3, des, camellia, blowfish,\n" \ + "arc4, des3, des, camellia, blowfish, chacha20,\n" \ "aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,\n" \ "havege, ctr_drbg, hmac_drbg\n" \ "rsa, dhm, ecdsa, ecdh.\n" @@ -229,7 +230,7 @@ typedef struct { char md4, md5, ripemd160, sha1, sha256, sha512, arc4, des3, des, aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac, - camellia, blowfish, + camellia, blowfish, chacha20, havege, ctr_drbg, hmac_drbg, rsa, dhm, ecdsa, ecdh; } todo_list; @@ -286,6 +287,8 @@ int main( int argc, char *argv[] ) todo.camellia = 1; else if( strcmp( argv[i], "blowfish" ) == 0 ) todo.blowfish = 1; + else if( strcmp( argv[i], "chacha20" ) == 0 ) + todo.chacha20 = 1; else if( strcmp( argv[i], "havege" ) == 0 ) todo.havege = 1; else if( strcmp( argv[i], "ctr_drbg" ) == 0 ) @@ -520,6 +523,13 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_CHACHA20_C) + if ( todo.chacha20 ) + { + TIME_AND_TSC( "ChaCha20", mbedtls_chacha20_crypt( buf, buf, 0U, BUFSIZE, buf, buf ) ); + } +#endif + #if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC) if( todo.blowfish ) { diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index ac0fbff05..36ee60b72 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -30,7 +30,7 @@ if( @ARGV ) { my $error_format_file = $data_dir.'/error.fmt'; my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH - CAMELLIA CCM CMAC CTR_DRBG DES + CAMELLIA CCM CHACHA20 CMAC CTR_DRBG DES ENTROPY GCM HMAC_DRBG MD2 MD4 MD5 NET OID PADLOCK PBKDF2 RIPEMD160 SHA1 SHA256 SHA512 THREADING XTEA ); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 16e19a927..1525bc2a3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -54,6 +54,7 @@ add_test_suite(base64) add_test_suite(blowfish) add_test_suite(camellia) add_test_suite(ccm) +add_test_suite(chacha20) add_test_suite(cipher cipher.aes) add_test_suite(cipher cipher.arc4) add_test_suite(cipher cipher.blowfish) diff --git a/tests/Makefile b/tests/Makefile index d85617fdc..233259b7a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -50,7 +50,7 @@ APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ test_suite_arc4$(EXEXT) test_suite_asn1write$(EXEXT) \ test_suite_base64$(EXEXT) test_suite_blowfish$(EXEXT) \ test_suite_camellia$(EXEXT) test_suite_ccm$(EXEXT) \ - test_suite_cmac$(EXEXT) \ + test_suite_chacha20$(EXEXT) test_suite_cmac$(EXEXT) \ test_suite_cipher.aes$(EXEXT) \ test_suite_cipher.arc4$(EXEXT) test_suite_cipher.ccm$(EXEXT) \ test_suite_cipher.gcm$(EXEXT) \ @@ -237,6 +237,10 @@ test_suite_ccm$(EXEXT): test_suite_ccm.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_chacha20$(EXEXT): test_suite_chacha20.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_cmac$(EXEXT): test_suite_cmac.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_chacha20.data b/tests/suites/test_suite_chacha20.data new file mode 100644 index 000000000..79f0408a2 --- /dev/null +++ b/tests/suites/test_suite_chacha20.data @@ -0,0 +1,2 @@ +ChaCha20 Selftest +chacha20_self_test: diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function new file mode 100644 index 000000000..2825a6148 --- /dev/null +++ b/tests/suites/test_suite_chacha20.function @@ -0,0 +1,14 @@ +/* BEGIN_HEADER */ +#include "mbedtls/chacha20.h" +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_CHACHA20_C + * END_DEPENDENCIES + */ +/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ +void chacha20_self_test() +{ + TEST_ASSERT( mbedtls_chacha20_self_test( 0 ) == 0 ); +} +/* END_CASE */ \ No newline at end of file From 0fe7b5b8c5a97c633315b3d4a90bd40a7a9efa51 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Sun, 15 May 2016 19:56:20 -0300 Subject: [PATCH 02/42] Add ChaCha20 to the Cipher module --- include/mbedtls/chacha20.h | 2 +- include/mbedtls/cipher.h | 4 +- library/chacha20.c | 4 +- library/cipher.c | 31 ++++++ library/cipher_wrap.c | 73 ++++++++++++ tests/CMakeLists.txt | 1 + tests/Makefile | 9 ++ tests/suites/test_suite_cipher.chacha20.data | 111 +++++++++++++++++++ 8 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 tests/suites/test_suite_cipher.chacha20.data diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index ab10a96a8..d23618ee0 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -121,7 +121,7 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, * output pointers are NULL. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_chacha20_process( mbedtls_chacha20_context *ctx, +int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, size_t size, const unsigned char *input, unsigned char *output ); diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index 3ee2ab7db..c5a50c0d2 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -86,6 +86,7 @@ typedef enum { MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ + MBEDTLS_CIPHER_ID_CHACHA20, /**< The Chacha20 cipher. */ } mbedtls_cipher_id_t; /** @@ -145,6 +146,7 @@ typedef enum { MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_CHACHA20, /**< Chacha20 stream cipher. */ } mbedtls_cipher_type_t; /** Supported cipher modes. */ @@ -190,7 +192,7 @@ enum { /** Maximum length of any IV, in Bytes. */ #define MBEDTLS_MAX_IV_LENGTH 16 /** Maximum block size of any cipher, in Bytes. */ -#define MBEDTLS_MAX_BLOCK_LENGTH 16 +#define MBEDTLS_MAX_BLOCK_LENGTH 64 /** * Base cipher information (opaque struct). diff --git a/library/chacha20.c b/library/chacha20.c index 75fd9e915..8206a3bf0 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -245,7 +245,7 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, return( 0 ); } -int mbedtls_chacha20_process( mbedtls_chacha20_context *ctx, +int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, size_t size, const unsigned char *input, unsigned char *output ) @@ -333,7 +333,7 @@ int mbedtls_chacha20_crypt( const unsigned char key[32], if ( result != 0 ) goto cleanup; - result = mbedtls_chacha20_process( &ctx, data_len, input, output ); + result = mbedtls_chacha20_update( &ctx, data_len, input, output ); cleanup: mbedtls_chacha20_free( &ctx ); diff --git a/library/cipher.c b/library/cipher.c index a5cd61cdf..68d0c10ff 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -46,6 +46,10 @@ #include "mbedtls/ccm.h" #endif +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + #if defined(MBEDTLS_CMAC_C) #include "mbedtls/cmac.h" #endif @@ -231,6 +235,18 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } +#if defined(MBEDTLS_CHACHA20_C) + if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) + { + if ( 0 != mbedtls_chacha20_starts( (mbedtls_chacha20_context*)ctx->cipher_ctx, + iv, + 0U ) ) /* Initial counter value */ + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + } +#endif + memcpy( ctx->iv, iv, actual_iv_size ); ctx->iv_size = actual_iv_size; @@ -314,6 +330,16 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } + +#if defined(MBEDTLS_CHACHA20_C) + if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) + { + *olen = ilen; + return mbedtls_chacha20_update( (mbedtls_chacha20_context*) ctx->cipher_ctx, + ilen, input, output ); + } +#endif + #if defined(MBEDTLS_CIPHER_MODE_CBC) if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) { @@ -646,6 +672,11 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, return( 0 ); } + if ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) + { + return( 0 ); + } + if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) { if( ctx->unprocessed_len != 0 ) diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index dc76af8ff..f4e7964df 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -53,6 +53,10 @@ #include "mbedtls/blowfish.h" #endif +#if defined(MBEDTLS_CHACHA20_C) +#include "mbedtls/chacha20.h" +#endif + #if defined(MBEDTLS_GCM_C) #include "mbedtls/gcm.h" #endif @@ -1283,6 +1287,71 @@ static const mbedtls_cipher_info_t arc4_128_info = { }; #endif /* MBEDTLS_ARC4_C */ +#if defined(MBEDTLS_CHACHA20_C) + +static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + if( key_bitlen != 256U ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if ( 0 != mbedtls_chacha20_setkey( (mbedtls_chacha20_context*)ctx, key ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( 0 ); +} + +static void * chacha20_ctx_alloc( void ) +{ + mbedtls_chacha20_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_chacha20_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_chacha20_init( ctx ); + + return( ctx ); +} + +static void chacha20_ctx_free( void *ctx ) +{ + mbedtls_chacha20_free( (mbedtls_chacha20_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t chacha20_base_info = { + MBEDTLS_CIPHER_ID_CHACHA20, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + chacha20_setkey_wrap, + chacha20_setkey_wrap, + chacha20_ctx_alloc, + chacha20_ctx_free +}; +static const mbedtls_cipher_info_t chacha20_info = { + MBEDTLS_CIPHER_CHACHA20, + MBEDTLS_MODE_NONE, + 256, + "CHACHA20", + 12, + 0, + 64, + &chacha20_base_info +}; +#endif /* MBEDTLS_CHACHA20_C */ + #if defined(MBEDTLS_CIPHER_NULL_CIPHER) static int null_crypt_stream( void *ctx, size_t length, const unsigned char *input, @@ -1438,6 +1507,10 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = #endif #endif /* MBEDTLS_DES_C */ +#if defined(MBEDTLS_CHACHA20_C) + { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, +#endif + #if defined(MBEDTLS_CIPHER_NULL_CIPHER) { MBEDTLS_CIPHER_NULL, &null_cipher_info }, #endif /* MBEDTLS_CIPHER_NULL_CIPHER */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1525bc2a3..3821657ae 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,6 +60,7 @@ add_test_suite(cipher cipher.arc4) add_test_suite(cipher cipher.blowfish) add_test_suite(cipher cipher.camellia) add_test_suite(cipher cipher.ccm) +add_test_suite(cipher cipher.chacha20) add_test_suite(cipher cipher.des) add_test_suite(cipher cipher.gcm) add_test_suite(cipher cipher.null) diff --git a/tests/Makefile b/tests/Makefile index 233259b7a..34a0a8915 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -53,6 +53,7 @@ APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ test_suite_chacha20$(EXEXT) test_suite_cmac$(EXEXT) \ test_suite_cipher.aes$(EXEXT) \ test_suite_cipher.arc4$(EXEXT) test_suite_cipher.ccm$(EXEXT) \ + test_suite_cipher.chacha20$(EXEXT) \ test_suite_cipher.gcm$(EXEXT) \ test_suite_cipher.blowfish$(EXEXT) \ test_suite_cipher.camellia$(EXEXT) \ @@ -125,6 +126,10 @@ test_suite_cipher.ccm.c : suites/test_suite_cipher.function suites/test_suite_ci echo " Gen $@" perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.ccm +test_suite_cipher.chacha20.c : suites/test_suite_cipher.function suites/test_suite_cipher.chacha20.data scripts/generate_code.pl suites/helpers.function suites/main_test.function + echo " Gen $@" + perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.chacha20 + test_suite_cipher.gcm.c : suites/test_suite_cipher.function suites/test_suite_cipher.gcm.data scripts/generate_code.pl suites/helpers.function suites/main_test.function echo " Gen $@" perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.gcm @@ -257,6 +262,10 @@ test_suite_cipher.ccm$(EXEXT): test_suite_cipher.ccm.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_cipher.chacha20$(EXEXT): test_suite_cipher.chacha20.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_cipher.gcm$(EXEXT): test_suite_cipher.gcm.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_cipher.chacha20.data b/tests/suites/test_suite_cipher.chacha20.data new file mode 100644 index 000000000..5f3e07d0b --- /dev/null +++ b/tests/suites/test_suite_cipher.chacha20.data @@ -0,0 +1,111 @@ +Decrypt empty buffer +depends_on:MBEDTLS_CHACHA20_C: +dec_empty_buf: + +ChaCha20 Encrypt and decrypt 0 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:0:-1 + +ChaCha20 Encrypt and decrypt 1 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:1:-1 + +ChaCha20 Encrypt and decrypt 2 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:2:-1 + +ChaCha20 Encrypt and decrypt 7 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:7:-1 + +ChaCha20 Encrypt and decrypt 8 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:8:-1 + +ChaCha20 Encrypt and decrypt 9 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:9:-1 + +ChaCha20 Encrypt and decrypt 15 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:15:-1 + +ChaCha20 Encrypt and decrypt 16 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:16:-1 + +ChaCha20 Encrypt and decrypt 17 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:17:-1 + +ChaCha20 Encrypt and decrypt 31 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:31:-1 + +ChaCha20 Encrypt and decrypt 32 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:32:-1 + +ChaCha20 Encrypt and decrypt 33 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:33:-1 + +ChaCha20 Encrypt and decrypt 47 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:47:-1 + +ChaCha20 Encrypt and decrypt 48 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:48:-1 + +ChaCha20 Encrypt and decrypt 49 bytes +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:49:-1 + +ChaCha20 Encrypt and decrypt 0 bytes in multiple parts 1 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:0:0:-1:0:0:0:0 + +ChaCha20 Encrypt and decrypt 1 bytes in multiple parts 1 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:1:0:-1:1:0:1:0 + +ChaCha20 Encrypt and decrypt 1 bytes in multiple parts 2 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:0:1:-1:0:1:0:1 + +ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 1 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:0:-1:16:0:16:0 + +ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 2 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:0:16:-1:0:16:0:16 + +ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 3 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:1:15:-1:1:15:1:15 + +ChaCha20 Encrypt and decrypt 16 bytes in multiple parts 4 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:15:1:-1:15:1:15:1 + +ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 1 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:15:7:-1:15:7:15:7 + +ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 2 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:7:15:-1:7:15:7:15 + +ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 3 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:6:-1:16:6:16:6 + +ChaCha20 Encrypt and decrypt 22 bytes in multiple parts 4 +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:6:16:-1:6:16:6:16 + +ChaCha20 Encrypt and decrypt 32 bytes in multiple parts +depends_on:MBEDTLS_CHACHA20_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20:256:16:16:-1:16:16:16:16 From 5d77eaa2330d0c4d422fc01635256011bd3fa073 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Mon, 16 May 2016 18:25:45 -0300 Subject: [PATCH 03/42] Add Poly1305 authenticator algorithm (RFC 7539) Test vectors are included from RFC 7539. Poly1305 is also added to the benchmark program. --- include/mbedtls/config.h | 10 + include/mbedtls/error.h | 1 + include/mbedtls/poly1305.h | 142 ++++++ library/CMakeLists.txt | 1 + library/Makefile | 10 +- library/error.c | 9 + library/poly1305.c | 518 ++++++++++++++++++++++ library/version_features.c | 6 + programs/test/benchmark.c | 14 +- scripts/generate_errors.pl | 2 +- tests/CMakeLists.txt | 1 + tests/Makefile | 5 + tests/suites/test_suite_poly1305.data | 51 +++ tests/suites/test_suite_poly1305.function | 35 ++ 14 files changed, 798 insertions(+), 7 deletions(-) create mode 100644 include/mbedtls/poly1305.h create mode 100644 library/poly1305.c create mode 100644 tests/suites/test_suite_poly1305.data create mode 100644 tests/suites/test_suite_poly1305.function diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 4c8fc3c36..7d0960a29 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -283,6 +283,7 @@ //#define MBEDTLS_MD2_ALT //#define MBEDTLS_MD4_ALT //#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT //#define MBEDTLS_RIPEMD160_ALT //#define MBEDTLS_RSA_ALT //#define MBEDTLS_SHA1_ALT @@ -2398,6 +2399,15 @@ */ #define MBEDTLS_PLATFORM_C +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + */ +#define MBEDTLS_POLY1305_C + /** * \def MBEDTLS_RIPEMD160_C * diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index ace0c47a6..feeda79ed 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -77,6 +77,7 @@ * SHA256 1 0x0037-0x0037 * SHA512 1 0x0039-0x0039 * CHACHA20 1 0x003B-0x003B + * POLY1305 1 0x0041-0x0041 * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h new file mode 100644 index 000000000..1aa55aeee --- /dev/null +++ b/include/mbedtls/poly1305.h @@ -0,0 +1,142 @@ +/** + * \file poly1305.h + * + * \brief Poly1305 authenticator algorithm. + * + * Copyright (C) 2006-2016, ARM Limited, 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_POLY1305_H +#define MBEDTLS_POLY1305_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +#if !defined(MBEDTLS_POLY1305_ALT) + +#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0041 /**< Invalid input parameter(s). */ + +typedef struct +{ + uint32_t r[4]; /** Stores the value for 'r' (low 128 bits of the key) */ + uint32_t s[4]; /** Stores the value for 's' (high 128 bits of the key) */ + uint32_t acc[5]; /** Accumulator number */ + uint8_t queue[16]; /** Stores partial block data */ + size_t queue_len; /** Number of bytes stored in 'queue'. Always less than 16 */ +} +mbedtls_poly1305_context; + +/** + * \brief Initialize a Poly1305 context + * + * \param ctx The Poly1305 context to be initialized + */ +void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ); + +/** + * \brief Clear a Poly1305 context + * + * \param ctx The Poly1305 context to be cleared + */ +void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); + +/** + * \brief Set the Poly1305 authentication key. + * + * \warning The key should be unique, and \b MUST be + * unpredictable for each invocation of Poly1305. + * + * \param ctx The Poly1305 context. + * \param key Buffer containing the 256-bit key. + * + * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx + * or key are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx, + const unsigned char key[32] ); + +/** + * \brief Process data with Poly1305. + * + * This function can be called multiple times to process + * a stream of data. + * + * \param ctx The Poly1305 context. + * \param ilen The input length (in bytes). Any value is accepted. + * \param input Buffer containing the input data to Process. + * + * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx + * or input are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, + size_t ilen, + const unsigned char *input ); + +/** + * \brief Generate the Poly1305 MAC. + * + * \param ctx The Poly1305 context. + * \param mac Buffer to where the MAC is written. Must be big enough + * to hold the 16-byte MAC. + * + * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx + * or mac are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, + unsigned char mac[16] ); + +#else /* MBEDTLS_POLY1305_ALT */ +#include "poly1305_alt.h" +#endif /* MBEDTLS_POLY1305_ALT */ + +/** + * \brief Generate the Poly1305 MAC of some data with the given key. + * + * \warning The key should be unique, and \b MUST be + * unpredictable for each invocation of Poly1305. + * + * \param key Buffer containing the 256-bit (32 bytes) key. + * \param ilen The length of the input data (in bytes). + * \param input Buffer containing the input data to process. + * \param mac Buffer to where the 128-bit (16 bytes) MAC is written. + * + * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if key, + * input, or mac are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_poly1305_mac( const unsigned char key[32], + size_t ilen, + const unsigned char *input, + unsigned char mac[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_poly1305_self_test( int verbose ); + +#endif /* MBEDTLS_POLY1305_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 78bab7fc7..251b6c625 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -48,6 +48,7 @@ set(src_crypto pkwrite.c platform.c platform_util.c + poly1305.c ripemd160.c rsa.c rsa_internal.c diff --git a/library/Makefile b/library/Makefile index 4fab59846..5fd693b25 100644 --- a/library/Makefile +++ b/library/Makefile @@ -63,11 +63,11 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \ padlock.o pem.o pk.o \ pk_wrap.o pkcs12.o pkcs5.o \ pkparse.o pkwrite.o platform.o \ - platform_util.o ripemd160.o rsa_internal.o \ - rsa.o sha1.o sha256.o \ - sha512.o threading.o timing.o \ - version.o version_features.o \ - xtea.o + platform_util.o poly1305.o \ + ripemd160.o rsa_internal.o rsa.o \ + sha1.o sha256.o sha512.o \ + threading.o timing.o version.o \ + version_features.o xtea.o OBJS_X509= certs.o pkcs11.o x509.o \ x509_create.o x509_crl.o x509_crt.o \ diff --git a/library/error.c b/library/error.c index 2aaf359ef..12bd2101b 100644 --- a/library/error.c +++ b/library/error.c @@ -153,6 +153,10 @@ #include "mbedtls/pkcs5.h" #endif +#if defined(MBEDTLS_POLY1305_C) +#include "mbedtls/poly1305.h" +#endif + #if defined(MBEDTLS_RIPEMD160_C) #include "mbedtls/ripemd160.h" #endif @@ -774,6 +778,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); #endif /* MBEDTLS_PADLOCK_C */ +#if defined(MBEDTLS_POLY1305_C) + if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" ); +#endif /* MBEDTLS_POLY1305_C */ + #if defined(MBEDTLS_RIPEMD160_C) if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) ) mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" ); diff --git a/library/poly1305.c b/library/poly1305.c new file mode 100644 index 000000000..9a61a85ce --- /dev/null +++ b/library/poly1305.c @@ -0,0 +1,518 @@ +/** + * \file poly1305.c + * + * \brief Poly1305 authentication algorithm. + * + * Copyright (C) 2006-2016, ARM Limited, 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) + */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_POLY1305_C) + +#if !defined(MBEDTLS_POLY1305_ALT) + +#include "mbedtls/poly1305.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#define POLY1305_BLOCK_SIZE_BYTES ( 16U ) + +#define BYTES_TO_U32_LE( data, offset ) \ + ( (uint32_t)data[offset] | \ + (uint32_t)( (uint32_t)data[(offset) + 1] << 8 ) | \ + (uint32_t)( (uint32_t)data[(offset) + 2] << 16 ) | \ + (uint32_t)( (uint32_t)data[(offset) + 3] << 24 ) \ + ) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/** + * \brief Process blocks with Poly1305. + * + * \param ctx The Poly1305 context. + * \param nblocks Number of blocks to process. Note that this function + * only processes full blocks. + * \param input Buffer containing the input block(s). + * \param needs_padding Set to 0 if the padding bit has already been applied + * to the input data before calling this function. + * Otherwise, set this parameter to 1. + */ +static void mbedtls_poly1305_process( mbedtls_poly1305_context *ctx, + size_t nblocks, + const unsigned char *input, + uint32_t needs_padding ) +{ + uint64_t d0, d1, d2, d3; + uint32_t acc0, acc1, acc2, acc3, acc4; + uint32_t r0, r1, r2, r3; + uint32_t rs1, rs2, rs3; + size_t offset = 0U; + size_t i; + + r0 = ctx->r[0]; + r1 = ctx->r[1]; + r2 = ctx->r[2]; + r3 = ctx->r[3]; + + rs1 = r1 + ( r1 >> 2U ); + rs2 = r2 + ( r2 >> 2U ); + rs3 = r3 + ( r3 >> 2U ); + + acc0 = ctx->acc[0]; + acc1 = ctx->acc[1]; + acc2 = ctx->acc[2]; + acc3 = ctx->acc[3]; + acc4 = ctx->acc[4]; + + /* Process full blocks */ + for ( i = 0U; i < nblocks; i++ ) + { + /* Compute: acc += block */ + /* Note that the input block is treated as a 128-bit little-endian integer */ + d0 = (uint64_t)acc0 + BYTES_TO_U32_LE( input, offset + 0 ); + d1 = (uint64_t)acc1 + BYTES_TO_U32_LE( input, offset + 4 ) + ( d0 >> 32U ); + d2 = (uint64_t)acc2 + BYTES_TO_U32_LE( input, offset + 8 ) + ( d1 >> 32U ); + d3 = (uint64_t)acc3 + BYTES_TO_U32_LE( input, offset + 12 ) + ( d2 >> 32U ); + acc0 = (uint32_t)d0; + acc1 = (uint32_t)d1; + acc2 = (uint32_t)d2; + acc3 = (uint32_t)d3; + acc4 += (uint32_t)( d3 >> 32U ) + needs_padding; + + /* Compute: acc *= r */ + d0 = ( (uint64_t)acc0 * r0 ) + + ( (uint64_t)acc1 * rs3 ) + + ( (uint64_t)acc2 * rs2 ) + + ( (uint64_t)acc3 * rs1 ); + d1 = ( (uint64_t)acc0 * r1 ) + + ( (uint64_t)acc1 * r0 ) + + ( (uint64_t)acc2 * rs3 ) + + ( (uint64_t)acc3 * rs2 ) + + ( (uint64_t)acc4 * rs1 ); + d2 = ( (uint64_t)acc0 * r2 ) + + ( (uint64_t)acc1 * r1 ) + + ( (uint64_t)acc2 * r0 ) + + ( (uint64_t)acc3 * rs3 ) + + ( (uint64_t)acc4 * rs2 ); + d3 = ( (uint64_t)acc0 * r3 ) + + ( (uint64_t)acc1 * r2 ) + + ( (uint64_t)acc2 * r1 ) + + ( (uint64_t)acc3 * r0 ) + + ( (uint64_t)acc4 * rs3 ); + acc4 *= r0; + + /* Compute: acc %= (2^130 - 5) (partial remainder) */ + d1 += ( d0 >> 32 ); + d2 += ( d1 >> 32 ); + d3 += ( d2 >> 32 ); + acc0 = (uint32_t)d0; + acc1 = (uint32_t)d1; + acc2 = (uint32_t)d2; + acc3 = (uint32_t)d3; + acc4 = (uint32_t)( d3 >> 32 ) + acc4; + + d0 = (uint64_t)acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU ); + acc4 &= 3U; + acc0 = (uint32_t)d0; + d0 = (uint64_t)acc1 + ( d0 >> 32U ); + acc1 = (uint32_t)d0; + d0 = (uint64_t)acc2 + ( d0 >> 32U ); + acc2 = (uint32_t)d0; + d0 = (uint64_t)acc3 + ( d0 >> 32U ); + acc3 = (uint32_t)d0; + d0 = (uint64_t)acc4 + ( d0 >> 32U ); + acc4 = (uint32_t)d0; + + offset += POLY1305_BLOCK_SIZE_BYTES; + } + + ctx->acc[0] = acc0; + ctx->acc[1] = acc1; + ctx->acc[2] = acc2; + ctx->acc[3] = acc3; + ctx->acc[4] = acc4; +} + +/** + * \brief Compute the Poly1305 MAC + * + * \param ctx The Poly1305 context. + * \param mac The buffer to where the MAC is written. Must be + * big enough to contain the 16-byte MAC. + */ +static void mbedtls_poly1305_compute_mac( const mbedtls_poly1305_context *ctx, + unsigned char mac[16] ) +{ + uint64_t d; + uint32_t g0, g1, g2, g3, g4; + uint32_t acc0, acc1, acc2, acc3, acc4; + uint32_t mask; + uint32_t mask_inv; + + acc0 = ctx->acc[0]; + acc1 = ctx->acc[1]; + acc2 = ctx->acc[2]; + acc3 = ctx->acc[3]; + acc4 = ctx->acc[4]; + + /* Before adding 's' we need to ensure that the accumulator is mod 2^130 - 5. + * We do this by calculating acc - (2^130 - 5), then checking if + * the 131st bit is set. If it is, then reduce: acc -= (2^130 - 5) + */ + + /* Calculate acc + -(2^130 - 5) */ + d = ( (uint64_t)acc0 + 5U ); + g0 = (uint32_t)d; + d = ( (uint64_t)acc1 + ( d >> 32 ) ); + g1 = (uint32_t)d; + d = ( (uint64_t)acc2 + ( d >> 32 ) ); + g2 = (uint32_t)d; + d = ( (uint64_t)acc3 + ( d >> 32 ) ); + g3 = (uint32_t)d; + g4 = acc4 + (uint32_t)( d >> 32U ); + + /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ + mask = (uint32_t)0U - ( g4 >> 2U ); + mask_inv = ~mask; + + /* If 131st bit is set then acc=g, otherwise, acc is unmodified */ + acc0 = ( acc0 & mask_inv ) | ( g0 & mask ); + acc1 = ( acc1 & mask_inv ) | ( g1 & mask ); + acc2 = ( acc2 & mask_inv ) | ( g2 & mask ); + acc3 = ( acc3 & mask_inv ) | ( g3 & mask ); + + /* Add 's' */ + d = (uint64_t)acc0 + ctx->s[0]; + acc0 = (uint32_t)d; + d = (uint64_t)acc1 + ctx->s[1] + ( d >> 32U ); + acc1 = (uint32_t)d; + d = (uint64_t)acc2 + ctx->s[2] + ( d >> 32U ); + acc2 = (uint32_t)d; + acc3 += ctx->s[3] + (uint32_t)( d >> 32U ); + + /* Compute MAC (128 least significant bits of the accumulator) */ + mac[0] = (uint8_t)acc0; + mac[1] = (uint8_t)( acc0 >> 8 ); + mac[2] = (uint8_t)( acc0 >> 16 ); + mac[3] = (uint8_t)( acc0 >> 24 ); + mac[4] = (uint8_t)acc1; + mac[5] = (uint8_t)( acc1 >> 8 ); + mac[6] = (uint8_t)( acc1 >> 16 ); + mac[7] = (uint8_t)( acc1 >> 24 ); + mac[8] = (uint8_t)acc2; + mac[9] = (uint8_t)( acc2 >> 8 ); + mac[10] = (uint8_t)( acc2 >> 16 ); + mac[11] = (uint8_t)( acc2 >> 24 ); + mac[12] = (uint8_t)acc3; + mac[13] = (uint8_t)( acc3 >> 8 ); + mac[14] = (uint8_t)( acc3 >> 16 ); + mac[15] = (uint8_t)( acc3 >> 24 ); +} + +void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) +{ + if ( ctx != NULL ) + { + mbedtls_zeroize( ctx, sizeof(mbedtls_poly1305_context) ); + } +} + +void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) +{ + if ( ctx != NULL ) + { + mbedtls_zeroize( ctx, sizeof(mbedtls_poly1305_context) ); + } +} + +int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx, + const unsigned char key[32] ) +{ + if ( ctx == NULL ) + { + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } + + /* r &= 0x0ffffffc0ffffffc0ffffffc0fffffff */ + ctx->r[0] = BYTES_TO_U32_LE( key, 0 ) & 0x0FFFFFFFU; + ctx->r[1] = BYTES_TO_U32_LE( key, 4 ) & 0x0FFFFFFCU; + ctx->r[2] = BYTES_TO_U32_LE( key, 8 ) & 0x0FFFFFFCU; + ctx->r[3] = BYTES_TO_U32_LE( key, 12 ) & 0x0FFFFFFCU; + + ctx->s[0] = BYTES_TO_U32_LE( key, 16 ); + ctx->s[1] = BYTES_TO_U32_LE( key, 20 ); + ctx->s[2] = BYTES_TO_U32_LE( key, 24 ); + ctx->s[3] = BYTES_TO_U32_LE( key, 28 ); + + /* Initial accumulator state */ + ctx->acc[0] = 0U; + ctx->acc[1] = 0U; + ctx->acc[2] = 0U; + ctx->acc[3] = 0U; + + return 0; +} + +int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, + size_t ilen, + const unsigned char* input ) +{ + size_t offset = 0U; + size_t remaining = ilen; + size_t queue_free_len; + size_t nblocks; + + if ( ( ctx == NULL ) || ( input == NULL ) ) + { + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } + + if ( ctx->queue_len > 0U ) + { + queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); + + if ( ilen < queue_free_len ) + { + /* Not enough data to complete the block. + * Store this data with the other leftovers. + */ + memcpy( &ctx->queue[ctx->queue_len], + input, + ilen ); + + ctx->queue_len += ilen; + + remaining = 0U; + } + else + { + /* Enough data to produce a complete block */ + memcpy( &ctx->queue[ctx->queue_len], + input, + queue_free_len ); + + ctx->queue_len = 0U; + + mbedtls_poly1305_process( ctx, + 1U, + ctx->queue, + 1U ); /* add padding bit */ + + offset += queue_free_len; + remaining -= queue_free_len; + } + } + + if ( remaining >= POLY1305_BLOCK_SIZE_BYTES ) + { + nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; + + mbedtls_poly1305_process( ctx, nblocks, &input[offset], 1U ); + + offset += nblocks * POLY1305_BLOCK_SIZE_BYTES; + remaining %= POLY1305_BLOCK_SIZE_BYTES; + } + + if ( remaining > 0U ) + { + /* Store partial block */ + ctx->queue_len = remaining; + memcpy( ctx->queue, &input[offset], remaining ); + } + + return( 0 ); +} + +int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, + unsigned char mac[16] ) +{ + if ( ( ctx == NULL ) || ( mac == NULL ) ) + { + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } + + /* Process any leftover data */ + if ( ctx->queue_len > 0U ) + { + /* Add padding bit */ + ctx->queue[ctx->queue_len] = 1U; + ctx->queue_len++; + + /* Pad with zeroes */ + memset( &ctx->queue[ctx->queue_len], + 0, + POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); + + mbedtls_poly1305_process( ctx, + 1U, /* Process 1 block */ + ctx->queue, + 0U ); /* Don't add padding bit (it was just added above) */ + } + + mbedtls_poly1305_compute_mac( ctx, mac ); + + return( 0 ); +} + +#endif /* MBEDTLS_POLY1305_ALT */ + +int mbedtls_poly1305_mac( const unsigned char key[32], + size_t ilen, + const unsigned char *input, + unsigned char mac[16] ) +{ + mbedtls_poly1305_context ctx; + int result; + + mbedtls_poly1305_init( &ctx ); + + result = mbedtls_poly1305_setkey( &ctx, key ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_poly1305_update( &ctx, ilen, input ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_poly1305_finish( &ctx, mac ); + +cleanup: + mbedtls_poly1305_free( &ctx ); + return( 0 ); +} + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char test_keys[2][32] = +{ + { + 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, + 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, + 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, + 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b + }, + { + 0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, + 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0, + 0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, + 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0 + } +}; + +static const unsigned char test_data[2][127] = +{ + { + 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x46, 0x6f, + 0x72, 0x75, 0x6d, 0x20, 0x52, 0x65, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x20, 0x47, 0x72, 0x6f, + 0x75, 0x70 + }, + { + 0x27, 0x54, 0x77, 0x61, 0x73, 0x20, 0x62, 0x72, + 0x69, 0x6c, 0x6c, 0x69, 0x67, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x6c, 0x69, 0x74, 0x68, 0x79, 0x20, 0x74, 0x6f, + 0x76, 0x65, 0x73, 0x0a, 0x44, 0x69, 0x64, 0x20, + 0x67, 0x79, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x67, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, + 0x61, 0x62, 0x65, 0x3a, 0x0a, 0x41, 0x6c, 0x6c, + 0x20, 0x6d, 0x69, 0x6d, 0x73, 0x79, 0x20, 0x77, + 0x65, 0x72, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x62, 0x6f, 0x72, 0x6f, 0x67, 0x6f, 0x76, 0x65, + 0x73, 0x2c, 0x0a, 0x41, 0x6e, 0x64, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x6d, 0x6f, 0x6d, 0x65, 0x20, + 0x72, 0x61, 0x74, 0x68, 0x73, 0x20, 0x6f, 0x75, + 0x74, 0x67, 0x72, 0x61, 0x62, 0x65, 0x2e + } +}; + +static const size_t test_data_len[2] = +{ + 34U, + 127U +}; + +static const unsigned char test_mac[2][16] = +{ + { + 0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, + 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9 + }, + { + 0x45, 0x41, 0x66, 0x9a, 0x7e, 0xaa, 0xee, 0x61, + 0xe7, 0x08, 0xdc, 0x7c, 0xbc, 0xc5, 0xeb, 0x62 + } +}; + +int mbedtls_poly1305_self_test( int verbose ) +{ + uint8_t mac[16]; + size_t i; + int result; + + for ( i = 0U; i < 2U; i++ ) + { + result = mbedtls_poly1305_mac( test_keys[i], + test_data_len[i], + test_data[i], + mac ); + if ( result != 0 ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "Poly1305 test %zi error code: %i\n", i, result ); + } + + return( -1 ); + } + + if ( memcmp( mac, test_mac[i], 16U ) != 0 ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "Poly1305 test %zi failed\n", i ); + } + + return( -1 ); + } + } + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_POLY1305_C */ diff --git a/library/version_features.c b/library/version_features.c index febd506b7..babf2c782 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -168,6 +168,9 @@ static const char *features[] = { #if defined(MBEDTLS_SHA512_PROCESS_ALT) "MBEDTLS_SHA512_PROCESS_ALT", #endif /* MBEDTLS_SHA512_PROCESS_ALT */ +#if defined(MBEDTLS_POLY1305_ALT) + "MBEDTLS_POLY1305_ALT", +#endif /* MBEDTLS_POLY1305_ALT */ #if defined(MBEDTLS_DES_SETKEY_ALT) "MBEDTLS_DES_SETKEY_ALT", #endif /* MBEDTLS_DES_SETKEY_ALT */ @@ -639,6 +642,9 @@ static const char *features[] = { #if defined(MBEDTLS_PLATFORM_C) "MBEDTLS_PLATFORM_C", #endif /* MBEDTLS_PLATFORM_C */ +#if defined(MBEDTLS_POLY1305_C) + "MBEDTLS_POLY1305_C", +#endif /* MBEDTLS_POLY1305_C */ #if defined(MBEDTLS_RIPEMD160_C) "MBEDTLS_RIPEMD160_C", #endif /* MBEDTLS_RIPEMD160_C */ diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index bc473cf86..c41966586 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -63,6 +63,7 @@ int main( void ) #include "mbedtls/gcm.h" #include "mbedtls/ccm.h" #include "mbedtls/cmac.h" +#include "mbedtls/poly1305.h" #include "mbedtls/havege.h" #include "mbedtls/ctr_drbg.h" #include "mbedtls/hmac_drbg.h" @@ -95,7 +96,8 @@ int main( void ) #define OPTIONS \ "md4, md5, ripemd160, sha1, sha256, sha512,\n" \ "arc4, des3, des, camellia, blowfish, chacha20,\n" \ - "aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac,\n" \ + "aes_cbc, aes_gcm, aes_ccm,\n" \ + "aes_cmac, des3_cmac, poly1305\n" \ "havege, ctr_drbg, hmac_drbg\n" \ "rsa, dhm, ecdsa, ecdh.\n" @@ -231,6 +233,7 @@ typedef struct { arc4, des3, des, aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac, camellia, blowfish, chacha20, + poly1305, havege, ctr_drbg, hmac_drbg, rsa, dhm, ecdsa, ecdh; } todo_list; @@ -289,6 +292,8 @@ int main( int argc, char *argv[] ) todo.blowfish = 1; else if( strcmp( argv[i], "chacha20" ) == 0 ) todo.chacha20 = 1; + else if( strcmp( argv[i], "poly1305" ) == 0 ) + todo.poly1305 = 1; else if( strcmp( argv[i], "havege" ) == 0 ) todo.havege = 1; else if( strcmp( argv[i], "ctr_drbg" ) == 0 ) @@ -530,6 +535,13 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_POLY1305_C) + if ( todo.poly1305 ) + { + TIME_AND_TSC( "Poly1305", mbedtls_poly1305_mac( buf, BUFSIZE, buf, buf ) ); + } +#endif + #if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC) if( todo.blowfish ) { diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index 36ee60b72..1dac39bf1 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -32,7 +32,7 @@ my $error_format_file = $data_dir.'/error.fmt'; my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH CAMELLIA CCM CHACHA20 CMAC CTR_DRBG DES ENTROPY GCM HMAC_DRBG MD2 MD4 MD5 - NET OID PADLOCK PBKDF2 RIPEMD160 + NET OID PADLOCK PBKDF2 POLY1305 RIPEMD160 SHA1 SHA256 SHA512 THREADING XTEA ); my @high_level_modules = qw( CIPHER DHM ECP MD PEM PK PKCS12 PKCS5 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3821657ae..82f155419 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -98,6 +98,7 @@ add_test_suite(pkcs5) add_test_suite(pk) add_test_suite(pkparse) add_test_suite(pkwrite) +add_test_suite(poly1305) add_test_suite(shax) add_test_suite(ssl) add_test_suite(timing) diff --git a/tests/Makefile b/tests/Makefile index 34a0a8915..90b2028f5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -82,6 +82,7 @@ APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ test_suite_pkcs1_v21$(EXEXT) test_suite_pkcs5$(EXEXT) \ test_suite_pkparse$(EXEXT) test_suite_pkwrite$(EXEXT) \ test_suite_pk$(EXEXT) \ + test_suite_poly1305$(EXEXT) \ test_suite_rsa$(EXEXT) test_suite_shax$(EXEXT) \ test_suite_ssl$(EXEXT) test_suite_timing$(EXEXT) \ test_suite_x509parse$(EXEXT) test_suite_x509write$(EXEXT) \ @@ -414,6 +415,10 @@ test_suite_pk$(EXEXT): test_suite_pk.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_poly1305$(EXEXT): test_suite_poly1305.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_rsa$(EXEXT): test_suite_rsa.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_poly1305.data b/tests/suites/test_suite_poly1305.data new file mode 100644 index 000000000..f259e848b --- /dev/null +++ b/tests/suites/test_suite_poly1305.data @@ -0,0 +1,51 @@ +Poly1305 RFC 7539 Example And Test Vector +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b":"a8061dc1305136c6c22b8baf0c0127a9":"43727970746f6772617068696320466f72756d2052657365617263682047726f7570" + +Poly1305 RFC 7539 Test Vector #1 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + +Poly1305 RFC 7539 Test Vector #2 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e":"36e5f6b5c5e06070f0efca96227a863e":"416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f" + +Poly1305 RFC 7539 Test Vector #3 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000":"f3477e7cd95417af89a6b8794c310cf0":"416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f" + +Poly1305 RFC 7539 Test Vector #4 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"4541669a7eaaee61e708dc7cbcc5eb62":"2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e" + +Poly1305 RFC 7539 Test Vector #5 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0200000000000000000000000000000000000000000000000000000000000000":"03000000000000000000000000000000":"ffffffffffffffffffffffffffffffff" + +Poly1305 RFC 7539 Test Vector #6 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"02000000000000000000000000000000ffffffffffffffffffffffffffffffff":"03000000000000000000000000000000":"02000000000000000000000000000000" + +Poly1305 RFC 7539 Test Vector #7 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0100000000000000000000000000000000000000000000000000000000000000":"05000000000000000000000000000000":"fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000" + +Poly1305 RFC 7539 Test Vector #8 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0100000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101" + +Poly1305 RFC 7539 Test Vector #9 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0200000000000000000000000000000000000000000000000000000000000000":"faffffffffffffffffffffffffffffff":"fdffffffffffffffffffffffffffffff" + +Poly1305 RFC 7539 Test Vector #10 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0100000000000000040000000000000000000000000000000000000000000000":"14000000000000005500000000000000":"e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000" + +Poly1305 RFC 7539 Test Vector #11 +depends_on:MBEDTLS_POLY1305_C +mbedtls_poly1305:"0100000000000000040000000000000000000000000000000000000000000000":"13000000000000000000000000000000":"e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000" + +Poly1305 Selftest +depends_on:MBEDTLS_SELF_TEST:MBEDTLS_POLY1305_C +poly1305_selftest: diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function new file mode 100644 index 000000000..af69a0312 --- /dev/null +++ b/tests/suites/test_suite_poly1305.function @@ -0,0 +1,35 @@ +/* BEGIN_HEADER */ +#include "mbedtls/poly1305.h" +#include +/* END_HEADER */ + +/* BEGIN_CASE depends_on:MBEDTLS_POLY1305_C */ +void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src_string ) +{ + unsigned char src_str[10000]; + unsigned char mac_str[100]; + unsigned char key[32]; + unsigned char mac[16]; + size_t src_len; + + memset(src_str, 0x00, 10000); + memset(mac_str, 0x00, 100); + memset(key, 0x00, 32); + memset(mac, 0x00, 16); + + src_len = unhexify( src_str, hex_src_string ); + unhexify( key, hex_key_string ); + + mbedtls_poly1305_mac( key, src_len, src_str, mac ); + hexify( mac_str, mac, 16 ); + + TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_POLY1305_C:MBEDTLS_SELF_TEST */ +void poly1305_selftest() +{ + TEST_ASSERT( mbedtls_poly1305_self_test( 0 ) == 0 ); +} +/* END_CASE */ From 31ac12e004dd169f47c2d575abad77fd9fedd4e4 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 17 May 2016 14:43:01 -0300 Subject: [PATCH 04/42] Implement AEAD-ChaCha20-Poly1305. This implementation is based off the description in RFC 7539. The ChaCha20 code is also updated to provide a means of generating keystream blocks with arbitrary counter values. This is used to generated the one-time Poly1305 key in the AEAD construction. --- include/mbedtls/aead_chacha20_poly1305.h | 224 +++++++++ include/mbedtls/chacha20.h | 21 + include/mbedtls/config.h | 23 + include/mbedtls/error.h | 1 + library/CMakeLists.txt | 1 + library/Makefile | 3 +- library/aead_chacha20_poly1305.c | 463 ++++++++++++++++++ library/chacha20.c | 96 ++-- library/error.c | 11 + library/version_features.c | 3 + scripts/generate_errors.pl | 3 +- tests/CMakeLists.txt | 1 + tests/Makefile | 8 +- .../test_suite_aead_chacha20_poly1305.data | 19 + ...test_suite_aead_chacha20_poly1305.function | 109 +++++ 15 files changed, 954 insertions(+), 32 deletions(-) create mode 100644 include/mbedtls/aead_chacha20_poly1305.h create mode 100644 library/aead_chacha20_poly1305.c create mode 100644 tests/suites/test_suite_aead_chacha20_poly1305.data create mode 100644 tests/suites/test_suite_aead_chacha20_poly1305.function diff --git a/include/mbedtls/aead_chacha20_poly1305.h b/include/mbedtls/aead_chacha20_poly1305.h new file mode 100644 index 000000000..a1ccf319e --- /dev/null +++ b/include/mbedtls/aead_chacha20_poly1305.h @@ -0,0 +1,224 @@ +/** + * \file aead_chacha20_poly1305.h + * + * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. + * + * Copyright (C) 2006-2016, ARM Limited, 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_AEAD_CHACHA20_POLY1305_H +#define MBEDTLS_AEAD_CHACHA20_POLY1305_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if !defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) + +#include "chacha20.h" +#include "poly1305.h" + +#define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ + +typedef enum +{ + MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, + MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT +} +mbedtls_aead_chacha20_poly1305_mode_t; + +typedef struct +{ + mbedtls_chacha20_context chacha20_ctx; /** ChaCha20 context */ + mbedtls_poly1305_context poly1305_ctx; /** Poly1305 context */ + uint64_t aad_len; /** Length (bytes) of the Additional Authenticated Data */ + uint64_t ciphertext_len; /** Length (bytes) of the ciphertext */ + int state; /** Current state of the context */ + mbedtls_aead_chacha20_poly1305_mode_t mode; /** Cipher mode (encrypt or decrypt) */ +} +mbedtls_aead_chacha20_poly1305_context; + +/** + * \brief Initialize ChaCha20-Poly1305 context + * + * \param ctx ChaCha20-Poly1305 context to be initialized + */ +void mbedtls_aead_chacha20_poly1305_init( mbedtls_aead_chacha20_poly1305_context *ctx ); + +/** + * \brief Clear ChaCha20-Poly1305 context + * + * \param ctx ChaCha20-Poly1305 context to be cleared + */ +void mbedtls_aead_chacha20_poly1305_free( mbedtls_aead_chacha20_poly1305_context *ctx ); + +/** + * \brief Set the ChaCha20-Poly1305 symmetric encryption key. + * + * \param ctx The ChaCha20-Poly1305 context. + * \param key The 256-bit (32 bytes) key. + * + * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * if \p ctx or \p key are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_aead_chacha20_poly1305_setkey( mbedtls_aead_chacha20_poly1305_context *ctx, + const unsigned char key[32] ); + +/** + * \brief Setup ChaCha20-Poly1305 context for encryption or decryption. + * + * \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. + * + * \param ctx The ChaCha20-Poly1305 context. + * \param nonce The nonce/IV to use for the message. This must be unique + * for every message encrypted under the same key. + * \param mode Specifies whether the context is used to encrypt or + * decrypt data. + * + * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * if \p ctx or \p mac are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_context *ctx, + const unsigned char nonce[12], + mbedtls_aead_chacha20_poly1305_mode_t mode ); + +/** + * \brief Process additional authenticated data (AAD). + * + * This function processes data that is authenticated, but + * not encrypted. + * + * \note This function is called before data is encrypted/decrypted. + * I.e. call this function to process the AAD before calling + * mbedtls_aead_chacha20_poly1305_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 mbedtls_aead_chacha20_poly1305_update, + * or if the context has been finished. + * + * \param ctx The ChaCha20-Poly1305 context. + * \param aad_len The length (in bytes) of the AAD. The length has no + * restrictions. + * \param aad Buffer containing the AAD. + * + * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * if \p ctx or \p aad are NULL. + * MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE is returned if + * the context has not been setup, the context has been + * finished, or if the AAD has been finished. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_context *ctx, + size_t aad_len, + const unsigned char *aad ); + +/** + * \brief Encrypt/decrypt data. + * + * The direction (encryption or decryption) depends on the + * mode that was given when calling + * mbedtls_aead_chacha20_poly1305_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. + * + * \param ctx The ChaCha20-Poly1305 context. + * \param len The length (in bytes) of the data to encrypt or decrypt. + * \param input Buffer containing the data to encrypt or decrypt. + * \param output Buffer to where the encrypted or decrypted data is written. + * + * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * if \p ctx, \p input, or \p output are NULL. + * MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE is returned if + * the context has not been setup, or if the context has been + * finished. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_context *ctx, + size_t len, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Compute the ChaCha20-Poly1305 MAC. + * + * \param ctx The ChaCha20-Poly1305 context. + * \param mac Buffer to where the 128-bit (16 bytes) MAC is written. + * + * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * if \p ctx or \p mac are NULL. + * MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE is returned if + * the context has not been setup. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_context *ctx, + unsigned char mac[16] ); + +#else /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ +#include "aead_chacha20_poly1305_alt.h" +#endif /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ + +/** + * \brief Encrypt or decrypt data, and produce a MAC with ChaCha20-Poly1305. + * + * \param key The 256-bit (32 bytes) encryption key to use. + * \param nonce The 96-bit (12 bytes) nonce/IV to use. + * \param mode Specifies whether the data in the \p input buffer is to + * be encrypted or decrypted. If there is no data to encrypt + * or decrypt (i.e. \p ilen is 0) then the value of this + * parameter does not matter. + * \param aad_len The length (in bytes) of the AAD data to process. + * \param aad Buffer containing the additional authenticated data (AAD). + * \param ilen The length (in bytes) of the data to encrypt or decrypt. + * \param input Buffer containing the data to encrypt or decrypt. + * \param output Buffer to where the encrypted or decrypted data is written. + * \param mac Buffer to where the computed 128-bit (16 bytes) MAC is written. + * + * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * if one or more of the required parameters are NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_aead_chacha20_poly1305_crypt_and_mac( const unsigned char key[32], + const unsigned char nonce[12], + mbedtls_aead_chacha20_poly1305_mode_t mode, + size_t aad_len, + const unsigned char *aad, + size_t ilen, + const unsigned char *input, + unsigned char *output, + unsigned char mac[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_aead_chacha20_poly1305_self_test( int verbose ); + +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_H */ diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index d23618ee0..ab87f66b9 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -99,6 +99,27 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, const unsigned char nonce[12], uint32_t counter ); +/** + * \brief Generates a block of keystream bytes for a specific counter value. + * + * This function uses the key and nonce previously set in + * the context (via mbedtls_chacha20_setkey and + * mbedtls_chacha20_starts), but ignores the previously + * set counter and uses the counter given as the parameter to + * this function. + * + * \param ctx The ChaCha20 context. This context is not modified. + * \param counter The counter value to use. + * \param keystream Buffer to where the generated keystream bytes are written. + * + * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or keystream are + * NULL. + * Otherwise, 0 is returned to indicate success. + */ +int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, + uint32_t counter, + unsigned char keystream[64] ); + /** * \brief Encrypt or decrypt data. * diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 7d0960a29..22d465cda 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -269,6 +269,7 @@ * digests and ciphers instead. * */ +//#define MBEDTLS_AEAD_CHACHA20_POLY1305_ALT //#define MBEDTLS_AES_ALT //#define MBEDTLS_ARC4_ALT //#define MBEDTLS_BLOWFISH_ALT @@ -1688,6 +1689,17 @@ */ #define MBEDTLS_AES_C +/** + * \def MBEDTLS_AEAD_CHACHA20_POLY1305_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/aead_chacha20_poly1305.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +#define MBEDTLS_AEAD_CHACHA20_POLY1305_C + /** * \def MBEDTLS_ARC4_C * @@ -1837,6 +1849,16 @@ */ #define MBEDTLS_CAMELLIA_C +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 block cipher. + * + * Module: library/chacha20.c + * Caller: library/aead_chacha20_poly1305.c + */ +#define MBEDTLS_CHACHA20_C + /** * \def MBEDTLS_CCM_C * @@ -2405,6 +2427,7 @@ * Enable the Poly1305 MAC algorithm. * * Module: library/poly1305.c + * Caller: library/aead_chacha20_poly1305.c */ #define MBEDTLS_POLY1305_C diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index feeda79ed..72b7f18ff 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -78,6 +78,7 @@ * SHA512 1 0x0039-0x0039 * CHACHA20 1 0x003B-0x003B * POLY1305 1 0x0041-0x0041 + * AEAD_CHACHA20_POLY1305 2 0x0047-0x0049 * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 251b6c625..b8f663d9c 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -3,6 +3,7 @@ option(USE_SHARED_MBEDTLS_LIBRARY "Build mbed TLS shared library." OFF) option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF) set(src_crypto + aead_chacha20_poly1305.c aes.c aesni.c arc4.c diff --git a/library/Makefile b/library/Makefile index 5fd693b25..de4bd5c42 100644 --- a/library/Makefile +++ b/library/Makefile @@ -47,7 +47,8 @@ ifdef WINDOWS_BUILD DLEXT=dll endif -OBJS_CRYPTO= aes.o aesni.o arc4.o \ +OBJS_CRYPTO= aead_chacha20_poly1305.o \ + aes.o aesni.o arc4.o \ asn1parse.o asn1write.o base64.o \ bignum.o blowfish.o camellia.o \ ccm.o chacha20.o \ diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c new file mode 100644 index 000000000..ab29dfa1b --- /dev/null +++ b/library/aead_chacha20_poly1305.c @@ -0,0 +1,463 @@ +/** + * \file aead_chacha20_poly1305.c + * + * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. + * + * Copyright (C) 2006-2016, ARM Limited, 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) + */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + +#include "mbedtls/aead_chacha20_poly1305.h" +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) + +#define AEAD_CHACHA20_POLY1305_STATE_INIT ( 0 ) +#define AEAD_CHACHA20_POLY1305_STATE_AAD ( 1 ) +#define AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ +#define AEAD_CHACHA20_POLY1305_STATE_FINISHED ( 3 ) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/** + * \brief Adds padding bytes (zeroes) to pad the AAD for Poly1305. + * + * \param ctx The ChaCha20-Poly1305 context. + */ +static void mbedtls_aead_chacha20_poly1305_pad_aad( mbedtls_aead_chacha20_poly1305_context *ctx ) +{ + uint32_t partial_block_len = (uint32_t)( ctx->aad_len % 16U ); + unsigned char zeroes[15]; + + if ( partial_block_len > 0U ) + { + memset( zeroes, 0, sizeof(zeroes) ); + (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, + 16U - partial_block_len, + zeroes ); + } +} + +/** + * \brief Adds padding bytes (zeroes) to pad the ciphertext for Poly1305. + * + * \param ctx The ChaCha20-Poly1305 context. + */ +static void mbedtls_aead_chacha20_poly1305_pad_ciphertext( mbedtls_aead_chacha20_poly1305_context *ctx ) +{ + uint32_t partial_block_len = (uint32_t)( ctx->ciphertext_len % 16U ); + unsigned char zeroes[15]; + + if ( partial_block_len > 0U ) + { + memset( zeroes, 0, sizeof(zeroes) ); + (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, + 16U - partial_block_len, + zeroes ); + } +} + +void mbedtls_aead_chacha20_poly1305_init( mbedtls_aead_chacha20_poly1305_context *ctx ) +{ + if ( ctx != NULL ) + { + mbedtls_chacha20_init( &ctx->chacha20_ctx ); + mbedtls_poly1305_init( &ctx->poly1305_ctx ); + ctx->aad_len = 0U; + ctx->ciphertext_len = 0U; + ctx->state = AEAD_CHACHA20_POLY1305_STATE_INIT; + ctx->mode = MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT; + } +} + +void mbedtls_aead_chacha20_poly1305_free( mbedtls_aead_chacha20_poly1305_context *ctx ) +{ + if ( ctx != NULL ) + { + mbedtls_chacha20_free( &ctx->chacha20_ctx ); + mbedtls_poly1305_free( &ctx->poly1305_ctx ); + ctx->aad_len = 0U; + ctx->ciphertext_len = 0U; + ctx->state = AEAD_CHACHA20_POLY1305_STATE_INIT; + ctx->mode = MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT; + } +} + +int mbedtls_aead_chacha20_poly1305_setkey( mbedtls_aead_chacha20_poly1305_context *ctx, + const unsigned char key[32] ) +{ + int result; + + if ( ( ctx == NULL ) || ( key == NULL ) ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } + + result = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); + + return( result ); +} + +int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_context *ctx, + const unsigned char nonce[12], + mbedtls_aead_chacha20_poly1305_mode_t mode ) +{ + int result; + unsigned char poly1305_key[64]; + + if ( ( ctx == NULL ) || ( nonce == NULL ) ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } + + result = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 1U ); + if ( result != 0 ) + goto cleanup; + + /* Generate the Poly1305 key by getting the ChaCha20 keystream output with counter = 0. + * Only the first 256-bits (32 bytes) of the key is used for Poly1305. + * The other 256 bits are discarded. + */ + result = mbedtls_chacha20_keystream_block( &ctx->chacha20_ctx, 0U, poly1305_key ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_poly1305_setkey( &ctx->poly1305_ctx, poly1305_key ); + + if ( result == 0 ) + { + ctx->aad_len = 0U; + ctx->ciphertext_len = 0U; + ctx->state = AEAD_CHACHA20_POLY1305_STATE_AAD; + ctx->mode = mode; + } + +cleanup: + mbedtls_zeroize( poly1305_key, 64U ); + return( result ); +} + +int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_context *ctx, + size_t aad_len, + const unsigned char *aad ) +{ + if ( ( ctx == NULL ) || ( aad == NULL ) ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } + else if ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) + { + return (MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + } + + ctx->aad_len += aad_len; + + return ( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad_len, aad ) ); +} + +int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_context *ctx, + size_t len, + const unsigned char *input, + unsigned char *output ) +{ + if ( ( ctx == NULL ) || ( input == NULL ) || ( output == NULL ) ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } + else if ( ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) && + ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ) ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + } + + if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_AAD ) + { + ctx->state = AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT; + + mbedtls_aead_chacha20_poly1305_pad_aad( ctx ); + } + + ctx->ciphertext_len += len; + + if ( ctx->mode == MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT ) + { + /* Note: the following functions return an error only if one or more of + * the input pointers are NULL. Since we have checked their validity + * above, we can safety ignore the return value. + */ + (void)mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, len, output ); + } + else /* DECRYPT */ + { + (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, len, input ); + (void)mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + } + + return( 0 ); +} + +int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_context *ctx, + unsigned char mac[16] ) +{ + unsigned char len_block[16]; + + if ( ( ctx == NULL ) || ( mac == NULL ) ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } + else if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_INIT ) + { + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + } + + if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_AAD ) + { + mbedtls_aead_chacha20_poly1305_pad_aad( ctx ); + } + else if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ) + { + mbedtls_aead_chacha20_poly1305_pad_ciphertext( ctx ); + } + + ctx->state = AEAD_CHACHA20_POLY1305_STATE_FINISHED; + + /* The lengths of the AAD and ciphertext are processed by + * Poly1305 as the final 128-bit block, encoded as little-endian integers. + */ + len_block[0] = (unsigned char)ctx->aad_len; + len_block[1] = (unsigned char)( ctx->aad_len >> 8 ); + len_block[2] = (unsigned char)( ctx->aad_len >> 16 ); + len_block[3] = (unsigned char)( ctx->aad_len >> 24 ); + len_block[4] = (unsigned char)( ctx->aad_len >> 32 ); + len_block[5] = (unsigned char)( ctx->aad_len >> 40 ); + len_block[6] = (unsigned char)( ctx->aad_len >> 48 ); + len_block[7] = (unsigned char)( ctx->aad_len >> 56 ); + len_block[8] = (unsigned char)ctx->ciphertext_len; + len_block[9] = (unsigned char)( ctx->ciphertext_len >> 8 ); + len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 ); + len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 ); + len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 ); + len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 ); + len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 ); + len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 ); + + (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, 16U, len_block ); + (void)mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); + + return( 0 ); +} + +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ + +int mbedtls_aead_chacha20_poly1305_crypt_and_mac ( const unsigned char key[32], + const unsigned char nonce[12], + mbedtls_aead_chacha20_poly1305_mode_t mode, + size_t aad_len, + const unsigned char *aad, + size_t ilen, + const unsigned char *input, + unsigned char *output, + unsigned char mac[16] ) +{ + mbedtls_aead_chacha20_poly1305_context ctx; + int result; + + mbedtls_aead_chacha20_poly1305_init( &ctx ); + + result = mbedtls_aead_chacha20_poly1305_setkey( &ctx, key ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_aead_chacha20_poly1305_starts( &ctx, nonce, mode ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_aead_chacha20_poly1305_update_aad( &ctx, aad_len, aad ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_aead_chacha20_poly1305_update( &ctx, ilen, input, output ); + if ( result != 0 ) + goto cleanup; + + result = mbedtls_aead_chacha20_poly1305_finish( &ctx, mac ); + +cleanup: + mbedtls_aead_chacha20_poly1305_free( &ctx ); + return( result ); +} + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char test_key[1][32] = +{ + { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f + } +}; + +static const unsigned char test_nonce[1][12] = +{ + { + 0x07, 0x00, 0x00, 0x00, /* 32-bit common part */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 /* 64-bit IV */ + } +}; + +static const unsigned char test_aad[1][12] = +{ + { + 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7 + } +}; + +static const size_t test_aad_len[1] = +{ + 12U +}; + +static const unsigned char test_input[1][114] = +{ + { + 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, + 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, + 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, + 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, + 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, + 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, + 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, + 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, + 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, + 0x74, 0x2e + } +}; + +static const unsigned char test_output[1][114] = +{ + { + 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, + 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, + 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, + 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, + 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, + 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, + 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, + 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, + 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, + 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, + 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, + 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, + 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, + 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, + 0x61, 0x16 + } +}; + +static const size_t test_input_len[1] = +{ + 114U +}; + +static const unsigned char test_mac[1][16] = +{ + { + 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, + 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 + } +}; + +int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) +{ + size_t i; + int result; + unsigned char output[200]; + unsigned char mac[16]; + + for ( i = 0U; i < 1U; i++ ) + { + result = mbedtls_aead_chacha20_poly1305_crypt_and_mac( test_key[i], + test_nonce[i], + MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, + test_aad_len[i], + test_aad[i], + test_input_len[i], + test_input[i], + output, + mac ); + if ( result != 0 ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "ChaCha20-Poly1305 test %zi error code: %i\n", i, result ); + } + return( -1 ); + } + + if ( memcmp( output, test_output[i], test_input_len[i] ) != 0 ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "ChaCha20-Poly1305 test %zi failure (wrong output)\n", i ); + } + return( -1 ); + } + + if ( memcmp( mac, test_mac[i], 16U ) != 0 ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "ChaCha20-Poly1305 test %zi failure (wrong MAC)\n", i ); + } + return( -1 ); + } + } + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ diff --git a/library/chacha20.c b/library/chacha20.c index 8206a3bf0..b20c7ad55 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -134,46 +134,47 @@ static void mbedtls_chacha20_inner_block( uint32_t state[16] ) * \param working_state This state is used as a temporary working area. * \param keystream Generated keystream bytes are written to this buffer. */ -static void mbedtls_chacha20_block( mbedtls_chacha20_context *ctx, +static void mbedtls_chacha20_block( const uint32_t initial_state[16], + uint32_t working_state[16], unsigned char keystream[64] ) { size_t i; size_t offset; - memcpy( ctx->working_state, - ctx->initial_state, - sizeof(ctx->initial_state) ); + memcpy( working_state, + initial_state, + CHACHA20_BLOCK_SIZE_BYTES ); for ( i = 0U; i < 10U; i++ ) { - mbedtls_chacha20_inner_block( ctx->working_state ); + mbedtls_chacha20_inner_block( working_state ); } - ctx->working_state[0] += ctx->initial_state[0]; - ctx->working_state[1] += ctx->initial_state[1]; - ctx->working_state[2] += ctx->initial_state[2]; - ctx->working_state[3] += ctx->initial_state[3]; - ctx->working_state[4] += ctx->initial_state[4]; - ctx->working_state[5] += ctx->initial_state[5]; - ctx->working_state[6] += ctx->initial_state[6]; - ctx->working_state[7] += ctx->initial_state[7]; - ctx->working_state[8] += ctx->initial_state[8]; - ctx->working_state[9] += ctx->initial_state[9]; - ctx->working_state[10] += ctx->initial_state[10]; - ctx->working_state[11] += ctx->initial_state[11]; - ctx->working_state[12] += ctx->initial_state[12]; - ctx->working_state[13] += ctx->initial_state[13]; - ctx->working_state[14] += ctx->initial_state[14]; - ctx->working_state[15] += ctx->initial_state[15]; + working_state[0] += initial_state[0]; + working_state[1] += initial_state[1]; + working_state[2] += initial_state[2]; + working_state[3] += initial_state[3]; + working_state[4] += initial_state[4]; + working_state[5] += initial_state[5]; + working_state[6] += initial_state[6]; + working_state[7] += initial_state[7]; + working_state[8] += initial_state[8]; + working_state[9] += initial_state[9]; + working_state[10] += initial_state[10]; + working_state[11] += initial_state[11]; + working_state[12] += initial_state[12]; + working_state[13] += initial_state[13]; + working_state[14] += initial_state[14]; + working_state[15] += initial_state[15]; for ( i = 0U; i < 16; i++ ) { offset = i * 4U; - keystream[offset ] = (unsigned char) ctx->working_state[i]; - keystream[offset + 1U] = (unsigned char)( ctx->working_state[i] >> 8 ); - keystream[offset + 2U] = (unsigned char)( ctx->working_state[i] >> 16 ); - keystream[offset + 3U] = (unsigned char)( ctx->working_state[i] >> 24 ); + keystream[offset ] = (unsigned char) working_state[i]; + keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 ); + keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 ); + keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 ); } } @@ -245,6 +246,43 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, return( 0 ); } +int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, + uint32_t counter, + unsigned char keystream[64] ) +{ + uint32_t initial_state[16]; + uint32_t working_state[16]; + + if ( ( ctx == NULL ) || ( keystream == NULL ) ) + { + return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + } + + initial_state[0] = ctx->initial_state[0]; + initial_state[1] = ctx->initial_state[1]; + initial_state[2] = ctx->initial_state[2]; + initial_state[3] = ctx->initial_state[3]; + initial_state[4] = ctx->initial_state[4]; + initial_state[5] = ctx->initial_state[5]; + initial_state[6] = ctx->initial_state[6]; + initial_state[7] = ctx->initial_state[7]; + initial_state[8] = ctx->initial_state[8]; + initial_state[9] = ctx->initial_state[9]; + initial_state[10] = ctx->initial_state[10]; + initial_state[11] = ctx->initial_state[11]; + initial_state[12] = counter; + initial_state[13] = ctx->initial_state[13]; + initial_state[14] = ctx->initial_state[14]; + initial_state[15] = ctx->initial_state[15]; + + mbedtls_chacha20_block( initial_state, working_state, keystream ); + + mbedtls_zeroize( initial_state, sizeof(initial_state) ); + mbedtls_zeroize( working_state, sizeof(working_state) ); + + return ( 0 ); +} + int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, size_t size, const unsigned char *input, @@ -271,7 +309,7 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, /* Process full blocks */ while ( size >= CHACHA20_BLOCK_SIZE_BYTES ) { - mbedtls_chacha20_block( ctx, &output[offset] ); + mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, &output[offset] ); for ( i = 0U; i < 64U; i += 8U ) { @@ -288,14 +326,14 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, /* Increment counter */ ctx->initial_state[CHACHA20_CTR_INDEX]++; - offset += 64U; - size -= 64U; + offset += CHACHA20_BLOCK_SIZE_BYTES; + size -= CHACHA20_BLOCK_SIZE_BYTES; } /* Last (partial) block */ if ( size > 0U ) { - mbedtls_chacha20_block( ctx, ctx->keystream8 ); + mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); for ( i = 0U; i < size; i++) { diff --git a/library/error.c b/library/error.c index 12bd2101b..d0a75ca5a 100644 --- a/library/error.c +++ b/library/error.c @@ -41,6 +41,10 @@ #include +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#include "mbedtls/aead_chacha20_poly1305.h" +#endif + #if defined(MBEDTLS_AES_C) #include "mbedtls/aes.h" #endif @@ -575,6 +579,13 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) // Low level error codes // // BEGIN generated code +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if( use_ret == -(MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "AEAD_CHACHA20_POLY1305 - Invalid input parameter(s)" ); + if( use_ret == -(MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE) ) + mbedtls_snprintf( buf, buflen, "AEAD_CHACHA20_POLY1305 - The requested operation is not permitted in the current state" ); +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ + #if defined(MBEDTLS_AES_C) if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) ) mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); diff --git a/library/version_features.c b/library/version_features.c index babf2c782..64aa9f641 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -516,6 +516,9 @@ static const char *features[] = { #if defined(MBEDTLS_AES_C) "MBEDTLS_AES_C", #endif /* MBEDTLS_AES_C */ +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + "MBEDTLS_AEAD_CHACHA20_POLY1305_C", +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ #if defined(MBEDTLS_ARC4_C) "MBEDTLS_ARC4_C", #endif /* MBEDTLS_ARC4_C */ diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index 1dac39bf1..b5d141322 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -29,7 +29,7 @@ if( @ARGV ) { my $error_format_file = $data_dir.'/error.fmt'; -my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH +my @low_level_modules = qw( AEAD_CHACHA20_POLY1305 AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH CAMELLIA CCM CHACHA20 CMAC CTR_DRBG DES ENTROPY GCM HMAC_DRBG MD2 MD4 MD5 NET OID PADLOCK PBKDF2 POLY1305 RIPEMD160 @@ -88,6 +88,7 @@ foreach my $line (@matches) $module_name = "BIGNUM" if ($module_name eq "MPI"); $module_name = "CTR_DRBG" if ($module_name eq "CTR"); $module_name = "HMAC_DRBG" if ($module_name eq "HMAC"); + $module_name = "AEAD_CHACHA20_POLY1305" if ($module_name eq "AEAD"); my $define_name = $module_name; $define_name = "X509_USE,X509_CREATE" if ($define_name eq "X509"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 82f155419..03797ec32 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -44,6 +44,7 @@ if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX-") endif(MSVC) +add_test_suite(aead_chacha20_poly1305) add_test_suite(aes aes.ecb) add_test_suite(aes aes.cbc) add_test_suite(aes aes.cfb) diff --git a/tests/Makefile b/tests/Makefile index 90b2028f5..4a23e64cc 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -45,7 +45,8 @@ ifdef ZLIB LOCAL_LDFLAGS += -lz endif -APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ +APPS = test_suite_aead_chacha20_poly1305$(EXEXT) \ + test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ test_suite_aes.cfb$(EXEXT) test_suite_aes.rest$(EXEXT) \ test_suite_arc4$(EXEXT) test_suite_asn1write$(EXEXT) \ test_suite_base64$(EXEXT) test_suite_blowfish$(EXEXT) \ @@ -203,6 +204,11 @@ test_suite_hmac_drbg.pr.c : suites/test_suite_hmac_drbg.function suites/test_sui echo " Gen $@" perl scripts/generate_code.pl suites $* $* + +test_suite_aead_chacha20_poly1305$(EXEXT): test_suite_aead_chacha20_poly1305.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_aes.ecb$(EXEXT): test_suite_aes.ecb.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_aead_chacha20_poly1305.data b/tests/suites/test_suite_aead_chacha20_poly1305.data new file mode 100644 index 000000000..1cbfa24da --- /dev/null +++ b/tests/suites/test_suite_aead_chacha20_poly1305.data @@ -0,0 +1,19 @@ +ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +mbedtls_aead_chacha20_poly1305_enc:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +mbedtls_aead_chacha20_poly1305_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600691" + +ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Encrypt) +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +mbedtls_aead_chacha20_poly1305_enc:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt) +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +mbedtls_aead_chacha20_poly1305_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"eead9d67890cbb22392336fea1851f38" + +ChaCha20-Poly1305 Selftest +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C:MBEDTLS_SELF_TEST +aead_chacha20_poly1305_selftest: diff --git a/tests/suites/test_suite_aead_chacha20_poly1305.function b/tests/suites/test_suite_aead_chacha20_poly1305.function new file mode 100644 index 000000000..6abd05414 --- /dev/null +++ b/tests/suites/test_suite_aead_chacha20_poly1305.function @@ -0,0 +1,109 @@ +/* BEGIN_HEADER */ +#include "mbedtls/aead_chacha20_poly1305.h" +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void mbedtls_aead_chacha20_poly1305_enc( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) +{ + unsigned char key_str[32]; + unsigned char nonce_str[12]; + unsigned char aad_str[10000]; + unsigned char input_str[10000]; + unsigned char output_str[10000]; + unsigned char mac_str[16]; + unsigned char output[10000]; + unsigned char mac[16]; + size_t input_len; + size_t output_len; + size_t aad_len; + size_t key_len; + size_t nonce_len; + size_t mac_len; + + memset( key_str, 0x00, 32 ); + memset( nonce_str, 0x00, 12 ); + memset( aad_str, 0x00, 10000 ); + memset( input_str, 0x00, 10000 ); + memset( output_str, 0x00, 10000 ); + memset( mac_str, 0x00, 16 ); + + aad_len = unhexify( aad_str, hex_aad_string ); + input_len = unhexify( input_str, hex_input_string ); + output_len = unhexify( output_str, hex_output_string ); + key_len = unhexify( key_str, hex_key_string ); + nonce_len = unhexify( nonce_str, hex_nonce_string ); + mac_len = unhexify( mac_str, hex_mac_string ); + + TEST_ASSERT( key_len == 32 ); + TEST_ASSERT( nonce_len == 12 ); + TEST_ASSERT( mac_len == 16 ); + + mbedtls_aead_chacha20_poly1305_crypt_and_mac( key_str, nonce_str, + MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, + aad_len, aad_str, + input_len, input_str, output, + mac ); + + TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); + TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void mbedtls_aead_chacha20_poly1305_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) +{ + unsigned char key_str[32]; + unsigned char nonce_str[12]; + unsigned char aad_str[10000]; + unsigned char input_str[10000]; + unsigned char output_str[10000]; + unsigned char mac_str[16]; + unsigned char output[10000]; + unsigned char mac[16]; + size_t input_len; + size_t output_len; + size_t aad_len; + size_t key_len; + size_t nonce_len; + size_t mac_len; + + memset( key_str, 0x00, 32 ); + memset( nonce_str, 0x00, 12 ); + memset( aad_str, 0x00, 10000 ); + memset( input_str, 0x00, 10000 ); + memset( output_str, 0x00, 10000 ); + memset( mac_str, 0x00, 16 ); + + aad_len = unhexify( aad_str, hex_aad_string ); + input_len = unhexify( input_str, hex_input_string ); + output_len = unhexify( output_str, hex_output_string ); + key_len = unhexify( key_str, hex_key_string ); + nonce_len = unhexify( nonce_str, hex_nonce_string ); + mac_len = unhexify( mac_str, hex_mac_string ); + + TEST_ASSERT( key_len == 32 ); + TEST_ASSERT( nonce_len == 12 ); + TEST_ASSERT( mac_len == 16 ); + + mbedtls_aead_chacha20_poly1305_crypt_and_mac( key_str, nonce_str, + MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT, + aad_len, aad_str, + input_len, input_str, output, + mac ); + + TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); + TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ +void aead_chacha20_poly1305_selftest() +{ + TEST_ASSERT( mbedtls_aead_chacha20_poly1305_self_test( 1 ) == 0 ); +} +/* END_CASE */ From f28c2aa64e0436fbc03c4b9f4c2f59f8d77dfdf8 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 17 May 2016 15:56:26 -0300 Subject: [PATCH 05/42] Allow some parameters to be NULL if the length is 0. This change permits users of the ChaCha20/Poly1305 algorithms (and the AEAD construction thereof) to pass NULL pointers for data that they do not need, and avoids the need to provide a valid buffer for data that is not used. --- include/mbedtls/aead_chacha20_poly1305.h | 6 ++++++ include/mbedtls/chacha20.h | 2 ++ include/mbedtls/poly1305.h | 1 + library/aead_chacha20_poly1305.c | 12 +++++++++++- library/chacha20.c | 7 ++++++- library/poly1305.c | 9 +++++++-- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/aead_chacha20_poly1305.h b/include/mbedtls/aead_chacha20_poly1305.h index a1ccf319e..6c8e420b5 100644 --- a/include/mbedtls/aead_chacha20_poly1305.h +++ b/include/mbedtls/aead_chacha20_poly1305.h @@ -124,6 +124,7 @@ int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_contex * \param aad_len The length (in bytes) of the AAD. The length has no * restrictions. * \param aad Buffer containing the AAD. + * This pointer can be NULL if aad_len == 0. * * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned * if \p ctx or \p aad are NULL. @@ -151,7 +152,9 @@ int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_co * \param ctx The ChaCha20-Poly1305 context. * \param len The length (in bytes) of the data to encrypt or decrypt. * \param input Buffer containing the data to encrypt or decrypt. + * This pointer can be NULL if len == 0. * \param output Buffer to where the encrypted or decrypted data is written. + * This pointer can be NULL if len == 0. * * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned * if \p ctx, \p input, or \p output are NULL. @@ -195,9 +198,12 @@ int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_contex * parameter does not matter. * \param aad_len The length (in bytes) of the AAD data to process. * \param aad Buffer containing the additional authenticated data (AAD). + * This pointer can be NULL if aad_len == 0. * \param ilen The length (in bytes) of the data to encrypt or decrypt. * \param input Buffer containing the data to encrypt or decrypt. + * This pointer can be NULL if ilen == 0. * \param output Buffer to where the encrypted or decrypted data is written. + * This pointer can be NULL if ilen == 0. * \param mac Buffer to where the computed 128-bit (16 bytes) MAC is written. * * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index ab87f66b9..ccce12270 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -136,7 +136,9 @@ int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, * \param ctx The ChaCha20 context. * \param size The length (in bytes) to process. This can have any length. * \param input Buffer containing the input data. + * This pointer can be NULL if size == 0. * \param output Buffer containing the output data. + * This pointer can be NULL if size == 0. * * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or * output pointers are NULL. diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index 1aa55aeee..ea9364a3c 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -85,6 +85,7 @@ int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx, * \param ctx The Poly1305 context. * \param ilen The input length (in bytes). Any value is accepted. * \param input Buffer containing the input data to Process. + * This pointer can be NULL if ilen == 0. * * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx * or input are NULL. diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index ab29dfa1b..2dea5c9c5 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -174,10 +174,15 @@ int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_co size_t aad_len, const unsigned char *aad ) { - if ( ( ctx == NULL ) || ( aad == NULL ) ) + if ( ctx == NULL ) { return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); } + else if ( ( aad_len > 0U ) && ( aad == NULL ) ) + { + /* aad pointer is allowed to be NULL if aad_len == 0 */ + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } else if ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) { return (MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); @@ -197,6 +202,11 @@ int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_contex { return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); } + else if ( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) ) + { + /* input and output pointers are allowed to be NULL if len == 0 */ + return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + } else if ( ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) && ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ) ) { diff --git a/library/chacha20.c b/library/chacha20.c index b20c7ad55..351124541 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -291,10 +291,15 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, size_t offset = 0U; size_t i; - if ( ( ctx == NULL ) || ( input == NULL ) || ( output == NULL ) ) + if ( ctx == NULL ) { return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); } + else if ( ( size > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) ) + { + /* input and output pointers are allowed to be NULL only if size == 0 */ + return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + } /* Use leftover keystream bytes, if available */ while ( ( size > 0U ) && ( ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) ) diff --git a/library/poly1305.c b/library/poly1305.c index 9a61a85ce..f9bdf2c93 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -293,12 +293,17 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, size_t queue_free_len; size_t nblocks; - if ( ( ctx == NULL ) || ( input == NULL ) ) + if ( ctx == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } + else if ( ( ilen > 0U ) && ( input == NULL ) ) + { + /* input pointer is allowed to be NULL only if ilen == 0 */ + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } - if ( ctx->queue_len > 0U ) + if ( ( remaining > 0U ) && ( ctx->queue_len > 0U ) ) { queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); From b437a98faf3684b06dc06901c72e7de9e862ca31 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 17 May 2016 20:33:28 -0300 Subject: [PATCH 06/42] Add ChaCha20+Poly1305 to the Cipher module --- include/mbedtls/cipher.h | 19 +- library/cipher.c | 191 ++++++++++++++++-- library/cipher_wrap.c | 73 +++++++ library/version_features.c | 12 +- tests/CMakeLists.txt | 1 + tests/Makefile | 9 + ...t_suite_cipher.aead_chacha20_poly1305.data | 111 ++++++++++ 7 files changed, 391 insertions(+), 25 deletions(-) create mode 100644 tests/suites/test_suite_cipher.aead_chacha20_poly1305.data diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index c5a50c0d2..f954ccec3 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -37,7 +37,7 @@ #include -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) #define MBEDTLS_CIPHER_MODE_AEAD #endif @@ -147,6 +147,7 @@ typedef enum { MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ MBEDTLS_CIPHER_CHACHA20, /**< Chacha20 stream cipher. */ + MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< Chacha20-Poly1305 AEAD cipher. */ } mbedtls_cipher_type_t; /** Supported cipher modes. */ @@ -562,11 +563,11 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, */ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) /** * \brief This function adds additional data for AEAD ciphers. - * Only supported with GCM. Must be called - * exactly once, after mbedtls_cipher_reset(). + * Currently supported with GCM and ChaCha20+Poly1305. + * Must be called exactly once, after mbedtls_cipher_reset(). * * \param ctx The generic cipher context. * \param ad The additional data to use. @@ -577,7 +578,7 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); */ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ); -#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ /** * \brief The generic cipher update function. It encrypts or @@ -635,10 +636,10 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) /** * \brief This function writes a tag for AEAD ciphers. - * Only supported with GCM. + * Currently supported with GCM and ChaCha20+Poly1305. * Must be called after mbedtls_cipher_finish(). * * \param ctx The generic cipher context. @@ -653,7 +654,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, /** * \brief This function checks the tag for AEAD ciphers. - * Only supported with GCM. + * Currently supported with GCM and ChaCha20+Poly1305. * Must be called after mbedtls_cipher_finish(). * * \param ctx The generic cipher context. @@ -665,7 +666,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, */ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ /** * \brief The generic all-in-one encryption/decryption function, diff --git a/library/cipher.c b/library/cipher.c index 68d0c10ff..b51a40bcc 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -38,6 +38,10 @@ #include #include +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#include "mbedtls/aead_chacha20_poly1305.h" +#endif + #if defined(MBEDTLS_GCM_C) #include "mbedtls/gcm.h" #endif @@ -65,6 +69,22 @@ #define MBEDTLS_CIPHER_MODE_STREAM #endif +/* Compare the contents of two buffers in constant time. + * Returns 0 if the contents are bitwise identical, otherwise returns + * a non-zero value. */ +static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) +{ + const unsigned char *p1 = (const unsigned char*) v1; + const unsigned char *p2 = (const unsigned char*) v2; + size_t i; + unsigned char diff; + + for( diff = 0, i = 0; i < len; i++ ) + diff |= p1[i] ^ p2[i]; + + return (int)diff; +} + static int supported_init = 0; const int *mbedtls_cipher_list( void ) @@ -263,22 +283,45 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) return( 0 ); } -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ) { if( NULL == ctx || NULL == ctx->cipher_info ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +#if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, ctx->iv, ctx->iv_size, ad, ad_len ); } +#endif + +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + int result; + mbedtls_aead_chacha20_poly1305_mode_t mode; + + mode = ( ctx->operation == MBEDTLS_ENCRYPT ) + ? MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT + : MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT; + + result = mbedtls_aead_chacha20_poly1305_starts( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ctx->iv, + mode ); + if ( result != 0 ) + return( result ); + + return mbedtls_aead_chacha20_poly1305_update_aad( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ad_len, ad ); + } +#endif return( 0 ); } -#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen ) @@ -340,6 +383,21 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif + if( input == output && + ( ctx->unprocessed_len != 0 || ilen % mbedtls_cipher_get_block_size( ctx ) ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) + { + *olen = ilen; + return mbedtls_aead_chacha20_poly1305_update( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ilen, input, output ); + } +#endif + #if defined(MBEDTLS_CIPHER_MODE_CBC) if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) { @@ -672,7 +730,8 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, return( 0 ); } - if ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) + if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || + ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) { return( 0 ); } @@ -788,7 +847,7 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_ciph } #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { @@ -798,8 +857,22 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, if( MBEDTLS_ENCRYPT != ctx->operation ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +#if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); +#endif + +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + /* Don't allow truncated MAC for Poly1305 */ + if ( tag_len != 16U ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + tag ); + } +#endif return( 0 ); } @@ -807,6 +880,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ) { + unsigned char check_tag[16]; int ret; if( NULL == ctx || NULL == ctx->cipher_info || @@ -815,12 +889,9 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } +#if defined(MBEDTLS_GCM_C) if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) { - unsigned char check_tag[16]; - size_t i; - int diff; - if( tag_len > sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); @@ -831,18 +902,38 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, } /* Check the tag in "constant-time" */ - for( diff = 0, i = 0; i < tag_len; i++ ) - diff |= tag[i] ^ check_tag[i]; - - if( diff != 0 ) + if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); return( 0 ); } +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + /* Don't allow truncated MAC for Poly1305 */ + if ( tag_len != sizeof( check_tag ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + ret = mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + check_tag ); + if ( ret != 0 ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + if( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ return( 0 ); } -#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ /* * Packet-oriented wrapper for non-AEAD modes @@ -901,6 +992,39 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, tag, tag_len ) ); } #endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + int ret; + + if ( ( iv_len != ctx->cipher_info->iv_size ) || + ( tag_len != 16U ) ) /* Truncated MAC is not allowed for Poly1305 */ + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = ilen; + + ret = mbedtls_aead_chacha20_poly1305_starts( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + iv, MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT ); + if ( ret != 0 ) + return( ret ); + + ret = mbedtls_aead_chacha20_poly1305_update_aad( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ad_len, ad ); + if ( ret != 0 ) + return( ret ); + + ret = mbedtls_aead_chacha20_poly1305_update( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ilen, input, output ); + if ( ret != 0 ) + return( ret ); + + ret = mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + tag ); + return( ret ); + } +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } @@ -947,6 +1071,47 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, return( ret ); } #endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + unsigned char check_tag[16]; + int ret; + + if ( ( iv_len != ctx->cipher_info->iv_size ) || + ( tag_len != 16U ) ) /* Truncated MAC is not allowed for Poly1305 */ + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = ilen; + + ret = mbedtls_aead_chacha20_poly1305_starts( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + iv, MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT ); + if ( ret != 0 ) + return( ret ); + + ret = mbedtls_aead_chacha20_poly1305_update_aad( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ad_len, ad ); + if ( ret != 0 ) + return( ret ); + + ret = mbedtls_aead_chacha20_poly1305_update( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ilen, input, output ); + if ( ret != 0 ) + return( ret ); + + ret = mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + check_tag ); + if ( ret != 0 ) + return( ret ); + + /* Compare the tag in constant time */ + if ( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index f4e7964df..d8c5f0611 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -33,6 +33,10 @@ #include "mbedtls/cipher_internal.h" +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#include "mbedtls/aead_chacha20_poly1305.h" +#endif + #if defined(MBEDTLS_AES_C) #include "mbedtls/aes.h" #endif @@ -1352,6 +1356,71 @@ static const mbedtls_cipher_info_t chacha20_info = { }; #endif /* MBEDTLS_CHACHA20_C */ +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + +static int aead_chacha20_poly1305_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + if( key_bitlen != 256U ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if ( 0 != mbedtls_aead_chacha20_poly1305_setkey( (mbedtls_aead_chacha20_poly1305_context*)ctx, key ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( 0 ); +} + +static void * aead_chacha20_poly1305_ctx_alloc( void ) +{ + mbedtls_aead_chacha20_poly1305_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_aead_chacha20_poly1305_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_aead_chacha20_poly1305_init( ctx ); + + return( ctx ); +} + +static void aead_chacha20_poly1305_ctx_free( void *ctx ) +{ + mbedtls_aead_chacha20_poly1305_free( (mbedtls_aead_chacha20_poly1305_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t aead_chacha20_poly1305_base_info = { + MBEDTLS_CIPHER_ID_CHACHA20, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aead_chacha20_poly1305_setkey_wrap, + aead_chacha20_poly1305_setkey_wrap, + aead_chacha20_poly1305_ctx_alloc, + aead_chacha20_poly1305_ctx_free +}; +static const mbedtls_cipher_info_t aead_chacha20_poly1305_info = { + MBEDTLS_CIPHER_CHACHA20_POLY1305, + MBEDTLS_MODE_NONE, + 256, + "CHACHA20-POLY1305", + 12, + 0, + 64, + &aead_chacha20_poly1305_base_info +}; +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ + #if defined(MBEDTLS_CIPHER_NULL_CIPHER) static int null_crypt_stream( void *ctx, size_t length, const unsigned char *input, @@ -1511,6 +1580,10 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, #endif +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + { MBEDTLS_CIPHER_CHACHA20_POLY1305, &aead_chacha20_poly1305_info }, +#endif + #if defined(MBEDTLS_CIPHER_NULL_CIPHER) { MBEDTLS_CIPHER_NULL, &null_cipher_info }, #endif /* MBEDTLS_CIPHER_NULL_CIPHER */ diff --git a/library/version_features.c b/library/version_features.c index 64aa9f641..b73410c6a 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -84,6 +84,9 @@ static const char *features[] = { #if defined(MBEDTLS_TIMING_ALT) "MBEDTLS_TIMING_ALT", #endif /* MBEDTLS_TIMING_ALT */ +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) + "MBEDTLS_AEAD_CHACHA20_POLY1305_ALT", +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ #if defined(MBEDTLS_AES_ALT) "MBEDTLS_AES_ALT", #endif /* MBEDTLS_AES_ALT */ @@ -126,6 +129,9 @@ static const char *features[] = { #if defined(MBEDTLS_MD5_ALT) "MBEDTLS_MD5_ALT", #endif /* MBEDTLS_MD5_ALT */ +#if defined(MBEDTLS_POLY1305_ALT) + "MBEDTLS_POLY1305_ALT", +#endif /* MBEDTLS_POLY1305_ALT */ #if defined(MBEDTLS_RIPEMD160_ALT) "MBEDTLS_RIPEMD160_ALT", #endif /* MBEDTLS_RIPEMD160_ALT */ @@ -168,9 +174,6 @@ static const char *features[] = { #if defined(MBEDTLS_SHA512_PROCESS_ALT) "MBEDTLS_SHA512_PROCESS_ALT", #endif /* MBEDTLS_SHA512_PROCESS_ALT */ -#if defined(MBEDTLS_POLY1305_ALT) - "MBEDTLS_POLY1305_ALT", -#endif /* MBEDTLS_POLY1305_ALT */ #if defined(MBEDTLS_DES_SETKEY_ALT) "MBEDTLS_DES_SETKEY_ALT", #endif /* MBEDTLS_DES_SETKEY_ALT */ @@ -540,6 +543,9 @@ static const char *features[] = { #if defined(MBEDTLS_CAMELLIA_C) "MBEDTLS_CAMELLIA_C", #endif /* MBEDTLS_CAMELLIA_C */ +#if defined(MBEDTLS_CHACHA20_C) + "MBEDTLS_CHACHA20_C", +#endif /* MBEDTLS_CHACHA20_C */ #if defined(MBEDTLS_CCM_C) "MBEDTLS_CCM_C", #endif /* MBEDTLS_CCM_C */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 03797ec32..c7d9fad3c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -56,6 +56,7 @@ add_test_suite(blowfish) add_test_suite(camellia) add_test_suite(ccm) add_test_suite(chacha20) +add_test_suite(cipher cipher.aead_chacha20_poly1305) add_test_suite(cipher cipher.aes) add_test_suite(cipher cipher.arc4) add_test_suite(cipher cipher.blowfish) diff --git a/tests/Makefile b/tests/Makefile index 4a23e64cc..e6ff26cf3 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -52,6 +52,7 @@ APPS = test_suite_aead_chacha20_poly1305$(EXEXT) \ test_suite_base64$(EXEXT) test_suite_blowfish$(EXEXT) \ test_suite_camellia$(EXEXT) test_suite_ccm$(EXEXT) \ test_suite_chacha20$(EXEXT) test_suite_cmac$(EXEXT) \ + test_suite_cipher.aead_chacha20_poly1305$(EXEXT) \ test_suite_cipher.aes$(EXEXT) \ test_suite_cipher.arc4$(EXEXT) test_suite_cipher.ccm$(EXEXT) \ test_suite_cipher.chacha20$(EXEXT) \ @@ -116,6 +117,10 @@ test_suite_aes.rest.c : suites/test_suite_aes.function suites/test_suite_aes.res echo " Gen $@" perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.rest +test_suite_cipher.aead_chacha20_poly1305.c : suites/test_suite_cipher.function suites/test_suite_cipher.aead_chacha20_poly1305.data scripts/generate_code.pl suites/helpers.function suites/main_test.function + echo " Gen $@" + perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.aead_chacha20_poly1305 + test_suite_cipher.aes.c : suites/test_suite_cipher.function suites/test_suite_cipher.aes.data scripts/generate_code.pl suites/helpers.function suites/main_test.function echo " Gen $@" perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.aes @@ -261,6 +266,10 @@ test_suite_cipher.aes$(EXEXT): test_suite_cipher.aes.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_cipher.aead_chacha20_poly1305$(EXEXT): test_suite_cipher.aead_chacha20_poly1305.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_cipher.arc4$(EXEXT): test_suite_cipher.arc4.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_cipher.aead_chacha20_poly1305.data b/tests/suites/test_suite_cipher.aead_chacha20_poly1305.data new file mode 100644 index 000000000..9cd1ed021 --- /dev/null +++ b/tests/suites/test_suite_cipher.aead_chacha20_poly1305.data @@ -0,0 +1,111 @@ +Decrypt empty buffer +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C: +dec_empty_buf: + +ChaCha20+Poly1305 Encrypt and decrypt 0 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:0:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 1 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:1:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 2 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:2:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 7 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:7:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 8 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:8:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 9 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:9:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 15 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:15:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 16 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:16:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 17 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:17:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 31 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:31:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 32 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:32:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 33 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:33:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 47 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:47:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 48 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:48:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 49 bytes +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:49:-1 + +ChaCha20+Poly1305 Encrypt and decrypt 0 bytes in multiple parts 1 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:0:0:-1:0:0:0:0 + +ChaCha20+Poly1305 Encrypt and decrypt 1 bytes in multiple parts 1 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:1:0:-1:1:0:1:0 + +ChaCha20+Poly1305 Encrypt and decrypt 1 bytes in multiple parts 2 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:0:1:-1:0:1:0:1 + +ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 1 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:0:-1:16:0:16:0 + +ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 2 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:0:16:-1:0:16:0:16 + +ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 3 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:1:15:-1:1:15:1:15 + +ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 4 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:15:1:-1:15:1:15:1 + +ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 1 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:15:7:-1:15:7:15:7 + +ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 2 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:7:15:-1:7:15:7:15 + +ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 3 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:6:-1:16:6:16:6 + +ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 4 +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:6:16:-1:6:16:6:16 + +ChaCha20+Poly1305 Encrypt and decrypt 32 bytes in multiple parts +depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:16:-1:16:16:16:16 From d00afaf2ba84048c4cd6c0371fcbd8343566ce63 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 10:07:53 -0300 Subject: [PATCH 07/42] Adjust verbose self-test output to match other ciphers. --- library/aead_chacha20_poly1305.c | 21 ++++++++++++++++++--- library/chacha20.c | 19 +++++++++++++++++-- library/poly1305.c | 19 +++++++++++++++++-- 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index 2dea5c9c5..3aa8d637d 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -428,6 +428,11 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) for ( i = 0U; i < 1U; i++ ) { + if ( verbose != 0 ) + { + mbedtls_printf( " ChaCha20-Poly1305 test %zi ", i ); + } + result = mbedtls_aead_chacha20_poly1305_crypt_and_mac( test_key[i], test_nonce[i], MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, @@ -441,7 +446,7 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "ChaCha20-Poly1305 test %zi error code: %i\n", i, result ); + mbedtls_printf( "error code: %i\n", result ); } return( -1 ); } @@ -450,7 +455,7 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "ChaCha20-Poly1305 test %zi failure (wrong output)\n", i ); + mbedtls_printf( "failure (wrong output)\n" ); } return( -1 ); } @@ -459,10 +464,20 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "ChaCha20-Poly1305 test %zi failure (wrong MAC)\n", i ); + mbedtls_printf( "failure (wrong MAC)\n" ); } return( -1 ); } + + if ( verbose != 0 ) + { + mbedtls_printf( "passed\n" ); + } + } + + if( verbose != 0 ) + { + mbedtls_printf( "\n" ); } return( 0 ); diff --git a/library/chacha20.c b/library/chacha20.c index 351124541..f3ddd9b96 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -559,6 +559,11 @@ int mbedtls_chacha20_self_test( int verbose ) for ( i = 0U; i < 2U; i++ ) { + if ( verbose != 0 ) + { + mbedtls_printf( " ChaCha20 test %zi ", i ); + } + result = mbedtls_chacha20_crypt( test_keys[i], test_nonces[i], test_counters[i], @@ -569,7 +574,7 @@ int mbedtls_chacha20_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "ChaCha20 test %zi error code: %i\n", i, result ); + mbedtls_printf( "error code: %i\n", result ); } return( -1 ); @@ -579,11 +584,21 @@ int mbedtls_chacha20_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "ChaCha20 test %zi failed\n", i ); + mbedtls_printf( "failed\n" ); } return( -1 ); } + + if ( verbose != 0 ) + { + mbedtls_printf( "passed\n" ); + } + } + + if( verbose != 0 ) + { + mbedtls_printf( "\n" ); } return( 0 ); diff --git a/library/poly1305.c b/library/poly1305.c index f9bdf2c93..d7c9ce160 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -490,6 +490,11 @@ int mbedtls_poly1305_self_test( int verbose ) for ( i = 0U; i < 2U; i++ ) { + if ( verbose != 0 ) + { + mbedtls_printf( " Poly1305 test %zi ", i ); + } + result = mbedtls_poly1305_mac( test_keys[i], test_data_len[i], test_data[i], @@ -498,7 +503,7 @@ int mbedtls_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "Poly1305 test %zi error code: %i\n", i, result ); + mbedtls_printf( "error code: %i\n", result ); } return( -1 ); @@ -508,11 +513,21 @@ int mbedtls_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "Poly1305 test %zi failed\n", i ); + mbedtls_printf( "failed\n" ); } return( -1 ); } + + if ( verbose != 0 ) + { + mbedtls_printf( "passed\n" ); + } + } + + if( verbose != 0 ) + { + mbedtls_printf( "\n" ); } return( 0 ); From a7472e16bc3e99ef39ce45e2aff22939bd7a4907 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 10:09:28 -0300 Subject: [PATCH 08/42] Add ChaCha20/Poly1305 ciphers to the selftest program --- programs/test/selftest.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 72a37342f..57f9924ce 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -44,6 +44,9 @@ #include "mbedtls/des.h" #include "mbedtls/aes.h" #include "mbedtls/camellia.h" +#include "mbedtls/chacha20.h" +#include "mbedtls/poly1305.h" +#include "mbedtls/aead_chacha20_poly1305.h" #include "mbedtls/base64.h" #include "mbedtls/bignum.h" #include "mbedtls/rsa.h" @@ -207,6 +210,15 @@ const selftest_t selftests[] = #if defined(MBEDTLS_CMAC_C) {"cmac", mbedtls_cmac_self_test}, #endif +#if defined(MBEDTLS_CHACHA20_C) + {"chacha20", mbedtls_chacha20_self_test}, +#endif +#if defined(MBEDTLS_POLY1305_C) + {"poly1305", mbedtls_poly1305_self_test}, +#endif +#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) + {"chacha20-poly1305", mbedtls_aead_chacha20_poly1305_self_test}, +#endif #if defined(MBEDTLS_BASE64_C) {"base64", mbedtls_base64_self_test}, #endif From 89c7b10c6ad482221a0f0b8f57cdaca6a99d6959 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 11:51:22 -0300 Subject: [PATCH 09/42] Add ChaCha20 test vectors from RFC 7539 --- tests/suites/test_suite_chacha20.data | 24 +++++++++++++ tests/suites/test_suite_chacha20.function | 41 +++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/tests/suites/test_suite_chacha20.data b/tests/suites/test_suite_chacha20.data index 79f0408a2..86094604b 100644 --- a/tests/suites/test_suite_chacha20.data +++ b/tests/suites/test_suite_chacha20.data @@ -1,2 +1,26 @@ +ChaCha20 RFC 7539 Example and Test Vector (Encrypt) +chacha20_crypt:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":1:"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0bf91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab77937365af90bbf74a35be6b40b8eedf2785e42874d" + +ChaCha20 RFC 7539 Example and Test Vector (Decrypt) +chacha20_crypt:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f":"000000000000004a00000000":1:"6e2e359a2568f98041ba0728dd0d6981e97e7aec1d4360c20a27afccfd9fae0bf91b65c5524733ab8f593dabcd62b3571639d624e65152ab8f530c359f0861d807ca0dbf500d6a6156a38e088a22b65e52bc514d16ccf806818ce91ab77937365af90bbf74a35be6b40b8eedf2785e42874d":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e" + +ChaCha20 RFC 7539 Test Vector #1 (Encrypt) +chacha20_crypt:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":0:"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586" + +ChaCha20 RFC 7539 Test Vector #1 (Decrypt) +chacha20_crypt:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":0:"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + +ChaCha20 RFC 7539 Test Vector #2 (Encrypt) +chacha20_crypt:"0000000000000000000000000000000000000000000000000000000000000001":"000000000000000000000002":1:"416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f":"a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85ad00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6ccc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0bc39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e698ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221" + +ChaCha20 RFC 7539 Test Vector #2 (Decrypt) +chacha20_crypt:"0000000000000000000000000000000000000000000000000000000000000001":"000000000000000000000002":1:"a3fbf07df3fa2fde4f376ca23e82737041605d9f4f4f57bd8cff2c1d4b7955ec2a97948bd3722915c8f3d337f7d370050e9e96d647b7c39f56e031ca5eb6250d4042e02785ececfa4b4bb5e8ead0440e20b6e8db09d881a7c6132f420e52795042bdfa7773d8a9051447b3291ce1411c680465552aa6c405b7764d5e87bea85ad00f8449ed8f72d0d662ab052691ca66424bc86d2df80ea41f43abf937d3259dc4b2d0dfb48a6c9139ddd7f76966e928e635553ba76c5c879d7b35d49eb2e62b0871cdac638939e25e8a1e0ef9d5280fa8ca328b351c3c765989cbcf3daa8b6ccc3aaf9f3979c92b3720fc88dc95ed84a1be059c6499b9fda236e7e818b04b0bc39c1e876b193bfe5569753f88128cc08aaa9b63d1a16f80ef2554d7189c411f5869ca52c5b83fa36ff216b9c1d30062bebcfd2dc5bce0911934fda79a86f6e698ced759c3ff9b6477338f3da4f9cd8514ea9982ccafb341b2384dd902f3d1ab7ac61dd29c6f21ba5b862f3730e37cfdc4fd806c22f221":"416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f" + +ChaCha20 RFC 7539 Test Vector #3 (Encrypt) +chacha20_crypt:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000000000000000002":42:"2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e":"62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1" + +ChaCha20 RFC 7539 Test Vector #3 (Decrypt) +chacha20_crypt:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000000000000000002":42:"62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1":"2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e" + ChaCha20 Selftest chacha20_self_test: diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index 2825a6148..75d2d0fc9 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -6,6 +6,47 @@ * depends_on:MBEDTLS_CHACHA20_C * END_DEPENDENCIES */ + +/* BEGIN_CASE */ +void chacha20_crypt( char *hex_key_string, + char *hex_nonce_string, + int counter, + char *hex_src_string, + char *hex_dst_string ) +{ + unsigned char key_str[100]; + unsigned char nonce_str[100]; + unsigned char src_str[10000]; + unsigned char dst_str[10000]; + unsigned char output[10000]; + size_t key_len; + size_t nonce_len; + size_t src_len; + size_t dst_len; + + memset(key_str, 0x00, 100); + memset(nonce_str, 0x00, 100); + memset(src_str, 0x00, 10000); + memset(dst_str, 0x00, 10000); + memset(output, 0x00, 10000); + + key_len = unhexify( key_str, hex_key_string ); + nonce_len = unhexify( nonce_str, hex_nonce_string ); + src_len = unhexify( src_str, hex_src_string ); + dst_len = unhexify( dst_str, hex_dst_string ); + + TEST_ASSERT( src_len == dst_len ); + TEST_ASSERT( key_len == 32U ); + TEST_ASSERT( nonce_len == 12U ); + + TEST_ASSERT( mbedtls_chacha20_crypt( key_str, nonce_str, counter, src_len, src_str, output ) == 0 ); + + hexify( dst_str, output, src_len ); + + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void chacha20_self_test() { From 5b7f1d8035431f4e761fe336ea0105f1bb5af1e4 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 12:04:41 -0300 Subject: [PATCH 10/42] Fix test suite when GCM Is disabled, but AEAD_ChaCha20_Poly1305 is enabled. --- tests/suites/test_suite_cipher.function | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index 8f1109ee8..e5a252fdb 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -60,7 +60,7 @@ void cipher_null_args( ) TEST_ASSERT( mbedtls_cipher_reset( NULL ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_cipher_reset( &ctx ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( mbedtls_cipher_update_ad( NULL, buf, 0 ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_cipher_update_ad( &ctx, buf, 0 ) @@ -77,7 +77,7 @@ void cipher_null_args( ) TEST_ASSERT( mbedtls_cipher_finish( &ctx, buf, &olen ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( mbedtls_cipher_write_tag( NULL, buf, olen ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_cipher_write_tag( &ctx, buf, olen ) @@ -195,7 +195,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len, TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, ad, sizeof( ad ) - i ) ); TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, ad, sizeof( ad ) - i ) ); #endif @@ -215,7 +215,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len, TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_enc, encbuf + outlen, &outlen ) ); total_len += outlen; -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_write_tag( &ctx_enc, tag, sizeof( tag ) ) ); #endif @@ -236,7 +236,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len, TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) ); total_len += outlen; -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_check_tag( &ctx_dec, tag, sizeof( tag ) ) ); #endif @@ -292,7 +292,7 @@ void enc_fail( int cipher_id, int pad_mode, int key_len, #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv, 16 ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, NULL, 0 ) ); #endif @@ -340,7 +340,7 @@ void dec_empty_buf() TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) ); #endif @@ -416,7 +416,7 @@ void enc_dec_buf_multipart( int cipher_id, int key_len, int first_length_val, TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) ); TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, NULL, 0 ) ); #endif @@ -484,7 +484,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, unsigned char ad[200]; unsigned char tag[20]; size_t key_len, iv_len, cipher_len, clear_len; -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) size_t ad_len, tag_len; #endif mbedtls_cipher_context_t ctx; @@ -505,7 +505,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, iv_len = unhexify( iv, hex_iv ); cipher_len = unhexify( cipher, hex_cipher ); clear_len = unhexify( clear, hex_clear ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) ad_len = unhexify( ad, hex_ad ); tag_len = unhexify( tag, hex_tag ); #else @@ -525,7 +525,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv, iv_len ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) ); -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, ad, ad_len ) ); #endif @@ -536,7 +536,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, TEST_ASSERT( finish_result == mbedtls_cipher_finish( &ctx, output + outlen, &outlen ) ); total_len += outlen; -#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) TEST_ASSERT( tag_result == mbedtls_cipher_check_tag( &ctx, tag, tag_len ) ); #endif From b9a069d0960e3fbf8c6c1816a1171a20514c6741 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 13:38:22 -0300 Subject: [PATCH 11/42] Fix unused function warning under certain configurations. I refactored some code into the function mbedtls_constant_time_memcmp in commit 7aad291 but this function is only used by GCM and AEAD_ChaCha20_Poly1305 to check the tags. So this function is now only enabled if either of these two ciphers is enabled. --- library/cipher.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/cipher.c b/library/cipher.c index b51a40bcc..71fa6f535 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -69,9 +69,13 @@ #define MBEDTLS_CIPHER_MODE_STREAM #endif + +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) /* Compare the contents of two buffers in constant time. * Returns 0 if the contents are bitwise identical, otherwise returns - * a non-zero value. */ + * a non-zero value. + * This is currently only used by GCM and ChaCha20+Poly1305. + */ static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t len ) { const unsigned char *p1 = (const unsigned char*) v1; @@ -84,6 +88,7 @@ static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t return (int)diff; } +#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ static int supported_init = 0; From 47252c739d27d59a3cb27b671b3323f0545d1806 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Thu, 19 May 2016 09:57:59 -0300 Subject: [PATCH 12/42] Correct signedness of printf specifier in self tests --- library/aead_chacha20_poly1305.c | 2 +- library/chacha20.c | 2 +- library/poly1305.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index 3aa8d637d..dac96ae34 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -430,7 +430,7 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( " ChaCha20-Poly1305 test %zi ", i ); + mbedtls_printf( " ChaCha20-Poly1305 test %zu ", i ); } result = mbedtls_aead_chacha20_poly1305_crypt_and_mac( test_key[i], diff --git a/library/chacha20.c b/library/chacha20.c index f3ddd9b96..437e38069 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -561,7 +561,7 @@ int mbedtls_chacha20_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( " ChaCha20 test %zi ", i ); + mbedtls_printf( " ChaCha20 test %zu ", i ); } result = mbedtls_chacha20_crypt( test_keys[i], diff --git a/library/poly1305.c b/library/poly1305.c index d7c9ce160..004d8574a 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -492,7 +492,7 @@ int mbedtls_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( " Poly1305 test %zi ", i ); + mbedtls_printf( " Poly1305 test %zu ", i ); } result = mbedtls_poly1305_mac( test_keys[i], From f589275d8021f269b43774cc0600c538e7fb5bc9 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 24 May 2016 11:16:17 -0300 Subject: [PATCH 13/42] Minor style and formatting fixes. This change corrects some minor style violations, mostly for spacing around parentheses. --- library/aead_chacha20_poly1305.c | 68 ++++++------ library/chacha20.c | 30 +++--- library/poly1305.c | 176 +++++++++++++++---------------- 3 files changed, 137 insertions(+), 137 deletions(-) diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index dac96ae34..8d7b63a70 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -59,15 +59,15 @@ static void mbedtls_zeroize( void *v, size_t n ) { */ static void mbedtls_aead_chacha20_poly1305_pad_aad( mbedtls_aead_chacha20_poly1305_context *ctx ) { - uint32_t partial_block_len = (uint32_t)( ctx->aad_len % 16U ); + uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); unsigned char zeroes[15]; if ( partial_block_len > 0U ) { - memset( zeroes, 0, sizeof(zeroes) ); - (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, - 16U - partial_block_len, - zeroes ); + memset( zeroes, 0, sizeof( zeroes ) ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, + 16U - partial_block_len, + zeroes ); } } @@ -78,15 +78,15 @@ static void mbedtls_aead_chacha20_poly1305_pad_aad( mbedtls_aead_chacha20_poly13 */ static void mbedtls_aead_chacha20_poly1305_pad_ciphertext( mbedtls_aead_chacha20_poly1305_context *ctx ) { - uint32_t partial_block_len = (uint32_t)( ctx->ciphertext_len % 16U ); + uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); unsigned char zeroes[15]; if ( partial_block_len > 0U ) { - memset( zeroes, 0, sizeof(zeroes) ); - (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, - 16U - partial_block_len, - zeroes ); + memset( zeroes, 0, sizeof( zeroes ) ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, + 16U - partial_block_len, + zeroes ); } } @@ -185,12 +185,12 @@ int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_co } else if ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) { - return (MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + return(MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); } ctx->aad_len += aad_len; - return ( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad_len, aad ) ); + return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad_len, aad ) ); } int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_context *ctx, @@ -228,13 +228,13 @@ int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_contex * the input pointers are NULL. Since we have checked their validity * above, we can safety ignore the return value. */ - (void)mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); - (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, len, output ); + (void) mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, len, output ); } else /* DECRYPT */ { - (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, len, input ); - (void)mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, len, input ); + (void) mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); } return( 0 ); @@ -268,25 +268,25 @@ int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_contex /* The lengths of the AAD and ciphertext are processed by * Poly1305 as the final 128-bit block, encoded as little-endian integers. */ - len_block[0] = (unsigned char)ctx->aad_len; - len_block[1] = (unsigned char)( ctx->aad_len >> 8 ); - len_block[2] = (unsigned char)( ctx->aad_len >> 16 ); - len_block[3] = (unsigned char)( ctx->aad_len >> 24 ); - len_block[4] = (unsigned char)( ctx->aad_len >> 32 ); - len_block[5] = (unsigned char)( ctx->aad_len >> 40 ); - len_block[6] = (unsigned char)( ctx->aad_len >> 48 ); - len_block[7] = (unsigned char)( ctx->aad_len >> 56 ); - len_block[8] = (unsigned char)ctx->ciphertext_len; - len_block[9] = (unsigned char)( ctx->ciphertext_len >> 8 ); - len_block[10] = (unsigned char)( ctx->ciphertext_len >> 16 ); - len_block[11] = (unsigned char)( ctx->ciphertext_len >> 24 ); - len_block[12] = (unsigned char)( ctx->ciphertext_len >> 32 ); - len_block[13] = (unsigned char)( ctx->ciphertext_len >> 40 ); - len_block[14] = (unsigned char)( ctx->ciphertext_len >> 48 ); - len_block[15] = (unsigned char)( ctx->ciphertext_len >> 56 ); + len_block[0] = (unsigned char) ctx->aad_len; + len_block[1] = (unsigned char) ( ctx->aad_len >> 8 ); + len_block[2] = (unsigned char) ( ctx->aad_len >> 16 ); + len_block[3] = (unsigned char) ( ctx->aad_len >> 24 ); + len_block[4] = (unsigned char) ( ctx->aad_len >> 32 ); + len_block[5] = (unsigned char) ( ctx->aad_len >> 40 ); + len_block[6] = (unsigned char) ( ctx->aad_len >> 48 ); + len_block[7] = (unsigned char) ( ctx->aad_len >> 56 ); + len_block[8] = (unsigned char) ctx->ciphertext_len; + len_block[9] = (unsigned char) ( ctx->ciphertext_len >> 8 ); + len_block[10] = (unsigned char) ( ctx->ciphertext_len >> 16 ); + len_block[11] = (unsigned char) ( ctx->ciphertext_len >> 24 ); + len_block[12] = (unsigned char) ( ctx->ciphertext_len >> 32 ); + len_block[13] = (unsigned char) ( ctx->ciphertext_len >> 40 ); + len_block[14] = (unsigned char) ( ctx->ciphertext_len >> 48 ); + len_block[15] = (unsigned char) ( ctx->ciphertext_len >> 56 ); - (void)mbedtls_poly1305_update( &ctx->poly1305_ctx, 16U, len_block ); - (void)mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, 16U, len_block ); + (void) mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); return( 0 ); } diff --git a/library/chacha20.c b/library/chacha20.c index 437e38069..4c2d8ef9a 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -46,14 +46,14 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ -#define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t)data[offset] | \ - (uint32_t)( (uint32_t)data[(offset) + 1] << 8 ) | \ - (uint32_t)( (uint32_t)data[(offset) + 2] << 16 ) | \ - (uint32_t)( (uint32_t)data[(offset) + 3] << 24 ) \ +#define BYTES_TO_U32_LE( data, offset ) \ + ( (uint32_t) data[offset] \ + | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \ + | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 ) \ + | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \ ) -#define ROTL32( value, amount ) ( (uint32_t)( value << amount ) | ( value >> ( 32 - amount ) ) ) +#define ROTL32( value, amount ) ( (uint32_t) ( value << amount ) | ( value >> ( 32 - amount ) ) ) #define CHACHA20_CTR_INDEX ( 12U ) @@ -171,10 +171,10 @@ static void mbedtls_chacha20_block( const uint32_t initial_state[16], { offset = i * 4U; - keystream[offset ] = (unsigned char) working_state[i]; - keystream[offset + 1U] = (unsigned char)( working_state[i] >> 8 ); - keystream[offset + 2U] = (unsigned char)( working_state[i] >> 16 ); - keystream[offset + 3U] = (unsigned char)( working_state[i] >> 24 ); + keystream[offset ] = (unsigned char) working_state[i]; + keystream[offset + 1U] = (unsigned char) ( working_state[i] >> 8 ); + keystream[offset + 2U] = (unsigned char) ( working_state[i] >> 16 ); + keystream[offset + 3U] = (unsigned char) ( working_state[i] >> 24 ); } } @@ -277,10 +277,10 @@ int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, mbedtls_chacha20_block( initial_state, working_state, keystream ); - mbedtls_zeroize( initial_state, sizeof(initial_state) ); - mbedtls_zeroize( working_state, sizeof(working_state) ); + mbedtls_zeroize( initial_state, sizeof( initial_state ) ); + mbedtls_zeroize( working_state, sizeof( working_state ) ); - return ( 0 ); + return( 0 ); } int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, @@ -351,7 +351,7 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, ctx->initial_state[CHACHA20_CTR_INDEX]++; } - return 0; + return( 0 ); } #endif /* !MBEDTLS_CHACHA20_ALT */ @@ -380,7 +380,7 @@ int mbedtls_chacha20_crypt( const unsigned char key[32], cleanup: mbedtls_chacha20_free( &ctx ); - return result; + return( result ); } #if defined(MBEDTLS_SELF_TEST) diff --git a/library/poly1305.c b/library/poly1305.c index 004d8574a..842a4d464 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -45,11 +45,11 @@ #define POLY1305_BLOCK_SIZE_BYTES ( 16U ) -#define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t)data[offset] | \ - (uint32_t)( (uint32_t)data[(offset) + 1] << 8 ) | \ - (uint32_t)( (uint32_t)data[(offset) + 2] << 16 ) | \ - (uint32_t)( (uint32_t)data[(offset) + 3] << 24 ) \ +#define BYTES_TO_U32_LE( data, offset ) \ + ( (uint32_t) data[offset] \ + | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \ + | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 ) \ + | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \ ) /* Implementation that should never be optimized out by the compiler */ @@ -100,59 +100,59 @@ static void mbedtls_poly1305_process( mbedtls_poly1305_context *ctx, { /* Compute: acc += block */ /* Note that the input block is treated as a 128-bit little-endian integer */ - d0 = (uint64_t)acc0 + BYTES_TO_U32_LE( input, offset + 0 ); - d1 = (uint64_t)acc1 + BYTES_TO_U32_LE( input, offset + 4 ) + ( d0 >> 32U ); - d2 = (uint64_t)acc2 + BYTES_TO_U32_LE( input, offset + 8 ) + ( d1 >> 32U ); - d3 = (uint64_t)acc3 + BYTES_TO_U32_LE( input, offset + 12 ) + ( d2 >> 32U ); - acc0 = (uint32_t)d0; - acc1 = (uint32_t)d1; - acc2 = (uint32_t)d2; - acc3 = (uint32_t)d3; - acc4 += (uint32_t)( d3 >> 32U ) + needs_padding; + d0 = (uint64_t) acc0 + BYTES_TO_U32_LE( input, offset + 0 ); + d1 = (uint64_t) acc1 + BYTES_TO_U32_LE( input, offset + 4 ) + ( d0 >> 32U ); + d2 = (uint64_t) acc2 + BYTES_TO_U32_LE( input, offset + 8 ) + ( d1 >> 32U ); + d3 = (uint64_t) acc3 + BYTES_TO_U32_LE( input, offset + 12 ) + ( d2 >> 32U ); + acc0 = (uint32_t) d0; + acc1 = (uint32_t) d1; + acc2 = (uint32_t) d2; + acc3 = (uint32_t) d3; + acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding; /* Compute: acc *= r */ - d0 = ( (uint64_t)acc0 * r0 ) + - ( (uint64_t)acc1 * rs3 ) + - ( (uint64_t)acc2 * rs2 ) + - ( (uint64_t)acc3 * rs1 ); - d1 = ( (uint64_t)acc0 * r1 ) + - ( (uint64_t)acc1 * r0 ) + - ( (uint64_t)acc2 * rs3 ) + - ( (uint64_t)acc3 * rs2 ) + - ( (uint64_t)acc4 * rs1 ); - d2 = ( (uint64_t)acc0 * r2 ) + - ( (uint64_t)acc1 * r1 ) + - ( (uint64_t)acc2 * r0 ) + - ( (uint64_t)acc3 * rs3 ) + - ( (uint64_t)acc4 * rs2 ); - d3 = ( (uint64_t)acc0 * r3 ) + - ( (uint64_t)acc1 * r2 ) + - ( (uint64_t)acc2 * r1 ) + - ( (uint64_t)acc3 * r0 ) + - ( (uint64_t)acc4 * rs3 ); + d0 = ( (uint64_t) acc0 * r0 ) + + ( (uint64_t) acc1 * rs3 ) + + ( (uint64_t) acc2 * rs2 ) + + ( (uint64_t) acc3 * rs1 ); + d1 = ( (uint64_t) acc0 * r1 ) + + ( (uint64_t) acc1 * r0 ) + + ( (uint64_t) acc2 * rs3 ) + + ( (uint64_t) acc3 * rs2 ) + + ( (uint64_t) acc4 * rs1 ); + d2 = ( (uint64_t) acc0 * r2 ) + + ( (uint64_t) acc1 * r1 ) + + ( (uint64_t) acc2 * r0 ) + + ( (uint64_t) acc3 * rs3 ) + + ( (uint64_t) acc4 * rs2 ); + d3 = ( (uint64_t) acc0 * r3 ) + + ( (uint64_t) acc1 * r2 ) + + ( (uint64_t) acc2 * r1 ) + + ( (uint64_t) acc3 * r0 ) + + ( (uint64_t) acc4 * rs3 ); acc4 *= r0; /* Compute: acc %= (2^130 - 5) (partial remainder) */ d1 += ( d0 >> 32 ); d2 += ( d1 >> 32 ); d3 += ( d2 >> 32 ); - acc0 = (uint32_t)d0; - acc1 = (uint32_t)d1; - acc2 = (uint32_t)d2; - acc3 = (uint32_t)d3; - acc4 = (uint32_t)( d3 >> 32 ) + acc4; + acc0 = (uint32_t) d0; + acc1 = (uint32_t) d1; + acc2 = (uint32_t) d2; + acc3 = (uint32_t) d3; + acc4 = (uint32_t) ( d3 >> 32 ) + acc4; - d0 = (uint64_t)acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU ); + d0 = (uint64_t) acc0 + ( acc4 >> 2 ) + ( acc4 & 0xFFFFFFFCU ); acc4 &= 3U; - acc0 = (uint32_t)d0; - d0 = (uint64_t)acc1 + ( d0 >> 32U ); - acc1 = (uint32_t)d0; - d0 = (uint64_t)acc2 + ( d0 >> 32U ); - acc2 = (uint32_t)d0; - d0 = (uint64_t)acc3 + ( d0 >> 32U ); - acc3 = (uint32_t)d0; - d0 = (uint64_t)acc4 + ( d0 >> 32U ); - acc4 = (uint32_t)d0; + acc0 = (uint32_t) d0; + d0 = (uint64_t) acc1 + ( d0 >> 32U ); + acc1 = (uint32_t) d0; + d0 = (uint64_t) acc2 + ( d0 >> 32U ); + acc2 = (uint32_t) d0; + d0 = (uint64_t) acc3 + ( d0 >> 32U ); + acc3 = (uint32_t) d0; + d0 = (uint64_t) acc4 + ( d0 >> 32U ); + acc4 = (uint32_t) d0; offset += POLY1305_BLOCK_SIZE_BYTES; } @@ -192,18 +192,18 @@ static void mbedtls_poly1305_compute_mac( const mbedtls_poly1305_context *ctx, */ /* Calculate acc + -(2^130 - 5) */ - d = ( (uint64_t)acc0 + 5U ); - g0 = (uint32_t)d; - d = ( (uint64_t)acc1 + ( d >> 32 ) ); - g1 = (uint32_t)d; - d = ( (uint64_t)acc2 + ( d >> 32 ) ); - g2 = (uint32_t)d; - d = ( (uint64_t)acc3 + ( d >> 32 ) ); - g3 = (uint32_t)d; - g4 = acc4 + (uint32_t)( d >> 32U ); + d = ( (uint64_t) acc0 + 5U ); + g0 = (uint32_t) d; + d = ( (uint64_t) acc1 + ( d >> 32 ) ); + g1 = (uint32_t) d; + d = ( (uint64_t) acc2 + ( d >> 32 ) ); + g2 = (uint32_t) d; + d = ( (uint64_t) acc3 + ( d >> 32 ) ); + g3 = (uint32_t) d; + g4 = acc4 + (uint32_t) ( d >> 32U ); /* mask == 0xFFFFFFFF if 131st bit is set, otherwise mask == 0 */ - mask = (uint32_t)0U - ( g4 >> 2U ); + mask = (uint32_t) 0U - ( g4 >> 2U ); mask_inv = ~mask; /* If 131st bit is set then acc=g, otherwise, acc is unmodified */ @@ -213,38 +213,38 @@ static void mbedtls_poly1305_compute_mac( const mbedtls_poly1305_context *ctx, acc3 = ( acc3 & mask_inv ) | ( g3 & mask ); /* Add 's' */ - d = (uint64_t)acc0 + ctx->s[0]; - acc0 = (uint32_t)d; - d = (uint64_t)acc1 + ctx->s[1] + ( d >> 32U ); - acc1 = (uint32_t)d; - d = (uint64_t)acc2 + ctx->s[2] + ( d >> 32U ); - acc2 = (uint32_t)d; - acc3 += ctx->s[3] + (uint32_t)( d >> 32U ); + d = (uint64_t) acc0 + ctx->s[0]; + acc0 = (uint32_t) d; + d = (uint64_t) acc1 + ctx->s[1] + ( d >> 32U ); + acc1 = (uint32_t) d; + d = (uint64_t) acc2 + ctx->s[2] + ( d >> 32U ); + acc2 = (uint32_t) d; + acc3 += ctx->s[3] + (uint32_t) ( d >> 32U ); /* Compute MAC (128 least significant bits of the accumulator) */ - mac[0] = (uint8_t)acc0; - mac[1] = (uint8_t)( acc0 >> 8 ); - mac[2] = (uint8_t)( acc0 >> 16 ); - mac[3] = (uint8_t)( acc0 >> 24 ); - mac[4] = (uint8_t)acc1; - mac[5] = (uint8_t)( acc1 >> 8 ); - mac[6] = (uint8_t)( acc1 >> 16 ); - mac[7] = (uint8_t)( acc1 >> 24 ); - mac[8] = (uint8_t)acc2; - mac[9] = (uint8_t)( acc2 >> 8 ); - mac[10] = (uint8_t)( acc2 >> 16 ); - mac[11] = (uint8_t)( acc2 >> 24 ); - mac[12] = (uint8_t)acc3; - mac[13] = (uint8_t)( acc3 >> 8 ); - mac[14] = (uint8_t)( acc3 >> 16 ); - mac[15] = (uint8_t)( acc3 >> 24 ); + mac[0] = (unsigned char) acc0; + mac[1] = (unsigned char) ( acc0 >> 8 ); + mac[2] = (unsigned char) ( acc0 >> 16 ); + mac[3] = (unsigned char) ( acc0 >> 24 ); + mac[4] = (unsigned char) acc1; + mac[5] = (unsigned char) ( acc1 >> 8 ); + mac[6] = (unsigned char) ( acc1 >> 16 ); + mac[7] = (unsigned char) ( acc1 >> 24 ); + mac[8] = (unsigned char) acc2; + mac[9] = (unsigned char) ( acc2 >> 8 ); + mac[10] = (unsigned char) ( acc2 >> 16 ); + mac[11] = (unsigned char) ( acc2 >> 24 ); + mac[12] = (unsigned char) acc3; + mac[13] = (unsigned char) ( acc3 >> 8 ); + mac[14] = (unsigned char) ( acc3 >> 16 ); + mac[15] = (unsigned char) ( acc3 >> 24 ); } void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) { if ( ctx != NULL ) { - mbedtls_zeroize( ctx, sizeof(mbedtls_poly1305_context) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); } } @@ -252,7 +252,7 @@ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) { if ( ctx != NULL ) { - mbedtls_zeroize( ctx, sizeof(mbedtls_poly1305_context) ); + mbedtls_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); } } @@ -281,7 +281,7 @@ int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx, ctx->acc[2] = 0U; ctx->acc[3] = 0U; - return 0; + return( 0 ); } int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, @@ -484,7 +484,7 @@ static const unsigned char test_mac[2][16] = int mbedtls_poly1305_self_test( int verbose ) { - uint8_t mac[16]; + unsigned char mac[16]; size_t i; int result; @@ -496,9 +496,9 @@ int mbedtls_poly1305_self_test( int verbose ) } result = mbedtls_poly1305_mac( test_keys[i], - test_data_len[i], - test_data[i], - mac ); + test_data_len[i], + test_data[i], + mac ); if ( result != 0 ) { if ( verbose != 0 ) From 690d9e6fad23ec9cac0260fc7ddca41180ec09ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 3 May 2018 12:49:58 +0200 Subject: [PATCH 14/42] Add ChangeLog entry for new features. Fixes #346 --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7b50534ca..990d7caac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,11 @@ mbed TLS ChangeLog (Sorted per branch, date) = mbed TLS x.x.x branch released xxxx-xx-xx +Features + * Add new crypto primitives from RFC 7539: stream cipher Chacha20, one-time + authenticator Poly1305 and AEAD construct Chacha20-Poly1305. Contributed by + Daniel King (#485). + API Changes * Extend the platform module with a util component that contains functionality shared by multiple Mbed TLS modules. At this stage From deda80e80da3984af81ced6e0227c2f23c34d832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 09:58:35 +0200 Subject: [PATCH 15/42] Adapt the _ALT style to our new standard - in .h files: only put the context declaration inside the #ifdef _ALT (this was changed in 2.9.0, ie after the original PR) - in .c file: only leave selftest out of _ALT: even though some function are trivial to build from other parts, alt implementors might want to go another way about them (for efficiency or other reasons) --- include/mbedtls/aead_chacha20_poly1305.h | 18 +++++++++--------- include/mbedtls/chacha20.h | 12 ++++++------ include/mbedtls/poly1305.h | 12 ++++++------ library/aead_chacha20_poly1305.c | 4 ++-- library/chacha20.c | 4 ++-- library/poly1305.c | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/mbedtls/aead_chacha20_poly1305.h b/include/mbedtls/aead_chacha20_poly1305.h index 6c8e420b5..6f7ab6f7f 100644 --- a/include/mbedtls/aead_chacha20_poly1305.h +++ b/include/mbedtls/aead_chacha20_poly1305.h @@ -29,11 +29,6 @@ #include MBEDTLS_CONFIG_FILE #endif -#if !defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) - -#include "chacha20.h" -#include "poly1305.h" - #define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ #define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ @@ -44,6 +39,11 @@ typedef enum } mbedtls_aead_chacha20_poly1305_mode_t; +#if !defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) + +#include "chacha20.h" +#include "poly1305.h" + typedef struct { mbedtls_chacha20_context chacha20_ctx; /** ChaCha20 context */ @@ -55,6 +55,10 @@ typedef struct } mbedtls_aead_chacha20_poly1305_context; +#else /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ +#include "aead_chacha20_poly1305_alt.h" +#endif /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ + /** * \brief Initialize ChaCha20-Poly1305 context * @@ -183,10 +187,6 @@ int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_contex int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_context *ctx, unsigned char mac[16] ); -#else /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ -#include "aead_chacha20_poly1305_alt.h" -#endif /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ - /** * \brief Encrypt or decrypt data, and produce a MAC with ChaCha20-Poly1305. * diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index ccce12270..a2856a7e4 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -31,13 +31,13 @@ #include MBEDTLS_CONFIG_FILE #endif -#if !defined(MBEDTLS_CHACHA20_ALT) - #include #include #define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x003B /**< Invalid input parameter(s). */ +#if !defined(MBEDTLS_CHACHA20_ALT) + typedef struct { uint32_t initial_state[16]; /*! Holds the initial state (before round operations) */ @@ -47,6 +47,10 @@ typedef struct } mbedtls_chacha20_context; +#else /* MBEDTLS_CHACHA20_ALT */ +#include "chacha20_alt.h" +#endif /* MBEDTLS_CHACHA20_ALT */ + /** * \brief Initialize ChaCha20 context * @@ -149,10 +153,6 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, const unsigned char *input, unsigned char *output ); -#else /* MBEDTLS_CHACHA20_ALT */ -#include "chacha20_alt.h" -#endif /* MBEDTLS_CHACHA20_ALT */ - /** * \brief Encrypt or decrypt a message using ChaCha20. * diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index ea9364a3c..915f8ab0d 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -32,10 +32,10 @@ #include #include -#if !defined(MBEDTLS_POLY1305_ALT) - #define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0041 /**< Invalid input parameter(s). */ +#if !defined(MBEDTLS_POLY1305_ALT) + typedef struct { uint32_t r[4]; /** Stores the value for 'r' (low 128 bits of the key) */ @@ -46,6 +46,10 @@ typedef struct } mbedtls_poly1305_context; +#else /* MBEDTLS_POLY1305_ALT */ +#include "poly1305_alt.h" +#endif /* MBEDTLS_POLY1305_ALT */ + /** * \brief Initialize a Poly1305 context * @@ -109,10 +113,6 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, unsigned char mac[16] ); -#else /* MBEDTLS_POLY1305_ALT */ -#include "poly1305_alt.h" -#endif /* MBEDTLS_POLY1305_ALT */ - /** * \brief Generate the Poly1305 MAC of some data with the given key. * diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index 8d7b63a70..2e07f1ed4 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -291,8 +291,6 @@ int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_contex return( 0 ); } -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ - int mbedtls_aead_chacha20_poly1305_crypt_and_mac ( const unsigned char key[32], const unsigned char nonce[12], mbedtls_aead_chacha20_poly1305_mode_t mode, @@ -331,6 +329,8 @@ cleanup: return( result ); } +#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ + #if defined(MBEDTLS_SELF_TEST) static const unsigned char test_key[1][32] = diff --git a/library/chacha20.c b/library/chacha20.c index 4c2d8ef9a..5d2c3e5bf 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -354,8 +354,6 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, return( 0 ); } -#endif /* !MBEDTLS_CHACHA20_ALT */ - int mbedtls_chacha20_crypt( const unsigned char key[32], const unsigned char nonce[12], uint32_t counter, @@ -383,6 +381,8 @@ cleanup: return( result ); } +#endif /* !MBEDTLS_CHACHA20_ALT */ + #if defined(MBEDTLS_SELF_TEST) static const unsigned char test_keys[2][32] = diff --git a/library/poly1305.c b/library/poly1305.c index 842a4d464..6acbc7fa5 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -390,8 +390,6 @@ int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, return( 0 ); } -#endif /* MBEDTLS_POLY1305_ALT */ - int mbedtls_poly1305_mac( const unsigned char key[32], size_t ilen, const unsigned char *input, @@ -417,6 +415,8 @@ cleanup: return( 0 ); } +#endif /* MBEDTLS_POLY1305_ALT */ + #if defined(MBEDTLS_SELF_TEST) static const unsigned char test_keys[2][32] = From a9ed291d2db2489ea7246b94a462bfb32d1d87ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 10:10:30 +0200 Subject: [PATCH 16/42] Add missing extern "C" guard to new headers --- include/mbedtls/aead_chacha20_poly1305.h | 8 ++++++++ include/mbedtls/chacha20.h | 8 ++++++++ include/mbedtls/poly1305.h | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/include/mbedtls/aead_chacha20_poly1305.h b/include/mbedtls/aead_chacha20_poly1305.h index 6f7ab6f7f..21c3158b0 100644 --- a/include/mbedtls/aead_chacha20_poly1305.h +++ b/include/mbedtls/aead_chacha20_poly1305.h @@ -32,6 +32,10 @@ #define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ #define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, @@ -227,4 +231,8 @@ int mbedtls_aead_chacha20_poly1305_crypt_and_mac( const unsigned char key[32], */ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ); +#ifdef __cplusplus +} +#endif + #endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_H */ diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index a2856a7e4..f88bd28b7 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -36,6 +36,10 @@ #define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x003B /**< Invalid input parameter(s). */ +#ifdef __cplusplus +extern "C" { +#endif + #if !defined(MBEDTLS_CHACHA20_ALT) typedef struct @@ -189,4 +193,8 @@ int mbedtls_chacha20_crypt( const unsigned char key[32], */ int mbedtls_chacha20_self_test( int verbose ); +#ifdef __cplusplus +} +#endif + #endif /* MBEDTLS_CHACHA20_H */ diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index 915f8ab0d..c911b9fde 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -34,6 +34,10 @@ #define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0041 /**< Invalid input parameter(s). */ +#ifdef __cplusplus +extern "C" { +#endif + #if !defined(MBEDTLS_POLY1305_ALT) typedef struct @@ -140,4 +144,8 @@ int mbedtls_poly1305_mac( const unsigned char key[32], */ int mbedtls_poly1305_self_test( int verbose ); +#ifdef __cplusplus +} +#endif + #endif /* MBEDTLS_POLY1305_H */ From 726cf72fce3b4e5a3e9e5b7d403708a85f066f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 10:14:18 +0200 Subject: [PATCH 17/42] Avoid using %zu in selftest functions This is a C99 feature and unfortunately we can't rely on it yet considering the set of toolchain (versions) we want to support. --- library/aead_chacha20_poly1305.c | 4 ++-- library/chacha20.c | 4 ++-- library/poly1305.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index 2e07f1ed4..f00380c0b 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -421,7 +421,7 @@ static const unsigned char test_mac[1][16] = int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) { - size_t i; + unsigned i; int result; unsigned char output[200]; unsigned char mac[16]; @@ -430,7 +430,7 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( " ChaCha20-Poly1305 test %zu ", i ); + mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); } result = mbedtls_aead_chacha20_poly1305_crypt_and_mac( test_key[i], diff --git a/library/chacha20.c b/library/chacha20.c index 5d2c3e5bf..28133a675 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -554,14 +554,14 @@ static const size_t test_lengths[2] = int mbedtls_chacha20_self_test( int verbose ) { unsigned char output[381]; - size_t i; + unsigned i; int result; for ( i = 0U; i < 2U; i++ ) { if ( verbose != 0 ) { - mbedtls_printf( " ChaCha20 test %zu ", i ); + mbedtls_printf( " ChaCha20 test %u ", i ); } result = mbedtls_chacha20_crypt( test_keys[i], diff --git a/library/poly1305.c b/library/poly1305.c index 6acbc7fa5..5a096586d 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -485,14 +485,14 @@ static const unsigned char test_mac[2][16] = int mbedtls_poly1305_self_test( int verbose ) { unsigned char mac[16]; - size_t i; + unsigned i; int result; for ( i = 0U; i < 2U; i++ ) { if ( verbose != 0 ) { - mbedtls_printf( " Poly1305 test %zu ", i ); + mbedtls_printf( " Poly1305 test %u ", i ); } result = mbedtls_poly1305_mac( test_keys[i], From 54b1a7342c53b2cee7eb6a5744abc110846501c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 10:21:56 +0200 Subject: [PATCH 18/42] Rename poly1305_setkey() to poly1305_starts() For consistency with the existing CMAC and HMAC APIs --- include/mbedtls/poly1305.h | 2 +- library/aead_chacha20_poly1305.c | 2 +- library/poly1305.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index c911b9fde..f69191578 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -81,7 +81,7 @@ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); * or key are NULL. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx, +int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, const unsigned char key[32] ); /** diff --git a/library/aead_chacha20_poly1305.c b/library/aead_chacha20_poly1305.c index f00380c0b..04180081a 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/aead_chacha20_poly1305.c @@ -155,7 +155,7 @@ int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_contex if ( result != 0 ) goto cleanup; - result = mbedtls_poly1305_setkey( &ctx->poly1305_ctx, poly1305_key ); + result = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); if ( result == 0 ) { diff --git a/library/poly1305.c b/library/poly1305.c index 5a096586d..66f932c4f 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -256,7 +256,7 @@ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) } } -int mbedtls_poly1305_setkey( mbedtls_poly1305_context *ctx, +int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, const unsigned char key[32] ) { if ( ctx == NULL ) @@ -400,7 +400,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32], mbedtls_poly1305_init( &ctx ); - result = mbedtls_poly1305_setkey( &ctx, key ); + result = mbedtls_poly1305_starts( &ctx, key ); if ( result != 0 ) goto cleanup; From d4bd8569d4f14915fbc82961a6cf12cca9baac82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 10:43:27 +0200 Subject: [PATCH 19/42] Rename aead_chacha20_poly1305 to chachapoly While the old name is explicit and aligned with the RFC, it's also very long, so with the mbedtls_ prefix prepended we get a 31-char prefix to each identifier, which quickly conflicts with our 80-column policy. The new name is shorter, it's what a lot of people use when speaking about that construction anyway, and hopefully should not introduce confusion at it seems unlikely that variants other than 20/1305 be standardised in the foreseeable future. --- ...{aead_chacha20_poly1305.h => chachapoly.h} | 106 +++++------ include/mbedtls/cipher.h | 10 +- include/mbedtls/config.h | 12 +- include/mbedtls/error.h | 2 +- library/CMakeLists.txt | 2 +- library/Makefile | 5 +- ...{aead_chacha20_poly1305.c => chachapoly.c} | 166 +++++++++--------- library/cipher.c | 70 ++++---- library/cipher_wrap.c | 45 ++--- library/error.c | 22 +-- library/version_features.c | 12 +- programs/test/selftest.c | 6 +- scripts/generate_errors.pl | 5 +- tests/CMakeLists.txt | 4 +- tests/Makefile | 32 ++-- .../test_suite_aead_chacha20_poly1305.data | 19 -- tests/suites/test_suite_chachapoly.data | 19 ++ ...unction => test_suite_chachapoly.function} | 32 ++-- ...data => test_suite_cipher.chachapoly.data} | 56 +++--- tests/suites/test_suite_cipher.function | 24 +-- visualc/VS2010/mbedTLS.vcxproj | 6 + 21 files changed, 330 insertions(+), 325 deletions(-) rename include/mbedtls/{aead_chacha20_poly1305.h => chachapoly.h} (64%) rename library/{aead_chacha20_poly1305.c => chachapoly.c} (64%) delete mode 100644 tests/suites/test_suite_aead_chacha20_poly1305.data create mode 100644 tests/suites/test_suite_chachapoly.data rename tests/suites/{test_suite_aead_chacha20_poly1305.function => test_suite_chachapoly.function} (67%) rename tests/suites/{test_suite_cipher.aead_chacha20_poly1305.data => test_suite_cipher.chachapoly.data} (74%) diff --git a/include/mbedtls/aead_chacha20_poly1305.h b/include/mbedtls/chachapoly.h similarity index 64% rename from include/mbedtls/aead_chacha20_poly1305.h rename to include/mbedtls/chachapoly.h index 21c3158b0..810675ddd 100644 --- a/include/mbedtls/aead_chacha20_poly1305.h +++ b/include/mbedtls/chachapoly.h @@ -1,5 +1,5 @@ /** - * \file aead_chacha20_poly1305.h + * \file chachapoly.h * * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. * @@ -20,8 +20,8 @@ * * This file is part of mbed TLS (https://tls.mbed.org) */ -#ifndef MBEDTLS_AEAD_CHACHA20_POLY1305_H -#define MBEDTLS_AEAD_CHACHA20_POLY1305_H +#ifndef MBEDTLS_CHACHAPOLY_H +#define MBEDTLS_CHACHAPOLY_H #if !defined(MBEDTLS_CONFIG_FILE) #include "config.h" @@ -29,8 +29,8 @@ #include MBEDTLS_CONFIG_FILE #endif -#define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ -#define MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ +#define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ #ifdef __cplusplus extern "C" { @@ -38,12 +38,12 @@ extern "C" { typedef enum { - MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, - MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT + MBEDTLS_CHACHAPOLY_ENCRYPT, + MBEDTLS_CHACHAPOLY_DECRYPT } -mbedtls_aead_chacha20_poly1305_mode_t; +mbedtls_chachapoly_mode_t; -#if !defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) +#if !defined(MBEDTLS_CHACHAPOLY_ALT) #include "chacha20.h" #include "poly1305.h" @@ -55,27 +55,27 @@ typedef struct uint64_t aad_len; /** Length (bytes) of the Additional Authenticated Data */ uint64_t ciphertext_len; /** Length (bytes) of the ciphertext */ int state; /** Current state of the context */ - mbedtls_aead_chacha20_poly1305_mode_t mode; /** Cipher mode (encrypt or decrypt) */ + mbedtls_chachapoly_mode_t mode; /** Cipher mode (encrypt or decrypt) */ } -mbedtls_aead_chacha20_poly1305_context; +mbedtls_chachapoly_context; -#else /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ -#include "aead_chacha20_poly1305_alt.h" -#endif /* !MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ +#else /* !MBEDTLS_CHACHAPOLY_ALT */ +#include "chachapoly_alt.h" +#endif /* !MBEDTLS_CHACHAPOLY_ALT */ /** * \brief Initialize ChaCha20-Poly1305 context * * \param ctx ChaCha20-Poly1305 context to be initialized */ -void mbedtls_aead_chacha20_poly1305_init( mbedtls_aead_chacha20_poly1305_context *ctx ); +void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ); /** * \brief Clear ChaCha20-Poly1305 context * * \param ctx ChaCha20-Poly1305 context to be cleared */ -void mbedtls_aead_chacha20_poly1305_free( mbedtls_aead_chacha20_poly1305_context *ctx ); +void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); /** * \brief Set the ChaCha20-Poly1305 symmetric encryption key. @@ -83,12 +83,12 @@ void mbedtls_aead_chacha20_poly1305_free( mbedtls_aead_chacha20_poly1305_context * \param ctx The ChaCha20-Poly1305 context. * \param key The 256-bit (32 bytes) key. * - * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if \p ctx or \p key are NULL. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_aead_chacha20_poly1305_setkey( mbedtls_aead_chacha20_poly1305_context *ctx, - const unsigned char key[32] ); +int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, + const unsigned char key[32] ); /** * \brief Setup ChaCha20-Poly1305 context for encryption or decryption. @@ -102,13 +102,13 @@ int mbedtls_aead_chacha20_poly1305_setkey( mbedtls_aead_chacha20_poly1305_contex * \param mode Specifies whether the context is used to encrypt or * decrypt data. * - * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if \p ctx or \p mac are NULL. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_context *ctx, - const unsigned char nonce[12], - mbedtls_aead_chacha20_poly1305_mode_t mode ); +int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, + const unsigned char nonce[12], + mbedtls_chachapoly_mode_t mode ); /** * \brief Process additional authenticated data (AAD). @@ -118,14 +118,14 @@ int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_contex * * \note This function is called before data is encrypted/decrypted. * I.e. call this function to process the AAD before calling - * mbedtls_aead_chacha20_poly1305_update. + * 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 mbedtls_aead_chacha20_poly1305_update, + * been processed by mbedtls_chachapoly_update, * or if the context has been finished. * * \param ctx The ChaCha20-Poly1305 context. @@ -134,23 +134,23 @@ int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_contex * \param aad Buffer containing the AAD. * This pointer can be NULL if aad_len == 0. * - * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if \p ctx or \p aad are NULL. - * MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE is returned if + * MBEDTLS_ERR_CHACHAPOLY_BAD_STATE is returned if * the context has not been setup, the context has been * finished, or if the AAD has been finished. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_context *ctx, - size_t aad_len, - const unsigned char *aad ); +int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, + size_t aad_len, + const unsigned char *aad ); /** * \brief Encrypt/decrypt data. * * The direction (encryption or decryption) depends on the * mode that was given when calling - * mbedtls_aead_chacha20_poly1305_starts. + * mbedtls_chachapoly_starts. * * You may call this function multiple times to process * an arbitrary amount of data. It is permitted to call @@ -164,17 +164,17 @@ int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_co * \param output Buffer to where the encrypted or decrypted data is written. * This pointer can be NULL if len == 0. * - * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if \p ctx, \p input, or \p output are NULL. - * MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE is returned if + * MBEDTLS_ERR_CHACHAPOLY_BAD_STATE is returned if * the context has not been setup, or if the context has been * finished. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output ); +int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, + size_t len, + const unsigned char *input, + unsigned char *output ); /** * \brief Compute the ChaCha20-Poly1305 MAC. @@ -182,14 +182,14 @@ int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_contex * \param ctx The ChaCha20-Poly1305 context. * \param mac Buffer to where the 128-bit (16 bytes) MAC is written. * - * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if \p ctx or \p mac are NULL. - * MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE is returned if + * MBEDTLS_ERR_CHACHAPOLY_BAD_STATE is returned if * the context has not been setup. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_context *ctx, - unsigned char mac[16] ); +int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, + unsigned char mac[16] ); /** * \brief Encrypt or decrypt data, and produce a MAC with ChaCha20-Poly1305. @@ -210,29 +210,29 @@ int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_contex * This pointer can be NULL if ilen == 0. * \param mac Buffer to where the computed 128-bit (16 bytes) MAC is written. * - * \return MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA is returned + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if one or more of the required parameters are NULL. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_aead_chacha20_poly1305_crypt_and_mac( const unsigned char key[32], - const unsigned char nonce[12], - mbedtls_aead_chacha20_poly1305_mode_t mode, - size_t aad_len, - const unsigned char *aad, - size_t ilen, - const unsigned char *input, - unsigned char *output, - unsigned char mac[16] ); +int mbedtls_chachapoly_crypt_and_mac( const unsigned char key[32], + const unsigned char nonce[12], + mbedtls_chachapoly_mode_t mode, + size_t aad_len, + const unsigned char *aad, + size_t ilen, + const unsigned char *input, + unsigned char *output, + unsigned char mac[16] ); /** * \brief Checkup routine * * \return 0 if successful, or 1 if the test failed */ -int mbedtls_aead_chacha20_poly1305_self_test( int verbose ); +int mbedtls_chachapoly_self_test( int verbose ); #ifdef __cplusplus } #endif -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_H */ +#endif /* MBEDTLS_CHACHAPOLY_H */ diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index f954ccec3..ac1f564fb 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -37,7 +37,7 @@ #include -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) #define MBEDTLS_CIPHER_MODE_AEAD #endif @@ -563,7 +563,7 @@ int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, */ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) /** * \brief This function adds additional data for AEAD ciphers. * Currently supported with GCM and ChaCha20+Poly1305. @@ -578,7 +578,7 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ); */ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ /** * \brief The generic cipher update function. It encrypts or @@ -636,7 +636,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, unsigned char *output, size_t *olen ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) /** * \brief This function writes a tag for AEAD ciphers. * Currently supported with GCM and ChaCha20+Poly1305. @@ -666,7 +666,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, */ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, const unsigned char *tag, size_t tag_len ); -#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ /** * \brief The generic all-in-one encryption/decryption function, diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 22d465cda..69d2b63b5 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -269,7 +269,7 @@ * digests and ciphers instead. * */ -//#define MBEDTLS_AEAD_CHACHA20_POLY1305_ALT +//#define MBEDTLS_CHACHAPOLY_ALT //#define MBEDTLS_AES_ALT //#define MBEDTLS_ARC4_ALT //#define MBEDTLS_BLOWFISH_ALT @@ -1690,15 +1690,15 @@ #define MBEDTLS_AES_C /** - * \def MBEDTLS_AEAD_CHACHA20_POLY1305_C + * \def MBEDTLS_CHACHAPOLY_C * * Enable the ChaCha20-Poly1305 AEAD algorithm. * - * Module: library/aead_chacha20_poly1305.c + * Module: library/chachapoly.c * * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C */ -#define MBEDTLS_AEAD_CHACHA20_POLY1305_C +#define MBEDTLS_CHACHAPOLY_C /** * \def MBEDTLS_ARC4_C @@ -1855,7 +1855,7 @@ * Enable the ChaCha20 block cipher. * * Module: library/chacha20.c - * Caller: library/aead_chacha20_poly1305.c + * Caller: library/chachapoly.c */ #define MBEDTLS_CHACHA20_C @@ -2427,7 +2427,7 @@ * Enable the Poly1305 MAC algorithm. * * Module: library/poly1305.c - * Caller: library/aead_chacha20_poly1305.c + * Caller: library/chachapoly.c */ #define MBEDTLS_POLY1305_C diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 72b7f18ff..e056975a2 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -78,7 +78,7 @@ * SHA512 1 0x0039-0x0039 * CHACHA20 1 0x003B-0x003B * POLY1305 1 0x0041-0x0041 - * AEAD_CHACHA20_POLY1305 2 0x0047-0x0049 + * CHACHAPOLY 2 0x0047-0x0049 * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index b8f663d9c..582769baf 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -3,7 +3,6 @@ option(USE_SHARED_MBEDTLS_LIBRARY "Build mbed TLS shared library." OFF) option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF) set(src_crypto - aead_chacha20_poly1305.c aes.c aesni.c arc4.c @@ -15,6 +14,7 @@ set(src_crypto camellia.c ccm.c chacha20.c + chachapoly.c cipher.c cipher_wrap.c cmac.c diff --git a/library/Makefile b/library/Makefile index de4bd5c42..a4c6e35b5 100644 --- a/library/Makefile +++ b/library/Makefile @@ -47,11 +47,10 @@ ifdef WINDOWS_BUILD DLEXT=dll endif -OBJS_CRYPTO= aead_chacha20_poly1305.o \ - aes.o aesni.o arc4.o \ +OBJS_CRYPTO= aes.o aesni.o arc4.o \ asn1parse.o asn1write.o base64.o \ bignum.o blowfish.o camellia.o \ - ccm.o chacha20.o \ + ccm.o chacha20.o chachapoly.o \ cipher.o cipher_wrap.o \ cmac.o ctr_drbg.o des.o \ dhm.o ecdh.o ecdsa.o \ diff --git a/library/aead_chacha20_poly1305.c b/library/chachapoly.c similarity index 64% rename from library/aead_chacha20_poly1305.c rename to library/chachapoly.c index 04180081a..3ba19542e 100644 --- a/library/aead_chacha20_poly1305.c +++ b/library/chachapoly.c @@ -1,5 +1,5 @@ /** - * \file aead_chacha20_poly1305.c + * \file chachapoly.c * * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. * @@ -26,9 +26,9 @@ #include MBEDTLS_CONFIG_FILE #endif -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/aead_chacha20_poly1305.h" +#include "mbedtls/chachapoly.h" #include #if defined(MBEDTLS_SELF_TEST) @@ -40,12 +40,12 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ -#if !defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) +#if !defined(MBEDTLS_CHACHAPOLY_ALT) -#define AEAD_CHACHA20_POLY1305_STATE_INIT ( 0 ) -#define AEAD_CHACHA20_POLY1305_STATE_AAD ( 1 ) -#define AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ -#define AEAD_CHACHA20_POLY1305_STATE_FINISHED ( 3 ) +#define CHACHAPOLY_STATE_INIT ( 0 ) +#define CHACHAPOLY_STATE_AAD ( 1 ) +#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ +#define CHACHAPOLY_STATE_FINISHED ( 3 ) /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { @@ -57,7 +57,7 @@ static void mbedtls_zeroize( void *v, size_t n ) { * * \param ctx The ChaCha20-Poly1305 context. */ -static void mbedtls_aead_chacha20_poly1305_pad_aad( mbedtls_aead_chacha20_poly1305_context *ctx ) +static void mbedtls_chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) { uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); unsigned char zeroes[15]; @@ -76,7 +76,7 @@ static void mbedtls_aead_chacha20_poly1305_pad_aad( mbedtls_aead_chacha20_poly13 * * \param ctx The ChaCha20-Poly1305 context. */ -static void mbedtls_aead_chacha20_poly1305_pad_ciphertext( mbedtls_aead_chacha20_poly1305_context *ctx ) +static void mbedtls_chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) { uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); unsigned char zeroes[15]; @@ -90,7 +90,7 @@ static void mbedtls_aead_chacha20_poly1305_pad_ciphertext( mbedtls_aead_chacha20 } } -void mbedtls_aead_chacha20_poly1305_init( mbedtls_aead_chacha20_poly1305_context *ctx ) +void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) { if ( ctx != NULL ) { @@ -98,12 +98,12 @@ void mbedtls_aead_chacha20_poly1305_init( mbedtls_aead_chacha20_poly1305_context mbedtls_poly1305_init( &ctx->poly1305_ctx ); ctx->aad_len = 0U; ctx->ciphertext_len = 0U; - ctx->state = AEAD_CHACHA20_POLY1305_STATE_INIT; - ctx->mode = MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT; + ctx->state = CHACHAPOLY_STATE_INIT; + ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; } } -void mbedtls_aead_chacha20_poly1305_free( mbedtls_aead_chacha20_poly1305_context *ctx ) +void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ) { if ( ctx != NULL ) { @@ -111,19 +111,19 @@ void mbedtls_aead_chacha20_poly1305_free( mbedtls_aead_chacha20_poly1305_context mbedtls_poly1305_free( &ctx->poly1305_ctx ); ctx->aad_len = 0U; ctx->ciphertext_len = 0U; - ctx->state = AEAD_CHACHA20_POLY1305_STATE_INIT; - ctx->mode = MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT; + ctx->state = CHACHAPOLY_STATE_INIT; + ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; } } -int mbedtls_aead_chacha20_poly1305_setkey( mbedtls_aead_chacha20_poly1305_context *ctx, - const unsigned char key[32] ) +int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, + const unsigned char key[32] ) { int result; if ( ( ctx == NULL ) || ( key == NULL ) ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } result = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); @@ -131,16 +131,16 @@ int mbedtls_aead_chacha20_poly1305_setkey( mbedtls_aead_chacha20_poly1305_contex return( result ); } -int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_context *ctx, - const unsigned char nonce[12], - mbedtls_aead_chacha20_poly1305_mode_t mode ) +int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, + const unsigned char nonce[12], + mbedtls_chachapoly_mode_t mode ) { int result; unsigned char poly1305_key[64]; if ( ( ctx == NULL ) || ( nonce == NULL ) ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } result = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 1U ); @@ -161,7 +161,7 @@ int mbedtls_aead_chacha20_poly1305_starts( mbedtls_aead_chacha20_poly1305_contex { ctx->aad_len = 0U; ctx->ciphertext_len = 0U; - ctx->state = AEAD_CHACHA20_POLY1305_STATE_AAD; + ctx->state = CHACHAPOLY_STATE_AAD; ctx->mode = mode; } @@ -170,22 +170,22 @@ cleanup: return( result ); } -int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_context *ctx, - size_t aad_len, - const unsigned char *aad ) +int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, + size_t aad_len, + const unsigned char *aad ) { if ( ctx == NULL ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } else if ( ( aad_len > 0U ) && ( aad == NULL ) ) { /* aad pointer is allowed to be NULL if aad_len == 0 */ - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } - else if ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) + else if ( ctx->state != CHACHAPOLY_STATE_AAD ) { - return(MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + return(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } ctx->aad_len += aad_len; @@ -193,36 +193,36 @@ int mbedtls_aead_chacha20_poly1305_update_aad( mbedtls_aead_chacha20_poly1305_co return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad_len, aad ) ); } -int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_context *ctx, - size_t len, - const unsigned char *input, - unsigned char *output ) +int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, + size_t len, + const unsigned char *input, + unsigned char *output ) { if ( ( ctx == NULL ) || ( input == NULL ) || ( output == NULL ) ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } else if ( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) ) { /* input and output pointers are allowed to be NULL if len == 0 */ - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } - else if ( ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_AAD ) && - ( ctx->state != AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ) ) + else if ( ( ctx->state != CHACHAPOLY_STATE_AAD ) && + ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } - if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_AAD ) + if ( ctx->state == CHACHAPOLY_STATE_AAD ) { - ctx->state = AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT; + ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; - mbedtls_aead_chacha20_poly1305_pad_aad( ctx ); + mbedtls_chachapoly_pad_aad( ctx ); } ctx->ciphertext_len += len; - if ( ctx->mode == MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT ) + if ( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT ) { /* Note: the following functions return an error only if one or more of * the input pointers are NULL. Since we have checked their validity @@ -240,30 +240,30 @@ int mbedtls_aead_chacha20_poly1305_update( mbedtls_aead_chacha20_poly1305_contex return( 0 ); } -int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_context *ctx, - unsigned char mac[16] ) +int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, + unsigned char mac[16] ) { unsigned char len_block[16]; if ( ( ctx == NULL ) || ( mac == NULL ) ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } - else if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_INIT ) + else if ( ctx->state == CHACHAPOLY_STATE_INIT ) { - return( MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } - if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_AAD ) + if ( ctx->state == CHACHAPOLY_STATE_AAD ) { - mbedtls_aead_chacha20_poly1305_pad_aad( ctx ); + mbedtls_chachapoly_pad_aad( ctx ); } - else if ( ctx->state == AEAD_CHACHA20_POLY1305_STATE_CIPHERTEXT ) + else if ( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) { - mbedtls_aead_chacha20_poly1305_pad_ciphertext( ctx ); + mbedtls_chachapoly_pad_ciphertext( ctx ); } - ctx->state = AEAD_CHACHA20_POLY1305_STATE_FINISHED; + ctx->state = CHACHAPOLY_STATE_FINISHED; /* The lengths of the AAD and ciphertext are processed by * Poly1305 as the final 128-bit block, encoded as little-endian integers. @@ -291,45 +291,45 @@ int mbedtls_aead_chacha20_poly1305_finish( mbedtls_aead_chacha20_poly1305_contex return( 0 ); } -int mbedtls_aead_chacha20_poly1305_crypt_and_mac ( const unsigned char key[32], - const unsigned char nonce[12], - mbedtls_aead_chacha20_poly1305_mode_t mode, - size_t aad_len, - const unsigned char *aad, - size_t ilen, - const unsigned char *input, - unsigned char *output, - unsigned char mac[16] ) +int mbedtls_chachapoly_crypt_and_mac ( const unsigned char key[32], + const unsigned char nonce[12], + mbedtls_chachapoly_mode_t mode, + size_t aad_len, + const unsigned char *aad, + size_t ilen, + const unsigned char *input, + unsigned char *output, + unsigned char mac[16] ) { - mbedtls_aead_chacha20_poly1305_context ctx; + mbedtls_chachapoly_context ctx; int result; - mbedtls_aead_chacha20_poly1305_init( &ctx ); + mbedtls_chachapoly_init( &ctx ); - result = mbedtls_aead_chacha20_poly1305_setkey( &ctx, key ); + result = mbedtls_chachapoly_setkey( &ctx, key ); if ( result != 0 ) goto cleanup; - result = mbedtls_aead_chacha20_poly1305_starts( &ctx, nonce, mode ); + result = mbedtls_chachapoly_starts( &ctx, nonce, mode ); if ( result != 0 ) goto cleanup; - result = mbedtls_aead_chacha20_poly1305_update_aad( &ctx, aad_len, aad ); + result = mbedtls_chachapoly_update_aad( &ctx, aad_len, aad ); if ( result != 0 ) goto cleanup; - result = mbedtls_aead_chacha20_poly1305_update( &ctx, ilen, input, output ); + result = mbedtls_chachapoly_update( &ctx, ilen, input, output ); if ( result != 0 ) goto cleanup; - result = mbedtls_aead_chacha20_poly1305_finish( &ctx, mac ); + result = mbedtls_chachapoly_finish( &ctx, mac ); cleanup: - mbedtls_aead_chacha20_poly1305_free( &ctx ); + mbedtls_chachapoly_free( &ctx ); return( result ); } -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ +#endif /* MBEDTLS_CHACHAPOLY_ALT */ #if defined(MBEDTLS_SELF_TEST) @@ -419,7 +419,7 @@ static const unsigned char test_mac[1][16] = } }; -int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) +int mbedtls_chachapoly_self_test( int verbose ) { unsigned i; int result; @@ -433,15 +433,15 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); } - result = mbedtls_aead_chacha20_poly1305_crypt_and_mac( test_key[i], - test_nonce[i], - MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, - test_aad_len[i], - test_aad[i], - test_input_len[i], - test_input[i], - output, - mac ); + result = mbedtls_chachapoly_crypt_and_mac( test_key[i], + test_nonce[i], + MBEDTLS_CHACHAPOLY_ENCRYPT, + test_aad_len[i], + test_aad[i], + test_input_len[i], + test_input[i], + output, + mac ); if ( result != 0 ) { if ( verbose != 0 ) @@ -485,4 +485,4 @@ int mbedtls_aead_chacha20_poly1305_self_test( int verbose ) #endif /* MBEDTLS_SELF_TEST */ -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_CHACHAPOLY_C */ diff --git a/library/cipher.c b/library/cipher.c index 71fa6f535..acc986fa8 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -38,8 +38,8 @@ #include #include -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) -#include "mbedtls/aead_chacha20_poly1305.h" +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" #endif #if defined(MBEDTLS_GCM_C) @@ -70,7 +70,7 @@ #endif -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) /* Compare the contents of two buffers in constant time. * Returns 0 if the contents are bitwise identical, otherwise returns * a non-zero value. @@ -88,7 +88,7 @@ static int mbedtls_constant_time_memcmp( const void *v1, const void *v2, size_t return (int)diff; } -#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ static int supported_init = 0; @@ -288,7 +288,7 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) return( 0 ); } -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, const unsigned char *ad, size_t ad_len ) { @@ -303,30 +303,30 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, } #endif -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { int result; - mbedtls_aead_chacha20_poly1305_mode_t mode; + mbedtls_chachapoly_mode_t mode; mode = ( ctx->operation == MBEDTLS_ENCRYPT ) - ? MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT - : MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT; + ? MBEDTLS_CHACHAPOLY_ENCRYPT + : MBEDTLS_CHACHAPOLY_DECRYPT; - result = mbedtls_aead_chacha20_poly1305_starts( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ctx->iv, mode ); if ( result != 0 ) return( result ); - return mbedtls_aead_chacha20_poly1305_update_aad( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ad_len, ad ); } #endif return( 0 ); } -#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen ) @@ -394,11 +394,11 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) { *olen = ilen; - return mbedtls_aead_chacha20_poly1305_update( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ilen, input, output ); } #endif @@ -852,7 +852,7 @@ int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_ciph } #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { @@ -867,14 +867,14 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); #endif -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { /* Don't allow truncated MAC for Poly1305 */ if ( tag_len != 16U ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - return mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + return mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ); } #endif @@ -914,14 +914,14 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, } #endif /* MBEDTLS_GCM_C */ -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { /* Don't allow truncated MAC for Poly1305 */ if ( tag_len != sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - ret = mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag ); if ( ret != 0 ) { @@ -934,11 +934,11 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, return( 0 ); } -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_CHACHAPOLY_C */ return( 0 ); } -#endif /* MBEDTLS_GCM_C || MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ /* * Packet-oriented wrapper for non-AEAD modes @@ -997,7 +997,7 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, tag, tag_len ) ); } #endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { int ret; @@ -1010,26 +1010,26 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, *olen = ilen; - ret = mbedtls_aead_chacha20_poly1305_starts( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, - iv, MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT ); + ret = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + iv, MBEDTLS_CHACHAPOLY_ENCRYPT ); if ( ret != 0 ) return( ret ); - ret = mbedtls_aead_chacha20_poly1305_update_aad( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ad_len, ad ); if ( ret != 0 ) return( ret ); - ret = mbedtls_aead_chacha20_poly1305_update( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ilen, input, output ); if ( ret != 0 ) return( ret ); - ret = mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, tag ); return( ret ); } -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } @@ -1076,7 +1076,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, return( ret ); } #endif /* MBEDTLS_CCM_C */ -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { unsigned char check_tag[16]; @@ -1090,22 +1090,22 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, *olen = ilen; - ret = mbedtls_aead_chacha20_poly1305_starts( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, - iv, MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT ); + ret = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + iv, MBEDTLS_CHACHAPOLY_DECRYPT ); if ( ret != 0 ) return( ret ); - ret = mbedtls_aead_chacha20_poly1305_update_aad( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ad_len, ad ); if ( ret != 0 ) return( ret ); - ret = mbedtls_aead_chacha20_poly1305_update( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, ilen, input, output ); if ( ret != 0 ) return( ret ); - ret = mbedtls_aead_chacha20_poly1305_finish( (mbedtls_aead_chacha20_poly1305_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, check_tag ); if ( ret != 0 ) return( ret ); @@ -1116,7 +1116,7 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, return( 0 ); } -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index d8c5f0611..5c8082850 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -33,8 +33,8 @@ #include "mbedtls/cipher_internal.h" -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) -#include "mbedtls/aead_chacha20_poly1305.h" +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" #endif #if defined(MBEDTLS_AES_C) @@ -1356,40 +1356,41 @@ static const mbedtls_cipher_info_t chacha20_info = { }; #endif /* MBEDTLS_CHACHA20_C */ -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_CHACHAPOLY_C) -static int aead_chacha20_poly1305_setkey_wrap( void *ctx, const unsigned char *key, - unsigned int key_bitlen ) +static int chachapoly_setkey_wrap( void *ctx, + const unsigned char *key, + unsigned int key_bitlen ) { if( key_bitlen != 256U ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - if ( 0 != mbedtls_aead_chacha20_poly1305_setkey( (mbedtls_aead_chacha20_poly1305_context*)ctx, key ) ) + if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( 0 ); } -static void * aead_chacha20_poly1305_ctx_alloc( void ) +static void * chachapoly_ctx_alloc( void ) { - mbedtls_aead_chacha20_poly1305_context *ctx; - ctx = mbedtls_calloc( 1, sizeof( mbedtls_aead_chacha20_poly1305_context ) ); + mbedtls_chachapoly_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); if( ctx == NULL ) return( NULL ); - mbedtls_aead_chacha20_poly1305_init( ctx ); + mbedtls_chachapoly_init( ctx ); return( ctx ); } -static void aead_chacha20_poly1305_ctx_free( void *ctx ) +static void chachapoly_ctx_free( void *ctx ) { - mbedtls_aead_chacha20_poly1305_free( (mbedtls_aead_chacha20_poly1305_context *) ctx ); + mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); mbedtls_free( ctx ); } -static const mbedtls_cipher_base_t aead_chacha20_poly1305_base_info = { +static const mbedtls_cipher_base_t chachapoly_base_info = { MBEDTLS_CIPHER_ID_CHACHA20, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1404,12 +1405,12 @@ static const mbedtls_cipher_base_t aead_chacha20_poly1305_base_info = { #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif - aead_chacha20_poly1305_setkey_wrap, - aead_chacha20_poly1305_setkey_wrap, - aead_chacha20_poly1305_ctx_alloc, - aead_chacha20_poly1305_ctx_free + chachapoly_setkey_wrap, + chachapoly_setkey_wrap, + chachapoly_ctx_alloc, + chachapoly_ctx_free }; -static const mbedtls_cipher_info_t aead_chacha20_poly1305_info = { +static const mbedtls_cipher_info_t chachapoly_info = { MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MODE_NONE, 256, @@ -1417,9 +1418,9 @@ static const mbedtls_cipher_info_t aead_chacha20_poly1305_info = { 12, 0, 64, - &aead_chacha20_poly1305_base_info + &chachapoly_base_info }; -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#endif /* MBEDTLS_CHACHAPOLY_C */ #if defined(MBEDTLS_CIPHER_NULL_CIPHER) static int null_crypt_stream( void *ctx, size_t length, @@ -1580,8 +1581,8 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = { MBEDTLS_CIPHER_CHACHA20, &chacha20_info }, #endif -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) - { MBEDTLS_CIPHER_CHACHA20_POLY1305, &aead_chacha20_poly1305_info }, +#if defined(MBEDTLS_CHACHAPOLY_C) + { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, #endif #if defined(MBEDTLS_CIPHER_NULL_CIPHER) diff --git a/library/error.c b/library/error.c index d0a75ca5a..aeef9303a 100644 --- a/library/error.c +++ b/library/error.c @@ -41,10 +41,6 @@ #include -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) -#include "mbedtls/aead_chacha20_poly1305.h" -#endif - #if defined(MBEDTLS_AES_C) #include "mbedtls/aes.h" #endif @@ -77,6 +73,10 @@ #include "mbedtls/chacha20.h" #endif +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + #if defined(MBEDTLS_CIPHER_C) #include "mbedtls/cipher.h" #endif @@ -579,13 +579,6 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) // Low level error codes // // BEGIN generated code -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) - if( use_ret == -(MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_INPUT_DATA) ) - mbedtls_snprintf( buf, buflen, "AEAD_CHACHA20_POLY1305 - Invalid input parameter(s)" ); - if( use_ret == -(MBEDTLS_ERR_AEAD_CHACHA20_POLY1305_BAD_STATE) ) - mbedtls_snprintf( buf, buflen, "AEAD_CHACHA20_POLY1305 - The requested operation is not permitted in the current state" ); -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ - #if defined(MBEDTLS_AES_C) if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) ) mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); @@ -677,6 +670,13 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" ); #endif /* MBEDTLS_CHACHA20_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Invalid input parameter(s)" ); + if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) ) + mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" ); +#endif /* MBEDTLS_CHACHAPOLY_C */ + #if defined(MBEDTLS_CMAC_C) if( use_ret == -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) ) mbedtls_snprintf( buf, buflen, "CMAC - CMAC hardware accelerator failed" ); diff --git a/library/version_features.c b/library/version_features.c index b73410c6a..cce1a384e 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -84,9 +84,9 @@ static const char *features[] = { #if defined(MBEDTLS_TIMING_ALT) "MBEDTLS_TIMING_ALT", #endif /* MBEDTLS_TIMING_ALT */ -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_ALT) - "MBEDTLS_AEAD_CHACHA20_POLY1305_ALT", -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_ALT */ +#if defined(MBEDTLS_CHACHAPOLY_ALT) + "MBEDTLS_CHACHAPOLY_ALT", +#endif /* MBEDTLS_CHACHAPOLY_ALT */ #if defined(MBEDTLS_AES_ALT) "MBEDTLS_AES_ALT", #endif /* MBEDTLS_AES_ALT */ @@ -519,9 +519,9 @@ static const char *features[] = { #if defined(MBEDTLS_AES_C) "MBEDTLS_AES_C", #endif /* MBEDTLS_AES_C */ -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) - "MBEDTLS_AEAD_CHACHA20_POLY1305_C", -#endif /* MBEDTLS_AEAD_CHACHA20_POLY1305_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + "MBEDTLS_CHACHAPOLY_C", +#endif /* MBEDTLS_CHACHAPOLY_C */ #if defined(MBEDTLS_ARC4_C) "MBEDTLS_ARC4_C", #endif /* MBEDTLS_ARC4_C */ diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 57f9924ce..13fa98cdb 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -46,7 +46,7 @@ #include "mbedtls/camellia.h" #include "mbedtls/chacha20.h" #include "mbedtls/poly1305.h" -#include "mbedtls/aead_chacha20_poly1305.h" +#include "mbedtls/chachapoly.h" #include "mbedtls/base64.h" #include "mbedtls/bignum.h" #include "mbedtls/rsa.h" @@ -216,8 +216,8 @@ const selftest_t selftests[] = #if defined(MBEDTLS_POLY1305_C) {"poly1305", mbedtls_poly1305_self_test}, #endif -#if defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) - {"chacha20-poly1305", mbedtls_aead_chacha20_poly1305_self_test}, +#if defined(MBEDTLS_CHACHAPOLY_C) + {"chacha20-poly1305", mbedtls_chachapoly_self_test}, #endif #if defined(MBEDTLS_BASE64_C) {"base64", mbedtls_base64_self_test}, diff --git a/scripts/generate_errors.pl b/scripts/generate_errors.pl index b5d141322..811648a07 100755 --- a/scripts/generate_errors.pl +++ b/scripts/generate_errors.pl @@ -29,8 +29,8 @@ if( @ARGV ) { my $error_format_file = $data_dir.'/error.fmt'; -my @low_level_modules = qw( AEAD_CHACHA20_POLY1305 AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH - CAMELLIA CCM CHACHA20 CMAC CTR_DRBG DES +my @low_level_modules = qw( AES ARC4 ASN1 BASE64 BIGNUM BLOWFISH + CAMELLIA CCM CHACHA20 CHACHAPOLY CMAC CTR_DRBG DES ENTROPY GCM HMAC_DRBG MD2 MD4 MD5 NET OID PADLOCK PBKDF2 POLY1305 RIPEMD160 SHA1 SHA256 SHA512 THREADING XTEA ); @@ -88,7 +88,6 @@ foreach my $line (@matches) $module_name = "BIGNUM" if ($module_name eq "MPI"); $module_name = "CTR_DRBG" if ($module_name eq "CTR"); $module_name = "HMAC_DRBG" if ($module_name eq "HMAC"); - $module_name = "AEAD_CHACHA20_POLY1305" if ($module_name eq "AEAD"); my $define_name = $module_name; $define_name = "X509_USE,X509_CREATE" if ($define_name eq "X509"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c7d9fad3c..96305386c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -44,7 +44,6 @@ if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX-") endif(MSVC) -add_test_suite(aead_chacha20_poly1305) add_test_suite(aes aes.ecb) add_test_suite(aes aes.cbc) add_test_suite(aes aes.cfb) @@ -56,13 +55,14 @@ add_test_suite(blowfish) add_test_suite(camellia) add_test_suite(ccm) add_test_suite(chacha20) -add_test_suite(cipher cipher.aead_chacha20_poly1305) +add_test_suite(chachapoly) add_test_suite(cipher cipher.aes) add_test_suite(cipher cipher.arc4) add_test_suite(cipher cipher.blowfish) add_test_suite(cipher cipher.camellia) add_test_suite(cipher cipher.ccm) add_test_suite(cipher cipher.chacha20) +add_test_suite(cipher cipher.chachapoly) add_test_suite(cipher cipher.des) add_test_suite(cipher cipher.gcm) add_test_suite(cipher cipher.null) diff --git a/tests/Makefile b/tests/Makefile index e6ff26cf3..f9d976864 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -45,14 +45,14 @@ ifdef ZLIB LOCAL_LDFLAGS += -lz endif -APPS = test_suite_aead_chacha20_poly1305$(EXEXT) \ - test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ +APPS = test_suite_aes.ecb$(EXEXT) test_suite_aes.cbc$(EXEXT) \ test_suite_aes.cfb$(EXEXT) test_suite_aes.rest$(EXEXT) \ test_suite_arc4$(EXEXT) test_suite_asn1write$(EXEXT) \ test_suite_base64$(EXEXT) test_suite_blowfish$(EXEXT) \ test_suite_camellia$(EXEXT) test_suite_ccm$(EXEXT) \ - test_suite_chacha20$(EXEXT) test_suite_cmac$(EXEXT) \ - test_suite_cipher.aead_chacha20_poly1305$(EXEXT) \ + test_suite_chacha20$(EXEXT) test_suite_chachapoly$(EXEXT) \ + test_suite_cmac$(EXEXT) \ + test_suite_cipher.chachapoly$(EXEXT) \ test_suite_cipher.aes$(EXEXT) \ test_suite_cipher.arc4$(EXEXT) test_suite_cipher.ccm$(EXEXT) \ test_suite_cipher.chacha20$(EXEXT) \ @@ -117,10 +117,6 @@ test_suite_aes.rest.c : suites/test_suite_aes.function suites/test_suite_aes.res echo " Gen $@" perl scripts/generate_code.pl suites test_suite_aes test_suite_aes.rest -test_suite_cipher.aead_chacha20_poly1305.c : suites/test_suite_cipher.function suites/test_suite_cipher.aead_chacha20_poly1305.data scripts/generate_code.pl suites/helpers.function suites/main_test.function - echo " Gen $@" - perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.aead_chacha20_poly1305 - test_suite_cipher.aes.c : suites/test_suite_cipher.function suites/test_suite_cipher.aes.data scripts/generate_code.pl suites/helpers.function suites/main_test.function echo " Gen $@" perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.aes @@ -137,6 +133,10 @@ test_suite_cipher.chacha20.c : suites/test_suite_cipher.function suites/test_sui echo " Gen $@" perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.chacha20 +test_suite_cipher.chachapoly.c : suites/test_suite_cipher.function suites/test_suite_cipher.chachapoly.data scripts/generate_code.pl suites/helpers.function suites/main_test.function + echo " Gen $@" + perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.chachapoly + test_suite_cipher.gcm.c : suites/test_suite_cipher.function suites/test_suite_cipher.gcm.data scripts/generate_code.pl suites/helpers.function suites/main_test.function echo " Gen $@" perl scripts/generate_code.pl suites test_suite_cipher test_suite_cipher.gcm @@ -210,10 +210,6 @@ test_suite_hmac_drbg.pr.c : suites/test_suite_hmac_drbg.function suites/test_sui perl scripts/generate_code.pl suites $* $* -test_suite_aead_chacha20_poly1305$(EXEXT): test_suite_aead_chacha20_poly1305.c $(DEP) - echo " CC $<" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ - test_suite_aes.ecb$(EXEXT): test_suite_aes.ecb.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ @@ -258,6 +254,10 @@ test_suite_chacha20$(EXEXT): test_suite_chacha20.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_chachapoly$(EXEXT): test_suite_chachapoly.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_cmac$(EXEXT): test_suite_cmac.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ @@ -266,10 +266,6 @@ test_suite_cipher.aes$(EXEXT): test_suite_cipher.aes.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ -test_suite_cipher.aead_chacha20_poly1305$(EXEXT): test_suite_cipher.aead_chacha20_poly1305.c $(DEP) - echo " CC $<" - $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ - test_suite_cipher.arc4$(EXEXT): test_suite_cipher.arc4.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ @@ -282,6 +278,10 @@ test_suite_cipher.chacha20$(EXEXT): test_suite_cipher.chacha20.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ +test_suite_cipher.chachapoly$(EXEXT): test_suite_cipher.chachapoly.c $(DEP) + echo " CC $<" + $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ + test_suite_cipher.gcm$(EXEXT): test_suite_cipher.gcm.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ diff --git a/tests/suites/test_suite_aead_chacha20_poly1305.data b/tests/suites/test_suite_aead_chacha20_poly1305.data deleted file mode 100644 index 1cbfa24da..000000000 --- a/tests/suites/test_suite_aead_chacha20_poly1305.data +++ /dev/null @@ -1,19 +0,0 @@ -ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C -mbedtls_aead_chacha20_poly1305_enc:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" - -ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C -mbedtls_aead_chacha20_poly1305_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600691" - -ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Encrypt) -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C -mbedtls_aead_chacha20_poly1305_enc:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" - -ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt) -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C -mbedtls_aead_chacha20_poly1305_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"eead9d67890cbb22392336fea1851f38" - -ChaCha20-Poly1305 Selftest -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C:MBEDTLS_SELF_TEST -aead_chacha20_poly1305_selftest: diff --git a/tests/suites/test_suite_chachapoly.data b/tests/suites/test_suite_chachapoly.data new file mode 100644 index 000000000..08129aa37 --- /dev/null +++ b/tests/suites/test_suite_chachapoly.data @@ -0,0 +1,19 @@ +ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) +depends_on:MBEDTLS_CHACHAPOLY_C +mbedtls_chachapoly_enc:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" + +ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) +depends_on:MBEDTLS_CHACHAPOLY_C +mbedtls_chachapoly_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600691" + +ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Encrypt) +depends_on:MBEDTLS_CHACHAPOLY_C +mbedtls_chachapoly_enc:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" + +ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt) +depends_on:MBEDTLS_CHACHAPOLY_C +mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"eead9d67890cbb22392336fea1851f38" + +ChaCha20-Poly1305 Selftest +depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SELF_TEST +chachapoly_selftest: diff --git a/tests/suites/test_suite_aead_chacha20_poly1305.function b/tests/suites/test_suite_chachapoly.function similarity index 67% rename from tests/suites/test_suite_aead_chacha20_poly1305.function rename to tests/suites/test_suite_chachapoly.function index 6abd05414..fb1a738f0 100644 --- a/tests/suites/test_suite_aead_chacha20_poly1305.function +++ b/tests/suites/test_suite_chachapoly.function @@ -1,14 +1,14 @@ /* BEGIN_HEADER */ -#include "mbedtls/aead_chacha20_poly1305.h" +#include "mbedtls/chachapoly.h" /* END_HEADER */ /* BEGIN_DEPENDENCIES - * depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C + * depends_on:MBEDTLS_CHACHAPOLY_C * END_DEPENDENCIES */ /* BEGIN_CASE */ -void mbedtls_aead_chacha20_poly1305_enc( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) +void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) { unsigned char key_str[32]; unsigned char nonce_str[12]; @@ -43,11 +43,11 @@ void mbedtls_aead_chacha20_poly1305_enc( char *hex_key_string, char *hex_nonce_s TEST_ASSERT( nonce_len == 12 ); TEST_ASSERT( mac_len == 16 ); - mbedtls_aead_chacha20_poly1305_crypt_and_mac( key_str, nonce_str, - MBEDTLS_AEAD_CHACHA20_POLY1305_ENCRYPT, - aad_len, aad_str, - input_len, input_str, output, - mac ); + mbedtls_chachapoly_crypt_and_mac( key_str, nonce_str, + MBEDTLS_CHACHAPOLY_ENCRYPT, + aad_len, aad_str, + input_len, input_str, output, + mac ); TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); @@ -55,7 +55,7 @@ void mbedtls_aead_chacha20_poly1305_enc( char *hex_key_string, char *hex_nonce_s /* END_CASE */ /* BEGIN_CASE */ -void mbedtls_aead_chacha20_poly1305_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) +void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) { unsigned char key_str[32]; unsigned char nonce_str[12]; @@ -90,11 +90,11 @@ void mbedtls_aead_chacha20_poly1305_dec( char *hex_key_string, char *hex_nonce_s TEST_ASSERT( nonce_len == 12 ); TEST_ASSERT( mac_len == 16 ); - mbedtls_aead_chacha20_poly1305_crypt_and_mac( key_str, nonce_str, - MBEDTLS_AEAD_CHACHA20_POLY1305_DECRYPT, - aad_len, aad_str, - input_len, input_str, output, - mac ); + mbedtls_chachapoly_crypt_and_mac( key_str, nonce_str, + MBEDTLS_CHACHAPOLY_DECRYPT, + aad_len, aad_str, + input_len, input_str, output, + mac ); TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); @@ -102,8 +102,8 @@ void mbedtls_aead_chacha20_poly1305_dec( char *hex_key_string, char *hex_nonce_s /* END_CASE */ /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ -void aead_chacha20_poly1305_selftest() +void chachapoly_selftest() { - TEST_ASSERT( mbedtls_aead_chacha20_poly1305_self_test( 1 ) == 0 ); + TEST_ASSERT( mbedtls_chachapoly_self_test( 1 ) == 0 ); } /* END_CASE */ diff --git a/tests/suites/test_suite_cipher.aead_chacha20_poly1305.data b/tests/suites/test_suite_cipher.chachapoly.data similarity index 74% rename from tests/suites/test_suite_cipher.aead_chacha20_poly1305.data rename to tests/suites/test_suite_cipher.chachapoly.data index 9cd1ed021..de5b3d648 100644 --- a/tests/suites/test_suite_cipher.aead_chacha20_poly1305.data +++ b/tests/suites/test_suite_cipher.chachapoly.data @@ -1,111 +1,111 @@ Decrypt empty buffer -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C: +depends_on:MBEDTLS_CHACHAPOLY_C: dec_empty_buf: ChaCha20+Poly1305 Encrypt and decrypt 0 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:0:-1 ChaCha20+Poly1305 Encrypt and decrypt 1 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:1:-1 ChaCha20+Poly1305 Encrypt and decrypt 2 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:2:-1 ChaCha20+Poly1305 Encrypt and decrypt 7 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:7:-1 ChaCha20+Poly1305 Encrypt and decrypt 8 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:8:-1 ChaCha20+Poly1305 Encrypt and decrypt 9 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:9:-1 ChaCha20+Poly1305 Encrypt and decrypt 15 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:15:-1 ChaCha20+Poly1305 Encrypt and decrypt 16 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:16:-1 ChaCha20+Poly1305 Encrypt and decrypt 17 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:17:-1 ChaCha20+Poly1305 Encrypt and decrypt 31 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:31:-1 ChaCha20+Poly1305 Encrypt and decrypt 32 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:32:-1 ChaCha20+Poly1305 Encrypt and decrypt 33 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:33:-1 ChaCha20+Poly1305 Encrypt and decrypt 47 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:47:-1 ChaCha20+Poly1305 Encrypt and decrypt 48 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:48:-1 ChaCha20+Poly1305 Encrypt and decrypt 49 bytes -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20_POLY1305:"CHACHA20-POLY1305":256:49:-1 ChaCha20+Poly1305 Encrypt and decrypt 0 bytes in multiple parts 1 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:0:0:-1:0:0:0:0 ChaCha20+Poly1305 Encrypt and decrypt 1 bytes in multiple parts 1 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:1:0:-1:1:0:1:0 ChaCha20+Poly1305 Encrypt and decrypt 1 bytes in multiple parts 2 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:0:1:-1:0:1:0:1 ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 1 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:0:-1:16:0:16:0 ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 2 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:0:16:-1:0:16:0:16 ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 3 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:1:15:-1:1:15:1:15 ChaCha20+Poly1305 Encrypt and decrypt 16 bytes in multiple parts 4 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:15:1:-1:15:1:15:1 ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 1 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:15:7:-1:15:7:15:7 ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 2 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:7:15:-1:7:15:7:15 ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 3 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:6:-1:16:6:16:6 ChaCha20+Poly1305 Encrypt and decrypt 22 bytes in multiple parts 4 -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:6:16:-1:6:16:6:16 ChaCha20+Poly1305 Encrypt and decrypt 32 bytes in multiple parts -depends_on:MBEDTLS_AEAD_CHACHA20_POLY1305_C +depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:16:-1:16:16:16:16 diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index e5a252fdb..92462e52b 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -60,7 +60,7 @@ void cipher_null_args( ) TEST_ASSERT( mbedtls_cipher_reset( NULL ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_cipher_reset( &ctx ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( mbedtls_cipher_update_ad( NULL, buf, 0 ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_cipher_update_ad( &ctx, buf, 0 ) @@ -77,7 +77,7 @@ void cipher_null_args( ) TEST_ASSERT( mbedtls_cipher_finish( &ctx, buf, &olen ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( mbedtls_cipher_write_tag( NULL, buf, olen ) == MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_cipher_write_tag( &ctx, buf, olen ) @@ -195,7 +195,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len, TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, ad, sizeof( ad ) - i ) ); TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, ad, sizeof( ad ) - i ) ); #endif @@ -215,7 +215,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len, TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_enc, encbuf + outlen, &outlen ) ); total_len += outlen; -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_write_tag( &ctx_enc, tag, sizeof( tag ) ) ); #endif @@ -236,7 +236,7 @@ void enc_dec_buf( int cipher_id, char *cipher_string, int key_len, TEST_ASSERT( 0 == mbedtls_cipher_finish( &ctx_dec, decbuf + outlen, &outlen ) ); total_len += outlen; -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_check_tag( &ctx_dec, tag, sizeof( tag ) ) ); #endif @@ -292,7 +292,7 @@ void enc_fail( int cipher_id, int pad_mode, int key_len, #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv, 16 ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, NULL, 0 ) ); #endif @@ -340,7 +340,7 @@ void dec_empty_buf() TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) ); #endif @@ -416,7 +416,7 @@ void enc_dec_buf_multipart( int cipher_id, int key_len, int first_length_val, TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_dec ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx_enc ) ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_dec, NULL, 0 ) ); TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx_enc, NULL, 0 ) ); #endif @@ -484,7 +484,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, unsigned char ad[200]; unsigned char tag[20]; size_t key_len, iv_len, cipher_len, clear_len; -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) size_t ad_len, tag_len; #endif mbedtls_cipher_context_t ctx; @@ -505,7 +505,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, iv_len = unhexify( iv, hex_iv ); cipher_len = unhexify( cipher, hex_cipher ); clear_len = unhexify( clear, hex_clear ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) ad_len = unhexify( ad, hex_ad ); tag_len = unhexify( tag, hex_tag ); #else @@ -525,7 +525,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, #endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ TEST_ASSERT( 0 == mbedtls_cipher_set_iv( &ctx, iv, iv_len ) ); TEST_ASSERT( 0 == mbedtls_cipher_reset( &ctx ) ); -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( 0 == mbedtls_cipher_update_ad( &ctx, ad, ad_len ) ); #endif @@ -536,7 +536,7 @@ void decrypt_test_vec( int cipher_id, int pad_mode, TEST_ASSERT( finish_result == mbedtls_cipher_finish( &ctx, output + outlen, &outlen ) ); total_len += outlen; -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_AEAD_CHACHA20_POLY1305_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CHACHAPOLY_C) TEST_ASSERT( tag_result == mbedtls_cipher_check_tag( &ctx, tag, tag_len ) ); #endif diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 802cce719..b78577c29 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -158,6 +158,8 @@ + + @@ -198,6 +200,7 @@ + @@ -231,6 +234,8 @@ + + @@ -268,6 +273,7 @@ + From 02969bf882f9027dd9a596aa7a9e2934611380a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 11:57:05 +0200 Subject: [PATCH 20/42] ChaCha20: allow in-place en/decryption All other ciphers so far allow this. In particular, the TLS layer depends on this, despite what's documented in the Cipher layer, see https://github.com/ARMmbed/mbedtls/issues/1085 https://github.com/ARMmbed/mbedtls/issues/1087 Also, this can be useful for implementing chachapoly without depending on the semi-internal function keystream_block(), see next commit. --- include/mbedtls/chacha20.h | 5 ++--- library/chacha20.c | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index f88bd28b7..7999702f5 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -133,9 +133,8 @@ int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, * * This function is used to both encrypt and decrypt data. * - * \note The \p input and \p output buffers may overlap, but only - * if input >= output (i.e. only if input points ahead of - * the output pointer). + * \note The \p input and \p output pointers must either be equal or + * point to non-overlapping buffers. * * \note mbedtls_chacha20_setkey and mbedtls_chacha20_starts must be * called at least once to setup the context before this function diff --git a/library/chacha20.c b/library/chacha20.c index 28133a675..1abb96ef9 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -314,23 +314,22 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, /* Process full blocks */ while ( size >= CHACHA20_BLOCK_SIZE_BYTES ) { - mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, &output[offset] ); + /* Generate new keystream block and increment counter */ + mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); + ctx->initial_state[CHACHA20_CTR_INDEX]++; for ( i = 0U; i < 64U; i += 8U ) { - output[offset + i ] ^= input[offset + i ]; - output[offset + i + 1U] ^= input[offset + i + 1U]; - output[offset + i + 2U] ^= input[offset + i + 2U]; - output[offset + i + 3U] ^= input[offset + i + 3U]; - output[offset + i + 4U] ^= input[offset + i + 4U]; - output[offset + i + 5U] ^= input[offset + i + 5U]; - output[offset + i + 6U] ^= input[offset + i + 6U]; - output[offset + i + 7U] ^= input[offset + i + 7U]; + output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ]; + output[offset + i + 1U ] = input[offset + i + 1U ] ^ ctx->keystream8[i + 1U ]; + output[offset + i + 2U ] = input[offset + i + 2U ] ^ ctx->keystream8[i + 2U ]; + output[offset + i + 3U ] = input[offset + i + 3U ] ^ ctx->keystream8[i + 3U ]; + output[offset + i + 4U ] = input[offset + i + 4U ] ^ ctx->keystream8[i + 4U ]; + output[offset + i + 5U ] = input[offset + i + 5U ] ^ ctx->keystream8[i + 5U ]; + output[offset + i + 6U ] = input[offset + i + 6U ] ^ ctx->keystream8[i + 6U ]; + output[offset + i + 7U ] = input[offset + i + 7U ] ^ ctx->keystream8[i + 7U ]; } - /* Increment counter */ - ctx->initial_state[CHACHA20_CTR_INDEX]++; - offset += CHACHA20_BLOCK_SIZE_BYTES; size -= CHACHA20_BLOCK_SIZE_BYTES; } @@ -338,7 +337,9 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, /* Last (partial) block */ if ( size > 0U ) { + /* Generate new keystream block and increment counter */ mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); + ctx->initial_state[CHACHA20_CTR_INDEX]++; for ( i = 0U; i < size; i++) { @@ -347,8 +348,6 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, ctx->keystream_bytes_used = size; - /* Increment counter */ - ctx->initial_state[CHACHA20_CTR_INDEX]++; } return( 0 ); From 453cf2850fdd5dec672e443ccbeb31deefaac840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 12:18:34 +0200 Subject: [PATCH 21/42] Remove semi-internal chacha20_keystrem_block() It's actually easy to implement chachapoly without it, so let's not clutter the API (and avoid adding a burden to alt implementers). --- include/mbedtls/chacha20.h | 21 --------------------- library/chacha20.c | 37 ------------------------------------- library/chachapoly.c | 8 ++++++-- 3 files changed, 6 insertions(+), 60 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index 7999702f5..d32da1b77 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -107,27 +107,6 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, const unsigned char nonce[12], uint32_t counter ); -/** - * \brief Generates a block of keystream bytes for a specific counter value. - * - * This function uses the key and nonce previously set in - * the context (via mbedtls_chacha20_setkey and - * mbedtls_chacha20_starts), but ignores the previously - * set counter and uses the counter given as the parameter to - * this function. - * - * \param ctx The ChaCha20 context. This context is not modified. - * \param counter The counter value to use. - * \param keystream Buffer to where the generated keystream bytes are written. - * - * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or keystream are - * NULL. - * Otherwise, 0 is returned to indicate success. - */ -int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, - uint32_t counter, - unsigned char keystream[64] ); - /** * \brief Encrypt or decrypt data. * diff --git a/library/chacha20.c b/library/chacha20.c index 1abb96ef9..5ede4553c 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -246,43 +246,6 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, return( 0 ); } -int mbedtls_chacha20_keystream_block( const mbedtls_chacha20_context *ctx, - uint32_t counter, - unsigned char keystream[64] ) -{ - uint32_t initial_state[16]; - uint32_t working_state[16]; - - if ( ( ctx == NULL ) || ( keystream == NULL ) ) - { - return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); - } - - initial_state[0] = ctx->initial_state[0]; - initial_state[1] = ctx->initial_state[1]; - initial_state[2] = ctx->initial_state[2]; - initial_state[3] = ctx->initial_state[3]; - initial_state[4] = ctx->initial_state[4]; - initial_state[5] = ctx->initial_state[5]; - initial_state[6] = ctx->initial_state[6]; - initial_state[7] = ctx->initial_state[7]; - initial_state[8] = ctx->initial_state[8]; - initial_state[9] = ctx->initial_state[9]; - initial_state[10] = ctx->initial_state[10]; - initial_state[11] = ctx->initial_state[11]; - initial_state[12] = counter; - initial_state[13] = ctx->initial_state[13]; - initial_state[14] = ctx->initial_state[14]; - initial_state[15] = ctx->initial_state[15]; - - mbedtls_chacha20_block( initial_state, working_state, keystream ); - - mbedtls_zeroize( initial_state, sizeof( initial_state ) ); - mbedtls_zeroize( working_state, sizeof( working_state ) ); - - return( 0 ); -} - int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, size_t size, const unsigned char *input, diff --git a/library/chachapoly.c b/library/chachapoly.c index 3ba19542e..35ae99e11 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -143,15 +143,19 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } - result = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 1U ); + /* Set counter = 0, will be update to 1 when generating Poly1305 key */ + result = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U ); if ( result != 0 ) goto cleanup; /* Generate the Poly1305 key by getting the ChaCha20 keystream output with counter = 0. + * This is the same as encrypting a buffer of zeroes. * Only the first 256-bits (32 bytes) of the key is used for Poly1305. * The other 256 bits are discarded. */ - result = mbedtls_chacha20_keystream_block( &ctx->chacha20_ctx, 0U, poly1305_key ); + memset( poly1305_key, 0, sizeof( poly1305_key ) ); + result = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), + poly1305_key, poly1305_key ); if ( result != 0 ) goto cleanup; From 52a56d3b8606ccfe48927a3417454907ffa3d27b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 7 May 2018 12:56:36 +0200 Subject: [PATCH 22/42] chachapoly: split crypt_and_mac() to match GCM API In addition to making the APIs of the various AEAD modules more consistent with each other, it's useful to have an auth_decrypt() function so that we can safely check the tag ourselves, as the user might otherwise do it in an insecure way (or even forget to do it altogether). --- include/mbedtls/chachapoly.h | 51 ++++++++--- library/chachapoly.c | 93 +++++++++++++++------ tests/suites/test_suite_chachapoly.function | 37 +++++--- 3 files changed, 133 insertions(+), 48 deletions(-) diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index 810675ddd..e7413b36f 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -31,6 +31,8 @@ #define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ #define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ +#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x00049 /**< Authenticated decryption failed: data was not authentic. */ + #ifdef __cplusplus extern "C" { @@ -192,37 +194,64 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, unsigned char mac[16] ); /** - * \brief Encrypt or decrypt data, and produce a MAC with ChaCha20-Poly1305. + * \brief Encrypt or decrypt data, and produce a MAC (tag) with ChaCha20-Poly1305. * - * \param key The 256-bit (32 bytes) encryption key to use. - * \param nonce The 96-bit (12 bytes) nonce/IV to use. + * \param ctx The ChachaPoly context. * \param mode Specifies whether the data in the \p input buffer is to * be encrypted or decrypted. If there is no data to encrypt * or decrypt (i.e. \p ilen is 0) then the value of this * parameter does not matter. - * \param aad_len The length (in bytes) of the AAD data to process. + * \param length The length (in bytes) of the data to encrypt or decrypt. + * \param nonce The 96-bit (12 bytes) nonce/IV to use. * \param aad Buffer containing the additional authenticated data (AAD). * This pointer can be NULL if aad_len == 0. - * \param ilen The length (in bytes) of the data to encrypt or decrypt. + * \param aad_len The length (in bytes) of the AAD data to process. * \param input Buffer containing the data to encrypt or decrypt. * This pointer can be NULL if ilen == 0. * \param output Buffer to where the encrypted or decrypted data is written. * This pointer can be NULL if ilen == 0. - * \param mac Buffer to where the computed 128-bit (16 bytes) MAC is written. + * \param tag Buffer to where the computed 128-bit (16 bytes) MAC is written. * * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned * if one or more of the required parameters are NULL. * Otherwise, 0 is returned to indicate success. */ -int mbedtls_chachapoly_crypt_and_mac( const unsigned char key[32], - const unsigned char nonce[12], +int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, mbedtls_chachapoly_mode_t mode, - size_t aad_len, + size_t length, + const unsigned char nonce[12], const unsigned char *aad, - size_t ilen, + size_t aad_len, const unsigned char *input, unsigned char *output, - unsigned char mac[16] ); + unsigned char tag[16] ); + +/** + * \brief Decrypt data and check a MAC (tag) with ChaCha20-Poly1305. + * + * \param ctx The ChachaPoly context. + * \param length The length of the input and output data. + * \param nonce The nonce / initialization vector. + * \param aad The buffer holding the additional authenticated data. + * \param aad_len The length of the additional authenticated data. + * \param tag The buffer holding the tag. + * \param input The buffer holding the input data. + * \param output The buffer for holding the output data. + * + * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned + * if one or more of the required parameters are NULL. + * MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED if the tag does not + * match. + * Otherwise, 0 is returned to indicate success. + */ +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 ); /** * \brief Checkup routine diff --git a/library/chachapoly.c b/library/chachapoly.c index 35ae99e11..0dba5ed91 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -295,44 +295,70 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, return( 0 ); } -int mbedtls_chachapoly_crypt_and_mac ( const unsigned char key[32], - const unsigned char nonce[12], - mbedtls_chachapoly_mode_t mode, - size_t aad_len, - const unsigned char *aad, - size_t ilen, - const unsigned char *input, - unsigned char *output, - unsigned char mac[16] ) +int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, + mbedtls_chachapoly_mode_t mode, + 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] ) { - mbedtls_chachapoly_context ctx; int result; - mbedtls_chachapoly_init( &ctx ); - - result = mbedtls_chachapoly_setkey( &ctx, key ); + result = mbedtls_chachapoly_starts( ctx, nonce, mode ); if ( result != 0 ) goto cleanup; - result = mbedtls_chachapoly_starts( &ctx, nonce, mode ); - if ( result != 0 ) - goto cleanup; - - result = mbedtls_chachapoly_update_aad( &ctx, aad_len, aad ); + result = mbedtls_chachapoly_update_aad( ctx, aad_len, aad ); if ( result != 0 ) goto cleanup; - result = mbedtls_chachapoly_update( &ctx, ilen, input, output ); + result = mbedtls_chachapoly_update( ctx, length, input, output ); if ( result != 0 ) goto cleanup; - result = mbedtls_chachapoly_finish( &ctx, mac ); + result = mbedtls_chachapoly_finish( ctx, tag ); cleanup: - mbedtls_chachapoly_free( &ctx ); return( result ); } +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 ) +{ + int ret; + unsigned char check_tag[16]; + size_t i; + int diff; + + if( ( ret = mbedtls_chachapoly_crypt_and_tag( ctx, + MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, + aad, aad_len, input, output, check_tag ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < sizeof( check_tag ); i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ); + } + + return( 0 ); +} + #endif /* MBEDTLS_CHACHAPOLY_ALT */ #if defined(MBEDTLS_SELF_TEST) @@ -425,6 +451,7 @@ static const unsigned char test_mac[1][16] = int mbedtls_chachapoly_self_test( int verbose ) { + mbedtls_chachapoly_context ctx; unsigned i; int result; unsigned char output[200]; @@ -437,12 +464,24 @@ int mbedtls_chachapoly_self_test( int verbose ) mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); } - result = mbedtls_chachapoly_crypt_and_mac( test_key[i], - test_nonce[i], + mbedtls_chachapoly_init( &ctx ); + + result = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); + if ( result != 0 ) + { + if ( verbose != 0 ) + { + mbedtls_printf( "setkey() error code: %i\n", result ); + } + return( -1 ); + } + + result = mbedtls_chachapoly_crypt_and_tag( &ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, - test_aad_len[i], - test_aad[i], test_input_len[i], + test_nonce[i], + test_aad[i], + test_aad_len[i], test_input[i], output, mac ); @@ -450,7 +489,7 @@ int mbedtls_chachapoly_self_test( int verbose ) { if ( verbose != 0 ) { - mbedtls_printf( "error code: %i\n", result ); + mbedtls_printf( "crypt_and_tag() error code: %i\n", result ); } return( -1 ); } @@ -473,6 +512,8 @@ int mbedtls_chachapoly_self_test( int verbose ) return( -1 ); } + mbedtls_chachapoly_free( &ctx ); + if ( verbose != 0 ) { mbedtls_printf( "passed\n" ); diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index fb1a738f0..b205c4ce0 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -24,6 +24,7 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char size_t key_len; size_t nonce_len; size_t mac_len; + mbedtls_chachapoly_context ctx; memset( key_str, 0x00, 32 ); memset( nonce_str, 0x00, 12 ); @@ -43,14 +44,21 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char TEST_ASSERT( nonce_len == 12 ); TEST_ASSERT( mac_len == 16 ); - mbedtls_chachapoly_crypt_and_mac( key_str, nonce_str, + mbedtls_chachapoly_init( &ctx ); + + mbedtls_chachapoly_setkey( &ctx, key_str ); + + mbedtls_chachapoly_crypt_and_tag( &ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, - aad_len, aad_str, - input_len, input_str, output, - mac ); + input_len, nonce_str, + aad_str, aad_len, + input_str, output, mac ); TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); + +exit: + mbedtls_chachapoly_free( &ctx ); } /* END_CASE */ @@ -64,13 +72,14 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char unsigned char output_str[10000]; unsigned char mac_str[16]; unsigned char output[10000]; - unsigned char mac[16]; size_t input_len; size_t output_len; size_t aad_len; size_t key_len; size_t nonce_len; size_t mac_len; + int ret; + mbedtls_chachapoly_context ctx; memset( key_str, 0x00, 32 ); memset( nonce_str, 0x00, 12 ); @@ -90,14 +99,20 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char TEST_ASSERT( nonce_len == 12 ); TEST_ASSERT( mac_len == 16 ); - mbedtls_chachapoly_crypt_and_mac( key_str, nonce_str, - MBEDTLS_CHACHAPOLY_DECRYPT, - aad_len, aad_str, - input_len, input_str, output, - mac ); + mbedtls_chachapoly_init( &ctx ); + mbedtls_chachapoly_setkey( &ctx, key_str ); + + ret = mbedtls_chachapoly_auth_decrypt( &ctx, + input_len, nonce_str, + aad_str, aad_len, + mac_str, input_str, output ); + + TEST_ASSERT( ret == 0 ); TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); - TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); + +exit: + mbedtls_chachapoly_free( &ctx ); } /* END_CASE */ From 4f522633eb3655ce3645b00e74c0498e1bd10372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 May 2018 09:38:09 +0200 Subject: [PATCH 23/42] cipher: use new functions from chachapoly --- library/cipher.c | 60 ++++++++++-------------------------------------- 1 file changed, 12 insertions(+), 48 deletions(-) diff --git a/library/cipher.c b/library/cipher.c index acc986fa8..1827770b1 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -1000,34 +1000,17 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, #if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { - int ret; - + /* ChachaPoly has fixed length nonce and MAC (tag) */ if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) /* Truncated MAC is not allowed for Poly1305 */ + ( tag_len != 16U ) ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } *olen = ilen; - - ret = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - iv, MBEDTLS_CHACHAPOLY_ENCRYPT ); - if ( ret != 0 ) - return( ret ); - - ret = mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ad_len, ad ); - if ( ret != 0 ) - return( ret ); - - ret = mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ilen, input, output ); - if ( ret != 0 ) - return( ret ); - - ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - tag ); - return( ret ); + return( mbedtls_chachapoly_crypt_and_tag( ctx->cipher_ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + ilen, iv, ad, ad_len, input, output, tag ) ); } #endif /* MBEDTLS_CHACHAPOLY_C */ @@ -1079,42 +1062,23 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, #if defined(MBEDTLS_CHACHAPOLY_C) if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) { - unsigned char check_tag[16]; int ret; + /* ChachaPoly has fixed length nonce and MAC (tag) */ if ( ( iv_len != ctx->cipher_info->iv_size ) || - ( tag_len != 16U ) ) /* Truncated MAC is not allowed for Poly1305 */ + ( tag_len != 16U ) ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } *olen = ilen; + ret = mbedtls_chachapoly_auth_decrypt( ctx->cipher_ctx, ilen, + iv, ad, ad_len, tag, input, output ); - ret = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - iv, MBEDTLS_CHACHAPOLY_DECRYPT ); - if ( ret != 0 ) - return( ret ); + if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; - ret = mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ad_len, ad ); - if ( ret != 0 ) - return( ret ); - - ret = mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ilen, input, output ); - if ( ret != 0 ) - return( ret ); - - ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - check_tag ); - if ( ret != 0 ) - return( ret ); - - /* Compare the tag in constant time */ - if ( mbedtls_constant_time_memcmp( tag, check_tag, tag_len ) != 0 ) - return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); - - return( 0 ); + return( ret ); } #endif /* MBEDTLS_CHACHAPOLY_C */ From 6048e05d5c6040168e7ef3d0e55bc457fec92395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 8 May 2018 12:43:48 +0200 Subject: [PATCH 24/42] Update documentation to match new guidelines. --- include/mbedtls/chacha20.h | 157 ++++++++++-------- include/mbedtls/chachapoly.h | 297 +++++++++++++++++++++-------------- include/mbedtls/cipher.h | 6 +- include/mbedtls/poly1305.h | 124 +++++++++------ 4 files changed, 350 insertions(+), 234 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index d32da1b77..579ea3888 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -1,11 +1,18 @@ /** * \file chacha20.h * - * \brief ChaCha20 cipher. + * \brief This file contains ChaCha20 definitions and functions. + * + * ChaCha20 is a stream cipher that can encrypt and decrypt + * information. ChaCha was created by Daniel Bernstein as a variant of + * its Salsa cipher https://cr.yp.to/chacha/chacha-20080128.pdf + * ChaCha20 is the variant with 20 rounds, that was also standardized + * in RFC 7539. * * \author Daniel King - * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + */ + +/* 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 @@ -20,8 +27,9 @@ * 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) + * This file is part of Mbed TLS (https://tls.mbed.org) */ + #ifndef MBEDTLS_CHACHA20_H #define MBEDTLS_CHACHA20_H @@ -44,10 +52,10 @@ extern "C" { typedef struct { - uint32_t initial_state[16]; /*! Holds the initial state (before round operations) */ - uint32_t working_state[16]; /*! Holds the working state (after round operations) */ - uint8_t keystream8[64]; /*! Holds leftover keystream bytes */ - size_t keystream_bytes_used; /*! Number of keystream bytes currently used */ + uint32_t initial_state[16]; /*! The initial state (before round operations). */ + uint32_t working_state[16]; /*! The working state (after round operations). */ + uint8_t keystream8[64]; /*! Leftover keystream bytes. */ + size_t keystream_bytes_used; /*! Number of keystream bytes already used. */ } mbedtls_chacha20_context; @@ -56,118 +64,141 @@ mbedtls_chacha20_context; #endif /* MBEDTLS_CHACHA20_ALT */ /** - * \brief Initialize ChaCha20 context + * \brief This function initializes the specified ChaCha20 context. * - * \param ctx ChaCha20 context to be initialized + * It must be the first API called before using + * the context. + * + * It is usually followed by calls to + * \c mbedtls_chacha20_setkey() and + * \c mbedtls_chacha20_starts(), then one or more calls to + * to \c mbedtls_chacha20_update(), and finally to + * \c mbedtls_chacha20_free(). + * + * \param ctx The ChaCha20 context to initialize. */ void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ); /** - * \brief Clear ChaCha20 context + * \brief This function releases and clears the specified ChaCha20 context. * - * \param ctx ChaCha20 context to be cleared + * \param ctx The ChaCha20 context to clear. */ void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ); /** - * \brief Set the ChaCha20 key. + * \brief This function sets the encryption/decryption key. * - * \note The nonce and counter must be set after calling this function, - * before data can be encrypted/decrypted. The nonce and - * counter are set by calling mbedtls_chacha20_starts. + * \note After using this function, you must also call + * \c mbedtls_chacha20_starts() to set a nonce before you + * start encrypting/decrypting data with + * \c mbedtls_chacha_update(). * - * \see mbedtls_chacha20_starts + * \param ctx The ChaCha20 context to which the key should be bound. + * \param key The encryption/decryption key. Must be 32 bytes in length. * - * \param ctx The context to setup. - * \param key Buffer containing the 256-bit key. Must be 32 bytes in length. - * - * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA is returned if ctx or key - * is NULL, or if key_bits is not 128 or 256. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or key is NULL. */ int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, const unsigned char key[32] ); /** - * \brief Set the ChaCha20 nonce and initial counter value. + * \brief This function sets the nonce and initial counter value. * * \note A ChaCha20 context can be re-used with the same key by - * calling this function to change the nonce and/or initial - * counter value. + * calling this function to change the nonce. * - * \param ctx The ChaCha20 context. - * \param nonce Buffer containing the 96-bit nonce. Must be 12 bytes in size. - * \param counter Initial counter value to use. This is usually 0. + * \warning You must never use the same nonce twice with the same key. + * This would void any confidentiality guarantees for the + * messages encrypted with the same nonce and key. * - * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA is returned if ctx or - * nonce is NULL. - * Otherwise, 0 is returned to indicate success. + * \param ctx The ChaCha20 context to which the nonce should be bound. + * \param nonce The nonce. Must be 12 bytes in size. + * \param counter The initial counter value. This is usually 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if ctx or nonce is + * NULL. */ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, const unsigned char nonce[12], uint32_t counter ); /** - * \brief Encrypt or decrypt data. + * \brief This function encrypts or decrypts data. * - * This function is used to both encrypt and decrypt data. + * Since ChaCha20 is a stream cipher, the same operation is + * used for encrypting and decrypting data. * * \note The \p input and \p output pointers must either be equal or * point to non-overlapping buffers. * - * \note mbedtls_chacha20_setkey and mbedtls_chacha20_starts must be - * called at least once to setup the context before this function - * can be called. + * \note \c mbedtls_chacha20_setkey() and + * \c mbedtls_chacha20_starts() must be called at least once + * to setup the context before this function can be called. * - * \param ctx The ChaCha20 context. - * \param size The length (in bytes) to process. This can have any length. - * \param input Buffer containing the input data. + * \note This function can be called mutliple times in a row in + * order to encrypt of decrypt data piecewise with the same + * key and nonce. + * + * \param ctx The ChaCha20 context to use for encryption or decryption. + * \param size The length of the input data in bytes. + * \param input The buffer holding the input data. * This pointer can be NULL if size == 0. - * \param output Buffer containing the output data. + * \param output The buffer holding the output data. + * Must be able to hold \p size bytes. * This pointer can be NULL if size == 0. * - * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or * output pointers are NULL. - * Otherwise, 0 is returned to indicate success. */ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, - size_t size, - const unsigned char *input, - unsigned char *output ); + size_t size, + const unsigned char *input, + unsigned char *output ); /** - * \brief Encrypt or decrypt a message using ChaCha20. + * \brief This function encrypts or decrypts data with ChaCha20 and + * the given key and nonce. * - * This function is used the same way for encrypting and - * decrypting data. It's not necessary to specify which - * operation is being performed. + * Since ChaCha20 is a stream cipher, the same operation is + * used for encrypting and decrypting data. * - * \note The \p input and \p output buffers may overlap, but only - * if input >= output (i.e. only if input points ahead of - * the output pointer). + * \warning You must never use the same (key, nonce) pair more than + * once. This would void any confidentiality guarantees for + * the messages encrypted with the same nonce and key. * - * \param key Buffer containing the 256-bit key. Must be 32 bytes in length. - * \param nonce Buffer containing the 96-bit nonce. Must be 12 bytes in length. + * \note The \p input and \p output pointers must either be equal or + * point to non-overlapping buffers. + * + * \param key The encryption/decryption key. Must be 32 bytes in length. + * \param nonce The nonce. Must be 12 bytes in size. * \param counter The initial counter value. This is usually 0. - * \param data_len The number of bytes to process. - * \param input Buffer containing the input data (data to encrypt or decrypt). - * \param output Buffer to where the processed data is written. + * \param size The length of the input data in bytes. + * \param input The buffer holding the input data. + * This pointer can be NULL if size == 0. + * \param output The buffer holding the output data. + * Must be able to hold \p size bytes. + * This pointer can be NULL if size == 0. * - * \return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if key, nonce, input, + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if key, nonce, input, * or output is NULL. - * Otherwise, 0 is returned to indicate success. */ int mbedtls_chacha20_crypt( const unsigned char key[32], const unsigned char nonce[12], uint32_t counter, - size_t data_len, + size_t size, const unsigned char* input, unsigned char* output ); /** - * \brief Checkup routine + * \brief The ChaCha20 checkup routine. * - * \return 0 if successful, or 1 if the test failed + * \return \c 0 on success. + * \return \c 1 on failure. */ int mbedtls_chacha20_self_test( int verbose ); diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index e7413b36f..ddcd54972 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -1,9 +1,18 @@ /** * \file chachapoly.h * - * \brief ChaCha20-Poly1305 AEAD construction based on RFC 7539. + * \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and + * functions. * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * 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 + */ + +/* 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 @@ -18,8 +27,9 @@ * 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) + * This file is part of Mbed TLS (https://tls.mbed.org) */ + #ifndef MBEDTLS_CHACHAPOLY_H #define MBEDTLS_CHACHAPOLY_H @@ -30,7 +40,7 @@ #endif #define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ -#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state */ +#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state. */ #define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x00049 /**< Authenticated decryption failed: data was not authentic. */ @@ -40,8 +50,8 @@ extern "C" { typedef enum { - MBEDTLS_CHACHAPOLY_ENCRYPT, - MBEDTLS_CHACHAPOLY_DECRYPT + MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */ + MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */ } mbedtls_chachapoly_mode_t; @@ -52,12 +62,12 @@ mbedtls_chachapoly_mode_t; typedef struct { - mbedtls_chacha20_context chacha20_ctx; /** ChaCha20 context */ - mbedtls_poly1305_context poly1305_ctx; /** Poly1305 context */ - uint64_t aad_len; /** Length (bytes) of the Additional Authenticated Data */ - uint64_t ciphertext_len; /** Length (bytes) of the ciphertext */ - int state; /** Current state of the context */ - mbedtls_chachapoly_mode_t mode; /** Cipher mode (encrypt or decrypt) */ + 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; @@ -66,112 +76,144 @@ mbedtls_chachapoly_context; #endif /* !MBEDTLS_CHACHAPOLY_ALT */ /** - * \brief Initialize ChaCha20-Poly1305 context + * \brief This function initializes the specified ChaCha20-Poly1305 context. * - * \param ctx ChaCha20-Poly1305 context to be initialized + * 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 or decrypt 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(). + * + * + * \param ctx The ChachaPoly context to initialize. */ void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ); /** - * \brief Clear ChaCha20-Poly1305 context + * \brief This function releases and clears the specified ChaCha20-Poly1305 context. * - * \param ctx ChaCha20-Poly1305 context to be cleared + * \param ctx The ChachaPoly context to clear. */ void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); /** - * \brief Set the ChaCha20-Poly1305 symmetric encryption key. + * \brief This function sets the ChaCha20-Poly1305 symmetric encryption key. * - * \param ctx The ChaCha20-Poly1305 context. - * \param key The 256-bit (32 bytes) key. + * \param ctx The ChaCha20-Poly1305 context to which the key should be + * bound. + * \param key The 256-bit (32 bytes) key. * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if \p ctx or \p key are NULL. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * if \p ctx or \p key are NULL. */ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, const unsigned char key[32] ); /** - * \brief Setup ChaCha20-Poly1305 context for encryption or decryption. + * \brief This function starts a ChaCha20-Poly1305 encryption or + * decryption operation. * - * \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 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. - * \param nonce The nonce/IV to use for the message. This must be unique - * for every message encrypted under the same key. - * \param mode Specifies whether the context is used to encrypt or - * decrypt data. + * \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. * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if \p ctx or \p mac are NULL. - * Otherwise, 0 is returned to indicate success. + * \param ctx The ChaCha20-Poly1305 context. + * \param nonce The nonce/IV to use for the message. Must be 12 bytes. + * \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or + * #MBEDTLS_CHACHAPOLY_DECRYPT. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * if \p ctx or \p mac are NULL. */ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, const unsigned char nonce[12], mbedtls_chachapoly_mode_t mode ); /** - * \brief Process additional authenticated data (AAD). + * \brief This function feeds additional data to be authenticated + * into an ongoing ChaCha20-Poly1305 operation. * - * This function processes data that is authenticated, but - * not encrypted. + * 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 fro mthe 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 - * mbedtls_chachapoly_update. + * \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. + * 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 mbedtls_chachapoly_update, - * or if the context has been finished. + * This function cannot be called any more if data has + * been processed by \c mbedtls_chachapoly_update(), + * or if the context has been finished. * - * \param ctx The ChaCha20-Poly1305 context. - * \param aad_len The length (in bytes) of the AAD. The length has no - * restrictions. - * \param aad Buffer containing the AAD. - * This pointer can be NULL if aad_len == 0. + * \param ctx The ChaCha20-Poly1305 context to use. + * \param aad_len The length (in bytes) of the AAD. The length has no + * restrictions. + * \param aad Buffer containing the AAD. + * This pointer can be NULL if aad_len == 0. * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if \p ctx or \p aad are NULL. - * MBEDTLS_ERR_CHACHAPOLY_BAD_STATE is returned if - * the context has not been setup, the context has been - * finished, or if the AAD has been finished. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_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, size_t aad_len, const unsigned char *aad ); /** - * \brief Encrypt/decrypt data. + * \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 - * mbedtls_chachapoly_starts. + * 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. + * 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. * - * \param ctx The ChaCha20-Poly1305 context. - * \param len The length (in bytes) of the data to encrypt or decrypt. - * \param input Buffer containing the data to encrypt or decrypt. - * This pointer can be NULL if len == 0. - * \param output Buffer to where the encrypted or decrypted data is written. - * This pointer can be NULL if len == 0. + * \param ctx The ChaCha20-Poly1305 context to use. + * \param len The length (in bytes) of the data to encrypt or decrypt. + * \param input The buffer containing the data to encrypt or decrypt. + * This pointer can be NULL if len == 0. + * \param output The buffer to where the encrypted or decrypted data is written. + * Must be able to hold \p len bytes. + * This pointer can be NULL if len == 0. * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if \p ctx, \p input, or \p output are NULL. - * MBEDTLS_ERR_CHACHAPOLY_BAD_STATE is returned if - * the context has not been setup, or if the context has been - * finished. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * if \p ctx, \p input, or \p output are NULL. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE + * if the operation has not been started or has been + * finished. */ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, size_t len, @@ -179,42 +221,51 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, unsigned char *output ); /** - * \brief Compute the ChaCha20-Poly1305 MAC. + * \brief This function finished the ChaCha20-Poly1305 operation and + * generates the MAC (authentication tag). * - * \param ctx The ChaCha20-Poly1305 context. - * \param mac Buffer to where the 128-bit (16 bytes) MAC is written. + * \param ctx The ChaCha20-Poly1305 context to use. + * \param mac The buffer to where the 128-bit (16 bytes) MAC is written. * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if \p ctx or \p mac are NULL. - * MBEDTLS_ERR_CHACHAPOLY_BAD_STATE is returned if - * the context has not been setup. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * if \p ctx or \p mac are NULL. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE + * if the operation has not been started or has been + * finished. */ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, unsigned char mac[16] ); /** - * \brief Encrypt or decrypt data, and produce a MAC (tag) with ChaCha20-Poly1305. + * \brief This function performs a complete ChaCha20-Poly1305 + * operation with the previously-set key. * - * \param ctx The ChachaPoly context. - * \param mode Specifies whether the data in the \p input buffer is to - * be encrypted or decrypted. If there is no data to encrypt - * or decrypt (i.e. \p ilen is 0) then the value of this - * parameter does not matter. - * \param length The length (in bytes) of the data to encrypt or decrypt. - * \param nonce The 96-bit (12 bytes) nonce/IV to use. - * \param aad Buffer containing the additional authenticated data (AAD). - * This pointer can be NULL if aad_len == 0. - * \param aad_len The length (in bytes) of the AAD data to process. - * \param input Buffer containing the data to encrypt or decrypt. - * This pointer can be NULL if ilen == 0. - * \param output Buffer to where the encrypted or decrypted data is written. - * This pointer can be NULL if ilen == 0. - * \param tag Buffer to where the computed 128-bit (16 bytes) MAC is written. + * \note Before using this function, you must set the key with + * \c mbedtls_chachapoly_setkey(). * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if one or more of the required parameters are NULL. - * Otherwise, 0 is returned to indicate success. + * \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). + * \param mode The operation to perform: #MBEDTLS_CHACHAPOLY_ENCRYPT or + * #MBEDTLS_CHACHAPOLY_DECRYPT. + * \param length The length (in bytes) of the data to encrypt or decrypt. + * \param nonce The 96-bit (12 bytes) nonce/IV to use. + * \param aad The buffer containing the additional authenticated data (AAD). + * This pointer can be NULL if aad_len == 0. + * \param aad_len The length (in bytes) of the AAD data to process. + * \param input The buffer containing the data to encrypt or decrypt. + * This pointer can be NULL if ilen == 0. + * \param output The buffer to where the encrypted or decrypted data is written. + * This pointer can be NULL if ilen == 0. + * \param tag The buffer to where the computed 128-bit (16 bytes) MAC is written. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * if one or more of the required parameters are NULL. */ int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, mbedtls_chachapoly_mode_t mode, @@ -227,22 +278,29 @@ int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, unsigned char tag[16] ); /** - * \brief Decrypt data and check a MAC (tag) with ChaCha20-Poly1305. + * \brief This function performs a complete ChaCha20-Poly1305 + * authenticated decryption with the previously-set key. * - * \param ctx The ChachaPoly context. - * \param length The length of the input and output data. - * \param nonce The nonce / initialization vector. - * \param aad The buffer holding the additional authenticated data. - * \param aad_len The length of the additional authenticated data. - * \param tag The buffer holding the tag. - * \param input The buffer holding the input data. - * \param output The buffer for holding the output data. + * \note Before using this function, you must set the key with + * \c mbedtls_chachapoly_setkey(). * - * \return MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA is returned - * if one or more of the required parameters are NULL. - * MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED if the tag does not - * match. - * Otherwise, 0 is returned to indicate success. + * \param ctx The ChaCha20-Poly1305 context to use (holds the key). + * \param length The length (in bytes) of the data to decrypt. + * \param nonce The 96-bit (12 bytes) nonce/IV to use. + * \param aad The buffer containing the additional authenticated data (AAD). + * This pointer can be NULL if aad_len == 0. + * \param aad_len The length (in bytes) of the AAD data to process. + * \param tag The buffer holding the authentication tag. + * \param input The buffer containing the data to decrypt. + * This pointer can be NULL if ilen == 0. + * \param output The buffer to where the decrypted data is written. + * This pointer can be NULL if ilen == 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * if one or more of the required parameters are NULL. + * \return #MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED + * if the data was not authentic. */ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, size_t length, @@ -254,9 +312,10 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, unsigned char *output ); /** - * \brief Checkup routine + * \brief The ChaCha20-Poly1305 checkup routine. * - * \return 0 if successful, or 1 if the test failed + * \return \c 0 on success. + * \return \c 1 on failure. */ int mbedtls_chachapoly_self_test( int verbose ); diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index ac1f564fb..591aa79aa 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -86,7 +86,7 @@ typedef enum { MBEDTLS_CIPHER_ID_CAMELLIA, /**< The Camellia cipher. */ MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ - MBEDTLS_CIPHER_ID_CHACHA20, /**< The Chacha20 cipher. */ + MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ } mbedtls_cipher_id_t; /** @@ -146,8 +146,8 @@ typedef enum { MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ - MBEDTLS_CIPHER_CHACHA20, /**< Chacha20 stream cipher. */ - MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< Chacha20-Poly1305 AEAD cipher. */ + MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ + MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ } mbedtls_cipher_type_t; /** Supported cipher modes. */ diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index f69191578..c2e2655e7 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -1,9 +1,18 @@ /** * \file poly1305.h * - * \brief Poly1305 authenticator algorithm. + * \brief This file containts Poly1305 definitions and functions. * - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Poly1305 is a one-time message authenticator that can be used to + * authenticate messages. Poly1305-AES was created by Daniel + * Bernstein https://cr.yp.to/mac/poly1305-20050329.pdf The generic + * Poly1305 algorithm (not tied to AES) was also standardized in RFC + * 7539. + * + * \author Daniel King + */ + +/* 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 @@ -18,8 +27,9 @@ * 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) + * This file is part of Mbed TLS (https://tls.mbed.org) */ + #ifndef MBEDTLS_POLY1305_H #define MBEDTLS_POLY1305_H @@ -42,11 +52,11 @@ extern "C" { typedef struct { - uint32_t r[4]; /** Stores the value for 'r' (low 128 bits of the key) */ - uint32_t s[4]; /** Stores the value for 's' (high 128 bits of the key) */ - uint32_t acc[5]; /** Accumulator number */ - uint8_t queue[16]; /** Stores partial block data */ - size_t queue_len; /** Number of bytes stored in 'queue'. Always less than 16 */ + uint32_t r[4]; /** The value for 'r' (low 128 bits of the key). */ + uint32_t s[4]; /** The value for 's' (high 128 bits of the key). */ + uint32_t acc[5]; /** The accumulator number. */ + uint8_t queue[16]; /** The current partial block of data. */ + size_t queue_len; /** The number of bytes stored in 'queue'. */ } mbedtls_poly1305_context; @@ -55,82 +65,97 @@ mbedtls_poly1305_context; #endif /* MBEDTLS_POLY1305_ALT */ /** - * \brief Initialize a Poly1305 context + * \brief This function initializes the specified Poly1305 context. * - * \param ctx The Poly1305 context to be initialized + * It must be the first API called before using + * the context. + * + * It is usually followed by a call to + * \c mbedtls_poly1305_starts(), then one or more calls to + * \c mbedtls_poly1305_update(), then one call to + * \c mbedtls_poly1305_finish(), then finally + * \c mbedtls_poly1305_free(). + * + * \param ctx The Poly1305 context to initialize. */ void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ); /** - * \brief Clear a Poly1305 context + * \brief This function releases and clears the specified Poly1305 context. * - * \param ctx The Poly1305 context to be cleared + * \param ctx The Poly1305 context to clear. */ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); /** - * \brief Set the Poly1305 authentication key. + * \brief This function sets the one-time authentication key. * - * \warning The key should be unique, and \b MUST be - * unpredictable for each invocation of Poly1305. + * \warning The key must be unique and unpredictable for each + * invocation of Poly1305. * - * \param ctx The Poly1305 context. - * \param key Buffer containing the 256-bit key. + * \param ctx The Poly1305 context to which the key should be bound. + * \param key The buffer containing the 256-bit key. * - * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx - * or key are NULL. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA + * if ctx or key are NULL. */ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, const unsigned char key[32] ); /** - * \brief Process data with Poly1305. + * \brief This functions feeds an input bufer into an ongoing + * Poly1305 computation. * - * This function can be called multiple times to process - * a stream of data. + * It is called between \c mbedtls_cipher_cmac_starts() and + * \c mbedtls_cipher_cmac_finish(). + * Can be called repeatedly to process a stream of data. * - * \param ctx The Poly1305 context. - * \param ilen The input length (in bytes). Any value is accepted. - * \param input Buffer containing the input data to Process. - * This pointer can be NULL if ilen == 0. + * \param ctx The Poly1305 context to use for the Poly1305 operation. + * \param ilen The length of the input data (in bytes). Any value is accepted. + * \param input The buffer holding the input data. + * This pointer can be NULL if ilen == 0. * - * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx - * or input are NULL. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA + * if ctx or input are NULL. */ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, size_t ilen, const unsigned char *input ); /** - * \brief Generate the Poly1305 MAC. + * \brief This function generates the Poly1305 Message + * Authentication Code (MAC). * - * \param ctx The Poly1305 context. - * \param mac Buffer to where the MAC is written. Must be big enough - * to hold the 16-byte MAC. + * \param ctx The Poly1305 context to use for the Poly1305 operation. + * \param mac The buffer to where the MAC is written. Must be big enough + * to hold the 16-byte MAC. * - * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if ctx - * or mac are NULL. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA + * if ctx or mac are NULL. */ int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, unsigned char mac[16] ); /** - * \brief Generate the Poly1305 MAC of some data with the given key. + * \brief This function calculates the Poly1305 MAC of the input + * buffer with the provided key. * - * \warning The key should be unique, and \b MUST be - * unpredictable for each invocation of Poly1305. + * \warning The key must be unique and unpredictable for each + * invocation of Poly1305. * - * \param key Buffer containing the 256-bit (32 bytes) key. - * \param ilen The length of the input data (in bytes). - * \param input Buffer containing the input data to process. - * \param mac Buffer to where the 128-bit (16 bytes) MAC is written. + * \param key The buffer containing the 256-bit key. + * \param ilen The length of the input data (in bytes). Any value is accepted. + * \param input The buffer holding the input data. + * This pointer can be NULL if ilen == 0. + * \param mac The buffer to where the MAC is written. Must be big enough + * to hold the 16-byte MAC. * - * \return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA is returned if key, - * input, or mac are NULL. - * Otherwise, 0 is returned to indicate success. + * \return \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA + * if key, input, or mac are NULL. */ int mbedtls_poly1305_mac( const unsigned char key[32], size_t ilen, @@ -138,9 +163,10 @@ int mbedtls_poly1305_mac( const unsigned char key[32], unsigned char mac[16] ); /** - * \brief Checkup routine + * \brief The Poly1305 checkup routine. * - * \return 0 if successful, or 1 if the test failed + * \return \c 0 on success. + * \return \c 1 on failure. */ int mbedtls_poly1305_self_test( int verbose ); From 9b7a93cf1f6313dfdaf89986fed8b073db013516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 09:25:00 +0200 Subject: [PATCH 25/42] poly1305: adjust parameter order This module used (len, pointer) while (pointer, len) is more common in the rest of the library, in particular it's what's used in the CMAC API that is very comparable to Poly1305, so switch to (pointer, len) for consistency. --- include/mbedtls/poly1305.h | 6 +++--- library/chachapoly.c | 16 ++++++++-------- library/poly1305.c | 14 +++++++------- programs/test/benchmark.c | 2 +- tests/suites/test_suite_poly1305.function | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index c2e2655e7..19f523774 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -121,8 +121,8 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, * if ctx or input are NULL. */ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, - size_t ilen, - const unsigned char *input ); + const unsigned char *input, + size_t ilen ); /** * \brief This function generates the Poly1305 Message @@ -158,8 +158,8 @@ int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, * if key, input, or mac are NULL. */ int mbedtls_poly1305_mac( const unsigned char key[32], - size_t ilen, const unsigned char *input, + size_t ilen, unsigned char mac[16] ); /** diff --git a/library/chachapoly.c b/library/chachapoly.c index 0dba5ed91..d599c5240 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -66,8 +66,8 @@ static void mbedtls_chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) { memset( zeroes, 0, sizeof( zeroes ) ); (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, - 16U - partial_block_len, - zeroes ); + zeroes, + 16U - partial_block_len ); } } @@ -85,8 +85,8 @@ static void mbedtls_chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) { memset( zeroes, 0, sizeof( zeroes ) ); (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, - 16U - partial_block_len, - zeroes ); + zeroes, + 16U - partial_block_len ); } } @@ -194,7 +194,7 @@ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, ctx->aad_len += aad_len; - return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad_len, aad ) ); + return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) ); } int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, @@ -233,11 +233,11 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, * above, we can safety ignore the return value. */ (void) mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); - (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, len, output ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len ); } else /* DECRYPT */ { - (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, len, input ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len ); (void) mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); } @@ -289,7 +289,7 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, len_block[14] = (unsigned char) ( ctx->ciphertext_len >> 48 ); len_block[15] = (unsigned char) ( ctx->ciphertext_len >> 56 ); - (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, 16U, len_block ); + (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U ); (void) mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); return( 0 ); diff --git a/library/poly1305.c b/library/poly1305.c index 66f932c4f..14c362d58 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -285,8 +285,8 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, } int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, - size_t ilen, - const unsigned char* input ) + const unsigned char *input, + size_t ilen ) { size_t offset = 0U; size_t remaining = ilen; @@ -391,9 +391,9 @@ int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, } int mbedtls_poly1305_mac( const unsigned char key[32], - size_t ilen, - const unsigned char *input, - unsigned char mac[16] ) + const unsigned char *input, + size_t ilen, + unsigned char mac[16] ) { mbedtls_poly1305_context ctx; int result; @@ -404,7 +404,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32], if ( result != 0 ) goto cleanup; - result = mbedtls_poly1305_update( &ctx, ilen, input ); + result = mbedtls_poly1305_update( &ctx, input, ilen ); if ( result != 0 ) goto cleanup; @@ -496,8 +496,8 @@ int mbedtls_poly1305_self_test( int verbose ) } result = mbedtls_poly1305_mac( test_keys[i], - test_data_len[i], test_data[i], + test_data_len[i], mac ); if ( result != 0 ) { diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index c41966586..17f9d0e27 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -538,7 +538,7 @@ int main( int argc, char *argv[] ) #if defined(MBEDTLS_POLY1305_C) if ( todo.poly1305 ) { - TIME_AND_TSC( "Poly1305", mbedtls_poly1305_mac( buf, BUFSIZE, buf, buf ) ); + TIME_AND_TSC( "Poly1305", mbedtls_poly1305_mac( buf, buf, BUFSIZE, buf ) ); } #endif diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function index af69a0312..a633c2baa 100644 --- a/tests/suites/test_suite_poly1305.function +++ b/tests/suites/test_suite_poly1305.function @@ -20,7 +20,7 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src src_len = unhexify( src_str, hex_src_string ); unhexify( key, hex_key_string ); - mbedtls_poly1305_mac( key, src_len, src_str, mac ); + mbedtls_poly1305_mac( key, src_str, src_len, mac ); hexify( mac_str, mac, 16 ); TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); From 799b3903de734ceb27b018d81156655dca77f4be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 09:34:25 +0200 Subject: [PATCH 26/42] chachapoly: adjust parameter order This module used (len, pointer) while (pointer, len) is more common in the rest of the library, in particular it's what's used in the GCM API that very comparable to it, so switch to (pointer, len) for consistency. Note that the crypt_and_tag() and auth_decrypt() functions were already using the same convention as GCM, so this also increases intra-module consistency. --- include/mbedtls/chachapoly.h | 4 ++-- library/chachapoly.c | 6 +++--- library/cipher.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index ddcd54972..ce9737c2b 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -183,8 +183,8 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, * finished, or if the AAD has been finished. */ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, - size_t aad_len, - const unsigned char *aad ); + const unsigned char *aad, + size_t aad_len ); /** * \brief Thus function feeds data to be encrypted or decrypted diff --git a/library/chachapoly.c b/library/chachapoly.c index d599c5240..9ca21b39a 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -175,8 +175,8 @@ cleanup: } int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, - size_t aad_len, - const unsigned char *aad ) + const unsigned char *aad, + size_t aad_len ) { if ( ctx == NULL ) { @@ -311,7 +311,7 @@ int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, if ( result != 0 ) goto cleanup; - result = mbedtls_chachapoly_update_aad( ctx, aad_len, aad ); + result = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); if ( result != 0 ) goto cleanup; diff --git a/library/cipher.c b/library/cipher.c index 1827770b1..2463a6148 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -320,7 +320,7 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, return( result ); return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ad_len, ad ); + ad, ad_len ); } #endif From d17d297a63a3869a0f4fb9d9b0e57193ebb4c271 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 09:54:51 +0200 Subject: [PATCH 27/42] Add FEATURE_NOT_AVAILABLE error codes. --- include/mbedtls/chacha20.h | 3 ++- include/mbedtls/chachapoly.h | 7 ++++--- include/mbedtls/error.h | 6 +++--- include/mbedtls/poly1305.h | 3 ++- library/error.c | 8 ++++++++ 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index 579ea3888..7a8cd531e 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -42,7 +42,8 @@ #include #include -#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x003B /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0053 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0055 /**< Feature not available. For example, s part of the API is not implemented. */ #ifdef __cplusplus extern "C" { diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index ce9737c2b..a55a3eea2 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -39,9 +39,10 @@ #include MBEDTLS_CONFIG_FILE #endif -#define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x00047 /**< Invalid input parameter(s). */ -#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x00049 /**< The requested operation is not permitted in the current state. */ -#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x00049 /**< Authenticated decryption failed: data was not authentic. */ +#define MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA -0x0054 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0056 /**< The requested operation is not permitted in the current state. */ +#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0058 /**< Authenticated decryption failed: data was not authentic. */ +#define MBEDTLS_ERR_CHACHAPOLY_FEATURE_UNAVAILABLE -0x005A /**< Feature not available. For example, s part of the API is not implemented. */ #ifdef __cplusplus diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index e056975a2..21fa9fce2 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -76,9 +76,9 @@ * SHA1 1 0x0035-0x0035 * SHA256 1 0x0037-0x0037 * SHA512 1 0x0039-0x0039 - * CHACHA20 1 0x003B-0x003B - * POLY1305 1 0x0041-0x0041 - * CHACHAPOLY 2 0x0047-0x0049 + * CHACHA20 2 0x0053-0x0055 + * POLY1305 2 0x0057-0x0059 + * CHACHAPOLY 4 0x0054-0x005A * * High-level module nr (3 bits - 0x0...-0x7...) * Name ID Nr of Errors diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index 19f523774..021a3a0de 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -42,7 +42,8 @@ #include #include -#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0041 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA -0x0057 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE -0x0059 /**< Feature not available. For example, s part of the API is not implemented. */ #ifdef __cplusplus extern "C" { diff --git a/library/error.c b/library/error.c index aeef9303a..d9c21cd3f 100644 --- a/library/error.c +++ b/library/error.c @@ -668,6 +668,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) #if defined(MBEDTLS_CHACHA20_C) if( use_ret == -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA) ) mbedtls_snprintf( buf, buflen, "CHACHA20 - Invalid input parameter(s)" ); + if( use_ret == -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "CHACHA20 - Feature not available. For example, s part of the API is not implemented" ); #endif /* MBEDTLS_CHACHA20_C */ #if defined(MBEDTLS_CHACHAPOLY_C) @@ -675,6 +677,10 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Invalid input parameter(s)" ); if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE) ) mbedtls_snprintf( buf, buflen, "CHACHAPOLY - The requested operation is not permitted in the current state" ); + if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Authenticated decryption failed: data was not authentic" ); + if( use_ret == -(MBEDTLS_ERR_CHACHAPOLY_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "CHACHAPOLY - Feature not available. For example, s part of the API is not implemented" ); #endif /* MBEDTLS_CHACHAPOLY_C */ #if defined(MBEDTLS_CMAC_C) @@ -792,6 +798,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) #if defined(MBEDTLS_POLY1305_C) if( use_ret == -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA) ) mbedtls_snprintf( buf, buflen, "POLY1305 - Invalid input parameter(s)" ); + if( use_ret == -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "POLY1305 - Feature not available. For example, s part of the API is not implemented" ); #endif /* MBEDTLS_POLY1305_C */ #if defined(MBEDTLS_RIPEMD160_C) From c975b2cc41e898b1d862e7aa515cd7a8e92cec7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 10:21:28 +0200 Subject: [PATCH 28/42] Add Chacha20-Poly1305 to benchmark.c --- programs/test/benchmark.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index 17f9d0e27..3e9ab0a29 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -62,6 +62,7 @@ int main( void ) #include "mbedtls/chacha20.h" #include "mbedtls/gcm.h" #include "mbedtls/ccm.h" +#include "mbedtls/chachapoly.h" #include "mbedtls/cmac.h" #include "mbedtls/poly1305.h" #include "mbedtls/havege.h" @@ -96,7 +97,7 @@ int main( void ) #define OPTIONS \ "md4, md5, ripemd160, sha1, sha256, sha512,\n" \ "arc4, des3, des, camellia, blowfish, chacha20,\n" \ - "aes_cbc, aes_gcm, aes_ccm,\n" \ + "aes_cbc, aes_gcm, aes_ccm, chachapoly,\n" \ "aes_cmac, des3_cmac, poly1305\n" \ "havege, ctr_drbg, hmac_drbg\n" \ "rsa, dhm, ecdsa, ecdh.\n" @@ -231,7 +232,8 @@ unsigned char buf[BUFSIZE]; typedef struct { char md4, md5, ripemd160, sha1, sha256, sha512, arc4, des3, des, - aes_cbc, aes_gcm, aes_ccm, aes_cmac, des3_cmac, + aes_cbc, aes_gcm, aes_ccm, chachapoly, + aes_cmac, des3_cmac, camellia, blowfish, chacha20, poly1305, havege, ctr_drbg, hmac_drbg, @@ -282,6 +284,8 @@ int main( int argc, char *argv[] ) todo.aes_gcm = 1; else if( strcmp( argv[i], "aes_ccm" ) == 0 ) todo.aes_ccm = 1; + else if( strcmp( argv[i], "chachapoly" ) == 0 ) + todo.chachapoly = 1; else if( strcmp( argv[i], "aes_cmac" ) == 0 ) todo.aes_cmac = 1; else if( strcmp( argv[i], "des3_cmac" ) == 0 ) @@ -473,6 +477,27 @@ int main( int argc, char *argv[] ) } } #endif +#if defined(MBEDTLS_CHACHAPOLY_C) + if( todo.chachapoly ) + { + mbedtls_chachapoly_context chachapoly; + + mbedtls_chachapoly_init( &chachapoly ); + memset( buf, 0, sizeof( buf ) ); + memset( tmp, 0, sizeof( tmp ) ); + + mbedtls_snprintf( title, sizeof( title ), "ChaCha20-Poly1305" ); + + mbedtls_chachapoly_setkey( &chachapoly, tmp ); + + TIME_AND_TSC( title, + mbedtls_chachapoly_crypt_and_tag( &chachapoly, + MBEDTLS_CHACHAPOLY_ENCRYPT, BUFSIZE, tmp, + NULL, 0, buf, buf, tmp ) ); + + mbedtls_chachapoly_free( &chachapoly ); + } +#endif #if defined(MBEDTLS_CMAC_C) if( todo.aes_cmac ) { From f11d8e5f4d765546786f4ad3975433741d739e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 11:21:21 +0200 Subject: [PATCH 29/42] Reduce size of buffers in test suites --- tests/suites/test_suite_chacha20.function | 22 ++++----- tests/suites/test_suite_chachapoly.function | 54 ++++++++++----------- tests/suites/test_suite_poly1305.function | 16 +++--- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index 75d2d0fc9..9c0b98522 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -14,21 +14,21 @@ void chacha20_crypt( char *hex_key_string, char *hex_src_string, char *hex_dst_string ) { - unsigned char key_str[100]; - unsigned char nonce_str[100]; - unsigned char src_str[10000]; - unsigned char dst_str[10000]; - unsigned char output[10000]; + unsigned char key_str[32]; /* size set by the standard */ + unsigned char nonce_str[12]; /* size set by the standard */ + unsigned char src_str[375]; /* max size of binary input */ + unsigned char dst_str[751]; /* hex expansion of the above */ + unsigned char output[751]; size_t key_len; size_t nonce_len; size_t src_len; size_t dst_len; - memset(key_str, 0x00, 100); - memset(nonce_str, 0x00, 100); - memset(src_str, 0x00, 10000); - memset(dst_str, 0x00, 10000); - memset(output, 0x00, 10000); + memset( key_str, 0x00, sizeof( key_str ) ); + memset( nonce_str, 0x00, sizeof( nonce_str ) ); + memset( src_str, 0x00, sizeof( src_str ) ); + memset( dst_str, 0x00, sizeof( dst_str ) ); + memset( output, 0x00, sizeof( output ) ); key_len = unhexify( key_str, hex_key_string ); nonce_len = unhexify( nonce_str, hex_nonce_string ); @@ -52,4 +52,4 @@ void chacha20_self_test() { TEST_ASSERT( mbedtls_chacha20_self_test( 0 ) == 0 ); } -/* END_CASE */ \ No newline at end of file +/* END_CASE */ diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index b205c4ce0..3d6a2b6d1 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -10,14 +10,14 @@ /* BEGIN_CASE */ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) { - unsigned char key_str[32]; - unsigned char nonce_str[12]; - unsigned char aad_str[10000]; - unsigned char input_str[10000]; - unsigned char output_str[10000]; - unsigned char mac_str[16]; - unsigned char output[10000]; - unsigned char mac[16]; + unsigned char key_str[32]; /* size set by the standard */ + unsigned char nonce_str[12]; /* size set by the standard */ + unsigned char aad_str[12]; /* max size of test data so far */ + unsigned char input_str[265]; /* max size of binary input/output so far */ + unsigned char output_str[265]; + unsigned char output[265]; + unsigned char mac_str[16]; /* size set by the standard */ + unsigned char mac[16]; /* size set by the standard */ size_t input_len; size_t output_len; size_t aad_len; @@ -26,12 +26,12 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char size_t mac_len; mbedtls_chachapoly_context ctx; - memset( key_str, 0x00, 32 ); - memset( nonce_str, 0x00, 12 ); - memset( aad_str, 0x00, 10000 ); - memset( input_str, 0x00, 10000 ); - memset( output_str, 0x00, 10000 ); - memset( mac_str, 0x00, 16 ); + memset( key_str, 0x00, sizeof( key_str ) ); + memset( nonce_str, 0x00, sizeof( nonce_str ) ); + memset( aad_str, 0x00, sizeof( aad_str ) ); + memset( input_str, 0x00, sizeof( input_str ) ); + memset( output_str, 0x00, sizeof( output_str ) ); + memset( mac_str, 0x00, sizeof( mac_str ) ); aad_len = unhexify( aad_str, hex_aad_string ); input_len = unhexify( input_str, hex_input_string ); @@ -65,13 +65,13 @@ exit: /* BEGIN_CASE */ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) { - unsigned char key_str[32]; - unsigned char nonce_str[12]; - unsigned char aad_str[10000]; - unsigned char input_str[10000]; - unsigned char output_str[10000]; - unsigned char mac_str[16]; - unsigned char output[10000]; + unsigned char key_str[32]; /* size set by the standard */ + unsigned char nonce_str[12]; /* size set by the standard */ + unsigned char aad_str[12]; /* max size of test data so far */ + unsigned char input_str[265]; /* max size of binary input/output so far */ + unsigned char output_str[265]; + unsigned char output[265]; + unsigned char mac_str[16]; /* size set by the standard */ size_t input_len; size_t output_len; size_t aad_len; @@ -81,12 +81,12 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char int ret; mbedtls_chachapoly_context ctx; - memset( key_str, 0x00, 32 ); - memset( nonce_str, 0x00, 12 ); - memset( aad_str, 0x00, 10000 ); - memset( input_str, 0x00, 10000 ); - memset( output_str, 0x00, 10000 ); - memset( mac_str, 0x00, 16 ); + memset( key_str, 0x00, sizeof( key_str ) ); + memset( nonce_str, 0x00, sizeof( nonce_str ) ); + memset( aad_str, 0x00, sizeof( aad_str ) ); + memset( input_str, 0x00, sizeof( input_str ) ); + memset( output_str, 0x00, sizeof( output_str ) ); + memset( mac_str, 0x00, sizeof( mac_str ) ); aad_len = unhexify( aad_str, hex_aad_string ); input_len = unhexify( input_str, hex_input_string ); diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function index a633c2baa..5ede635c9 100644 --- a/tests/suites/test_suite_poly1305.function +++ b/tests/suites/test_suite_poly1305.function @@ -6,16 +6,16 @@ /* BEGIN_CASE depends_on:MBEDTLS_POLY1305_C */ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src_string ) { - unsigned char src_str[10000]; - unsigned char mac_str[100]; - unsigned char key[32]; - unsigned char mac[16]; + unsigned char src_str[375]; /* max size of binary input */ + unsigned char key[32]; /* size set by the standard */ + unsigned char mac[16]; /* size set by the standard */ + unsigned char mac_str[33]; /* hex expansion of the above */ size_t src_len; - memset(src_str, 0x00, 10000); - memset(mac_str, 0x00, 100); - memset(key, 0x00, 32); - memset(mac, 0x00, 16); + memset( src_str, 0x00, sizeof( src_str ) ); + memset( mac_str, 0x00, sizeof( mac_str ) ); + memset( key, 0x00, sizeof( key ) ); + memset( mac, 0x00, sizeof( mac ) ); src_len = unhexify( src_str, hex_src_string ); unhexify( key, hex_key_string ); From 2faaa10e68b134924f7b5ba6fa09be2ddf22591a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 12:22:13 +0200 Subject: [PATCH 30/42] chachapoly: add test with unauthentic data --- tests/suites/test_suite_chachapoly.data | 14 +++++++++++--- tests/suites/test_suite_chachapoly.function | 9 ++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_chachapoly.data b/tests/suites/test_suite_chachapoly.data index 08129aa37..f0b4a0de6 100644 --- a/tests/suites/test_suite_chachapoly.data +++ b/tests/suites/test_suite_chachapoly.data @@ -2,9 +2,13 @@ ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_enc:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" -ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) +ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Decrypt) depends_on:MBEDTLS_CHACHAPOLY_C -mbedtls_chachapoly_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600691" +mbedtls_chachapoly_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600691":0 + +ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Decrypt, not authentic) +depends_on:MBEDTLS_CHACHAPOLY_C +mbedtls_chachapoly_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600690":MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Encrypt) depends_on:MBEDTLS_CHACHAPOLY_C @@ -12,7 +16,11 @@ mbedtls_chachapoly_enc:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt) depends_on:MBEDTLS_CHACHAPOLY_C -mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"eead9d67890cbb22392336fea1851f38" +mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"eead9d67890cbb22392336fea1851f38":0 + +ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt, not authentic) +depends_on:MBEDTLS_CHACHAPOLY_C +mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"fead9d67890cbb22392336fea1851f38":MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ChaCha20-Poly1305 Selftest depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SELF_TEST diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index 3d6a2b6d1..a613870b3 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -63,7 +63,7 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string ) +void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char *hex_aad_string, char *hex_input_string, char *hex_output_string, char *hex_mac_string, int ret_exp ) { unsigned char key_str[32]; /* size set by the standard */ unsigned char nonce_str[12]; /* size set by the standard */ @@ -108,8 +108,11 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char aad_str, aad_len, mac_str, input_str, output ); - TEST_ASSERT( ret == 0 ); - TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); + TEST_ASSERT( ret == ret_exp ); + if( ret_exp == 0 ) + { + TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); + } exit: mbedtls_chachapoly_free( &ctx ); From b60045aacb1b365cd1d6d4e3e0c022bd36ff0642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 12:37:58 +0200 Subject: [PATCH 31/42] chacha20: fix bug in starts() and add test for it Previously the streaming API would fail when encrypting multiple messages with the same key. --- library/chacha20.c | 6 ++++ tests/suites/test_suite_chacha20.function | 37 ++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/library/chacha20.c b/library/chacha20.c index 5ede4553c..d89000da2 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -243,6 +243,12 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, ctx->initial_state[14] = BYTES_TO_U32_LE( nonce, 4 ); ctx->initial_state[15] = BYTES_TO_U32_LE( nonce, 8 ); + mbedtls_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); + mbedtls_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); + + /* Initially, there's no keystream bytes available */ + ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; + return( 0 ); } diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index 9c0b98522..fb3ad3e79 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -23,6 +23,7 @@ void chacha20_crypt( char *hex_key_string, size_t nonce_len; size_t src_len; size_t dst_len; + mbedtls_chacha20_context ctx; memset( key_str, 0x00, sizeof( key_str ) ); memset( nonce_str, 0x00, sizeof( nonce_str ) ); @@ -39,11 +40,45 @@ void chacha20_crypt( char *hex_key_string, TEST_ASSERT( key_len == 32U ); TEST_ASSERT( nonce_len == 12U ); + /* + * Test the integrated API + */ TEST_ASSERT( mbedtls_chacha20_crypt( key_str, nonce_str, counter, src_len, src_str, output ) == 0 ); hexify( dst_str, output, src_len ); + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 ); - TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0); + /* + * Test the streaming API + */ + mbedtls_chacha20_init( &ctx ); + + TEST_ASSERT( mbedtls_chacha20_setkey( &ctx, key_str ) == 0 ); + + TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 ); + + memset( output, 0x00, sizeof( output ) ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_len, src_str, output ) == 0 ); + + hexify( dst_str, output, src_len ); + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 ); + + /* + * Test the streaming API again, piecewise + */ + + /* Don't reset the context of key, in order to test that starts() do the + * right thing. */ + TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 ); + + memset( output, 0x00, sizeof( output ) ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, 1, src_str, output ) == 0 ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, src_len - 1, src_str + 1, output + 1 ) == 0 ); + + hexify( dst_str, output, src_len ); + TEST_ASSERT( strcmp( (char*) dst_str, hex_dst_string ) == 0 ); + + mbedtls_chacha20_free( &ctx ); } /* END_CASE */ From 97e34bf2f2fc29963b9d9b867f63fa5555a61db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 12:51:54 +0200 Subject: [PATCH 32/42] poly1305: fix bug in starts() and add test for it --- library/poly1305.c | 5 +++ tests/suites/test_suite_chacha20.function | 4 +-- tests/suites/test_suite_poly1305.function | 38 ++++++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/library/poly1305.c b/library/poly1305.c index 14c362d58..542a85004 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -280,6 +280,11 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, ctx->acc[1] = 0U; ctx->acc[2] = 0U; ctx->acc[3] = 0U; + ctx->acc[4] = 0U; + + /* Queue initially empty */ + mbedtls_zeroize( ctx->queue, sizeof( ctx->queue ) ); + ctx->queue_len = 0U; return( 0 ); } diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index fb3ad3e79..bac1ef3ca 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -67,8 +67,8 @@ void chacha20_crypt( char *hex_key_string, * Test the streaming API again, piecewise */ - /* Don't reset the context of key, in order to test that starts() do the - * right thing. */ + /* Don't free/init the context nor set the key again, + * in order to test that starts() does the right thing. */ TEST_ASSERT( mbedtls_chacha20_starts( &ctx, nonce_str, counter ) == 0 ); memset( output, 0x00, sizeof( output ) ); diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function index 5ede635c9..964d1297a 100644 --- a/tests/suites/test_suite_poly1305.function +++ b/tests/suites/test_suite_poly1305.function @@ -11,6 +11,7 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src unsigned char mac[16]; /* size set by the standard */ unsigned char mac_str[33]; /* hex expansion of the above */ size_t src_len; + mbedtls_poly1305_context ctx; memset( src_str, 0x00, sizeof( src_str ) ); memset( mac_str, 0x00, sizeof( mac_str ) ); @@ -20,10 +21,45 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src src_len = unhexify( src_str, hex_src_string ); unhexify( key, hex_key_string ); + /* + * Test the integrated API + */ mbedtls_poly1305_mac( key, src_str, src_len, mac ); - hexify( mac_str, mac, 16 ); + hexify( mac_str, mac, 16 ); TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); + + /* + * Test the streaming API + */ + mbedtls_poly1305_init( &ctx ); + + TEST_ASSERT( mbedtls_poly1305_starts( &ctx, key ) == 0 ); + + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str, src_len ) == 0 ); + + TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 ); + + hexify( mac_str, mac, 16 ); + TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); + + /* + * Test the streaming API again, piecewise + */ + + /* Don't free/init the context, in order to test that starts() does the + * right thing. */ + TEST_ASSERT( mbedtls_poly1305_starts( &ctx, key ) == 0 ); + + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str, 1 ) == 0 ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str + 1, src_len - 1) == 0 ); + + TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 ); + + hexify( mac_str, mac, 16 ); + TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); + + mbedtls_poly1305_free( &ctx ); } /* END_CASE */ From 996477d84bd48057c8447e4c305c72f72231805f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 12:25:18 +0200 Subject: [PATCH 33/42] cipher: add chachapoly test vector + unauth case --- tests/suites/test_suite_cipher.chachapoly.data | 8 ++++++++ tests/suites/test_suite_cipher.function | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_cipher.chachapoly.data b/tests/suites/test_suite_cipher.chachapoly.data index de5b3d648..d91dc2432 100644 --- a/tests/suites/test_suite_cipher.chachapoly.data +++ b/tests/suites/test_suite_cipher.chachapoly.data @@ -109,3 +109,11 @@ enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:6:16:-1:6:16:6:16 ChaCha20+Poly1305 Encrypt and decrypt 32 bytes in multiple parts depends_on:MBEDTLS_CHACHAPOLY_C enc_dec_buf_multipart:MBEDTLS_CIPHER_CHACHA20_POLY1305:256:16:16:-1:16:16:16:16 + +ChaCha20+Poly1305 RFC 7539 Test Vector #1 +depends_on:MBEDTLS_CHACHAPOLY_C +auth_crypt_tv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d" + +ChaCha20+Poly1305 RFC 7539 Test Vector #1 Unauthentic (1st bit flipped) +depends_on:MBEDTLS_CHACHAPOLY_C +auth_crypt_tv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"6ead9d67890cbb22392336fea1851f38":"FAIL" diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index 92462e52b..e4b7e4365 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -560,14 +560,14 @@ void auth_crypt_tv( int cipher_id, char *hex_key, char *hex_iv, int ret; unsigned char key[50]; unsigned char iv[50]; - unsigned char cipher[200]; - unsigned char clear[200]; + unsigned char cipher[265]; /* max size of test data so far */ + unsigned char clear[265]; + unsigned char output[267]; /* above + 2 (overwrite check) */ unsigned char ad[200]; unsigned char tag[20]; unsigned char my_tag[20]; size_t key_len, iv_len, cipher_len, clear_len, ad_len, tag_len; mbedtls_cipher_context_t ctx; - unsigned char output[200]; size_t outlen; mbedtls_cipher_init( &ctx ); From e9ea6d6e11b2a71dce2afc661750a8e2b72ebad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Wed, 9 May 2018 13:06:12 +0200 Subject: [PATCH 34/42] Fix selftest verbosity in test suites --- tests/suites/test_suite_chacha20.function | 2 +- tests/suites/test_suite_poly1305.function | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index bac1ef3ca..124e51003 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -85,6 +85,6 @@ void chacha20_crypt( char *hex_key_string, /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void chacha20_self_test() { - TEST_ASSERT( mbedtls_chacha20_self_test( 0 ) == 0 ); + TEST_ASSERT( mbedtls_chacha20_self_test( 1 ) == 0 ); } /* END_CASE */ diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function index 964d1297a..682eb05aa 100644 --- a/tests/suites/test_suite_poly1305.function +++ b/tests/suites/test_suite_poly1305.function @@ -66,6 +66,6 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src /* BEGIN_CASE depends_on:MBEDTLS_POLY1305_C:MBEDTLS_SELF_TEST */ void poly1305_selftest() { - TEST_ASSERT( mbedtls_poly1305_self_test( 0 ) == 0 ); + TEST_ASSERT( mbedtls_poly1305_self_test( 1 ) == 0 ); } /* END_CASE */ From 114f28b3d9b8f032fffca38967874e894a7cd9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 10:11:42 +0200 Subject: [PATCH 35/42] chacha20: add test for parameter validation --- tests/suites/test_suite_chacha20.data | 3 ++ tests/suites/test_suite_chacha20.function | 50 +++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/tests/suites/test_suite_chacha20.data b/tests/suites/test_suite_chacha20.data index 86094604b..3f9033eeb 100644 --- a/tests/suites/test_suite_chacha20.data +++ b/tests/suites/test_suite_chacha20.data @@ -22,5 +22,8 @@ chacha20_crypt:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0 ChaCha20 RFC 7539 Test Vector #3 (Decrypt) chacha20_crypt:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000000000000000002":42:"62e6347f95ed87a45ffae7426f27a1df5fb69110044c0d73118effa95b01e5cf166d3df2d721caf9b21e5fb14c616871fd84c54f9d65b283196c7fe4f60553ebf39c6402c42234e32a356b3e764312a61a5532055716ead6962568f87d3f3f7704c6a8d1bcd1bf4d50d6154b6da731b187b58dfd728afa36757a797ac188d1":"2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e" +ChaCha20 Paremeter Validation +chacha20_bad_params: + ChaCha20 Selftest chacha20_self_test: diff --git a/tests/suites/test_suite_chacha20.function b/tests/suites/test_suite_chacha20.function index 124e51003..669d91e79 100644 --- a/tests/suites/test_suite_chacha20.function +++ b/tests/suites/test_suite_chacha20.function @@ -82,6 +82,56 @@ void chacha20_crypt( char *hex_key_string, } /* END_CASE */ +/* BEGIN_CASE */ +void chacha20_bad_params() +{ + unsigned char key[32]; + unsigned char nonce[12]; + unsigned char src[1]; + unsigned char dst[1]; + uint32_t counter = 0; + size_t len = sizeof( src ); + mbedtls_chacha20_context ctx; + + mbedtls_chacha20_init( NULL ); + mbedtls_chacha20_free( NULL ); + + mbedtls_chacha20_init( &ctx ); + + TEST_ASSERT( mbedtls_chacha20_setkey( NULL, key ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_setkey( &ctx, NULL ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chacha20_starts( NULL, nonce, counter ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_starts( &ctx, NULL, counter ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chacha20_update( NULL, 0, src, dst ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, len, NULL, dst ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, len, src, NULL ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_update( &ctx, 0, NULL, NULL ) + == 0 ); + + mbedtls_chacha20_free( &ctx ); + + TEST_ASSERT( mbedtls_chacha20_crypt( NULL, nonce, counter, 0, src, dst ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_crypt( key, NULL, counter, 0, src, dst ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_crypt( key, nonce, counter, len, NULL, dst ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_crypt( key, nonce, counter, len, src, NULL ) + == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chacha20_crypt( key, nonce, counter, 0, NULL, NULL ) + == 0 ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void chacha20_self_test() { From 550c20fcf955b94e36762072935682415fde9660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 10:12:36 +0200 Subject: [PATCH 36/42] poly1305: add test for parameter validation Also fix two validation bugs found while adding the tests. Also handle test dependencies the right way while at it. --- library/poly1305.c | 4 +- tests/suites/test_suite_poly1305.data | 17 ++----- tests/suites/test_suite_poly1305.function | 55 +++++++++++++++++++++-- 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/library/poly1305.c b/library/poly1305.c index 542a85004..0aa453356 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -259,7 +259,7 @@ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, const unsigned char key[32] ) { - if ( ctx == NULL ) + if ( ctx == NULL || key == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } @@ -417,7 +417,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32], cleanup: mbedtls_poly1305_free( &ctx ); - return( 0 ); + return( result ); } #endif /* MBEDTLS_POLY1305_ALT */ diff --git a/tests/suites/test_suite_poly1305.data b/tests/suites/test_suite_poly1305.data index f259e848b..13912e997 100644 --- a/tests/suites/test_suite_poly1305.data +++ b/tests/suites/test_suite_poly1305.data @@ -1,51 +1,42 @@ Poly1305 RFC 7539 Example And Test Vector -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b":"a8061dc1305136c6c22b8baf0c0127a9":"43727970746f6772617068696320466f72756d2052657365617263682047726f7570" Poly1305 RFC 7539 Test Vector #1 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0000000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" Poly1305 RFC 7539 Test Vector #2 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e":"36e5f6b5c5e06070f0efca96227a863e":"416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f" Poly1305 RFC 7539 Test Vector #3 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000":"f3477e7cd95417af89a6b8794c310cf0":"416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f" Poly1305 RFC 7539 Test Vector #4 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"4541669a7eaaee61e708dc7cbcc5eb62":"2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e" Poly1305 RFC 7539 Test Vector #5 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0200000000000000000000000000000000000000000000000000000000000000":"03000000000000000000000000000000":"ffffffffffffffffffffffffffffffff" Poly1305 RFC 7539 Test Vector #6 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"02000000000000000000000000000000ffffffffffffffffffffffffffffffff":"03000000000000000000000000000000":"02000000000000000000000000000000" Poly1305 RFC 7539 Test Vector #7 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0100000000000000000000000000000000000000000000000000000000000000":"05000000000000000000000000000000":"fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000" Poly1305 RFC 7539 Test Vector #8 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0100000000000000000000000000000000000000000000000000000000000000":"00000000000000000000000000000000":"fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101" Poly1305 RFC 7539 Test Vector #9 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0200000000000000000000000000000000000000000000000000000000000000":"faffffffffffffffffffffffffffffff":"fdffffffffffffffffffffffffffffff" Poly1305 RFC 7539 Test Vector #10 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0100000000000000040000000000000000000000000000000000000000000000":"14000000000000005500000000000000":"e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000" Poly1305 RFC 7539 Test Vector #11 -depends_on:MBEDTLS_POLY1305_C mbedtls_poly1305:"0100000000000000040000000000000000000000000000000000000000000000":"13000000000000000000000000000000":"e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000" +Poly1305 Parameter validation +poly1305_bad_params: + Poly1305 Selftest -depends_on:MBEDTLS_SELF_TEST:MBEDTLS_POLY1305_C +depends_on:MBEDTLS_SELF_TEST poly1305_selftest: diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function index 682eb05aa..c5e7989fe 100644 --- a/tests/suites/test_suite_poly1305.function +++ b/tests/suites/test_suite_poly1305.function @@ -3,7 +3,12 @@ #include /* END_HEADER */ -/* BEGIN_CASE depends_on:MBEDTLS_POLY1305_C */ +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_POLY1305_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src_string ) { unsigned char src_str[375]; /* max size of binary input */ @@ -24,7 +29,7 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src /* * Test the integrated API */ - mbedtls_poly1305_mac( key, src_str, src_len, mac ); + TEST_ASSERT( mbedtls_poly1305_mac( key, src_str, src_len, mac ) == 0 ); hexify( mac_str, mac, 16 ); TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); @@ -63,7 +68,51 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src } /* END_CASE */ -/* BEGIN_CASE depends_on:MBEDTLS_POLY1305_C:MBEDTLS_SELF_TEST */ +/* BEGIN_CASE */ +void poly1305_bad_params() +{ + unsigned char src[1]; + unsigned char key[32]; + unsigned char mac[16]; + size_t src_len = sizeof( src ); + mbedtls_poly1305_context ctx; + + mbedtls_poly1305_init( NULL ); + mbedtls_poly1305_free( NULL ); + + mbedtls_poly1305_init( &ctx ); + + TEST_ASSERT( mbedtls_poly1305_starts( NULL, key ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_starts( &ctx, NULL ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_poly1305_update( NULL, src, 0 ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, NULL, src_len ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, NULL, 0 ) + == 0 ); + + TEST_ASSERT( mbedtls_poly1305_finish( NULL, mac ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_finish( &ctx, NULL ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_poly1305_mac( NULL, src, 0, mac ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_mac( key, NULL, src_len, mac ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_mac( key, src, 0, NULL ) + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_poly1305_mac( key, NULL, 0, mac ) + == 0 ); + + mbedtls_poly1305_free( &ctx ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void poly1305_selftest() { TEST_ASSERT( mbedtls_poly1305_self_test( 1 ) == 0 ); From 6dbfb69c129c9e93cad384c5fb6c14f25a4b7455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 10:39:32 +0200 Subject: [PATCH 37/42] chachapoly: add test for parameter validation Also fix two bugs found by the new tests. Also remove redundant test case dependency declarations while at it. --- library/chachapoly.c | 5 +- tests/suites/test_suite_chachapoly.data | 11 +- tests/suites/test_suite_chachapoly.function | 157 +++++++++++++++++++- 3 files changed, 161 insertions(+), 12 deletions(-) diff --git a/library/chachapoly.c b/library/chachapoly.c index 9ca21b39a..fd05886fb 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -202,7 +202,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, const unsigned char *input, unsigned char *output ) { - if ( ( ctx == NULL ) || ( input == NULL ) || ( output == NULL ) ) + if ( ctx == NULL ) { return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); } @@ -339,6 +339,9 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, size_t i; int diff; + if( tag == NULL ) + return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + if( ( ret = mbedtls_chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, aad, aad_len, input, output, check_tag ) ) != 0 ) diff --git a/tests/suites/test_suite_chachapoly.data b/tests/suites/test_suite_chachapoly.data index f0b4a0de6..b0eedea27 100644 --- a/tests/suites/test_suite_chachapoly.data +++ b/tests/suites/test_suite_chachapoly.data @@ -1,27 +1,24 @@ ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Encrypt) -depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_enc:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"1ae10b594f09e26a7e902ecbd0600691" ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Decrypt) -depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600691":0 ChaCha20-Poly1305 RFC 7539 Example and Test Vector (Decrypt, not authentic) -depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_dec:"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f":"070000004041424344454647":"50515253c0c1c2c3c4c5c6c7":"d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116":"4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e":"1ae10b594f09e26a7e902ecbd0600690":MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Encrypt) -depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_enc:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"eead9d67890cbb22392336fea1851f38" ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt) -depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"eead9d67890cbb22392336fea1851f38":0 ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt, not authentic) -depends_on:MBEDTLS_CHACHAPOLY_C mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"fead9d67890cbb22392336fea1851f38":MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED +ChaCha20-Poly1305 Parameter Validation +chachapoly_bad_params: + ChaCha20-Poly1305 Selftest -depends_on:MBEDTLS_CHACHAPOLY_C:MBEDTLS_SELF_TEST +depends_on:MBEDTLS_SELF_TEST chachapoly_selftest: diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index a613870b3..3f8145a54 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -46,13 +46,13 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char mbedtls_chachapoly_init( &ctx ); - mbedtls_chachapoly_setkey( &ctx, key_str ); + TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key_str ) == 0 ); - mbedtls_chachapoly_crypt_and_tag( &ctx, + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, input_len, nonce_str, aad_str, aad_len, - input_str, output, mac ); + input_str, output, mac ) == 0 ); TEST_ASSERT( memcmp( output_str, output, output_len ) == 0 ); TEST_ASSERT( memcmp( mac_str, mac, 16U ) == 0 ); @@ -101,7 +101,7 @@ void mbedtls_chachapoly_dec( char *hex_key_string, char *hex_nonce_string, char mbedtls_chachapoly_init( &ctx ); - mbedtls_chachapoly_setkey( &ctx, key_str ); + TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key_str ) == 0 ); ret = mbedtls_chachapoly_auth_decrypt( &ctx, input_len, nonce_str, @@ -119,6 +119,155 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void chachapoly_bad_params() +{ + unsigned char key[32]; + unsigned char nonce[12]; + unsigned char aad[1]; + unsigned char input[1]; + unsigned char output[1]; + unsigned char mac[16]; + size_t input_len = sizeof( input ); + size_t aad_len = sizeof( aad ); + mbedtls_chachapoly_context ctx; + + memset( key, 0x00, sizeof( key ) ); + memset( nonce, 0x00, sizeof( nonce ) ); + memset( aad, 0x00, sizeof( aad ) ); + memset( input, 0x00, sizeof( input ) ); + memset( output, 0x00, sizeof( output ) ); + memset( mac, 0x00, sizeof( mac ) ); + + mbedtls_chachapoly_init( NULL ); + mbedtls_chachapoly_free( NULL ); + + mbedtls_chachapoly_init( &ctx ); + + TEST_ASSERT( mbedtls_chachapoly_setkey( NULL, key ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, NULL ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( NULL, + MBEDTLS_CHACHAPOLY_ENCRYPT, + 0, nonce, + aad, 0, + input, output, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + 0, NULL, + aad, 0, + input, output, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + 0, nonce, + NULL, aad_len, + input, output, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + input_len, nonce, + aad, 0, + NULL, output, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + input_len, nonce, + aad, 0, + input, NULL, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + 0, nonce, + aad, 0, + input, output, NULL ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( NULL, + 0, nonce, + aad, 0, + mac, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + 0, NULL, + aad, 0, + mac, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + 0, nonce, + NULL, aad_len, + mac, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + 0, nonce, + aad, 0, + NULL, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + input_len, nonce, + aad, 0, + mac, NULL, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + input_len, nonce, + aad, 0, + mac, input, NULL ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + 0, nonce, + aad, aad_len, + NULL, NULL, mac ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + 0, nonce, + aad, aad_len, + mac, NULL, NULL ) + == 0 ); + + TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + input_len, nonce, + NULL, 0, + input, output, mac ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, + input_len, nonce, + NULL, 0, + mac, input, output ) + == 0 ); + + TEST_ASSERT( mbedtls_chachapoly_starts( NULL, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, NULL, MBEDTLS_CHACHAPOLY_ENCRYPT ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chachapoly_update_aad( NULL, aad, aad_len ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, NULL, aad_len ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chachapoly_update( NULL, input_len, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, NULL, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, NULL ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + + TEST_ASSERT( mbedtls_chachapoly_finish( NULL, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, NULL ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + +exit: + mbedtls_chachapoly_free( &ctx ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void chachapoly_selftest() { From 7a2c7f147559007e2403e30822e14a2cb817fab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 11:06:46 +0200 Subject: [PATCH 38/42] poly1305: add test with multiple small fragments This exercises the code path where data is just appended to the waiting queue while it isn't empty. --- tests/suites/test_suite_poly1305.function | 32 ++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_poly1305.function b/tests/suites/test_suite_poly1305.function index c5e7989fe..62d2ad951 100644 --- a/tests/suites/test_suite_poly1305.function +++ b/tests/suites/test_suite_poly1305.function @@ -54,15 +54,35 @@ void mbedtls_poly1305( char *hex_key_string, char *hex_mac_string, char *hex_src /* Don't free/init the context, in order to test that starts() does the * right thing. */ - TEST_ASSERT( mbedtls_poly1305_starts( &ctx, key ) == 0 ); + if( src_len >= 1 ) + { + TEST_ASSERT( mbedtls_poly1305_starts( &ctx, key ) == 0 ); - TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str, 1 ) == 0 ); - TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str + 1, src_len - 1) == 0 ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str, 1 ) == 0 ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str + 1, src_len - 1 ) == 0 ); - TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 ); + TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 ); - hexify( mac_str, mac, 16 ); - TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); + hexify( mac_str, mac, 16 ); + TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); + } + + /* + * Again with more pieces + */ + if( src_len >= 2 ) + { + TEST_ASSERT( mbedtls_poly1305_starts( &ctx, key ) == 0 ); + + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str, 1 ) == 0 ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str + 1, 1 ) == 0 ); + TEST_ASSERT( mbedtls_poly1305_update( &ctx, src_str + 2, src_len - 2 ) == 0 ); + + TEST_ASSERT( mbedtls_poly1305_finish( &ctx, mac ) == 0 ); + + hexify( mac_str, mac, 16 ); + TEST_ASSERT( strcmp( (char *) mac_str, hex_mac_string ) == 0 ); + } mbedtls_poly1305_free( &ctx ); } From 619b3092c284c793a26be4fa0cd2014223c5ffe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 11:41:00 +0200 Subject: [PATCH 39/42] chachapoly: add test for state flow --- tests/suites/test_suite_chachapoly.data | 3 + tests/suites/test_suite_chachapoly.function | 80 +++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/tests/suites/test_suite_chachapoly.data b/tests/suites/test_suite_chachapoly.data index b0eedea27..34cb56831 100644 --- a/tests/suites/test_suite_chachapoly.data +++ b/tests/suites/test_suite_chachapoly.data @@ -16,6 +16,9 @@ mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc ChaCha20-Poly1305 RFC 7539 Test Vector #1 (Decrypt, not authentic) mbedtls_chachapoly_dec:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"fead9d67890cbb22392336fea1851f38":MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED +ChaCha20-Poly1305 State Flow +chachapoly_state: + ChaCha20-Poly1305 Parameter Validation chachapoly_bad_params: diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index 3f8145a54..e379309cd 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -268,6 +268,86 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void chachapoly_state() +{ + unsigned char key[32]; + unsigned char nonce[12]; + unsigned char aad[1]; + unsigned char input[1]; + unsigned char output[1]; + unsigned char mac[16]; + size_t input_len = sizeof( input ); + size_t aad_len = sizeof( aad ); + mbedtls_chachapoly_context ctx; + + memset( key, 0x00, sizeof( key ) ); + memset( nonce, 0x00, sizeof( nonce ) ); + memset( aad, 0x00, sizeof( aad ) ); + memset( input, 0x00, sizeof( input ) ); + memset( output, 0x00, sizeof( output ) ); + memset( mac, 0x00, sizeof( mac ) ); + + /* Initial state: finish, update, update_aad forbidden */ + mbedtls_chachapoly_init( &ctx ); + + TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + + /* Still initial state: finish, update, update_aad forbidden */ + TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key ) + == 0 ); + + TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + + /* Starts -> finish OK */ + TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac ) + == 0 ); + + /* After finish: update, update_aad forbidden */ + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + + /* Starts -> update* OK */ + TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, output ) + == 0 ); + + /* After update: update_aad forbidden */ + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len ) + == MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + + /* Starts -> update_aad* -> finish OK */ + TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, aad, aad_len ) + == 0 ); + TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, mac ) + == 0 ); + +exit: + mbedtls_chachapoly_free( &ctx ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ void chachapoly_selftest() { From 53502519779470236af938911736e912ade8bda3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 11:42:07 +0200 Subject: [PATCH 40/42] Simplify selftest functions using macros This reduces clutter, making the functions more readable. Also, it makes lcov see each line as covered. This is not cheating, as the lines that were previously seen as not covered are not supposed to be reached anyway (failing branches of the selftests). Thanks to this and previous test suite enhancements, lcov now sees chacha20.c and poly1305.c at 100% line coverage, and for chachapoly.c only two lines are not covered (error returns from lower-level module that should never happen except perhaps if an alternative implementation returns an unexpected error). --- library/chacha20.c | 45 +++++++++++++------------------ library/chachapoly.c | 64 ++++++++++++++++---------------------------- library/poly1305.c | 45 +++++++++++++------------------ 3 files changed, 60 insertions(+), 94 deletions(-) diff --git a/library/chacha20.c b/library/chacha20.c index d89000da2..5a753ebaa 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -519,18 +519,29 @@ static const size_t test_lengths[2] = 375U }; +#define ASSERT( cond, args ) \ + do \ + { \ + if( ! ( cond ) ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf args; \ + \ + return( -1 ); \ + } \ + } \ + while( 0 ) + int mbedtls_chacha20_self_test( int verbose ) { unsigned char output[381]; unsigned i; int result; - for ( i = 0U; i < 2U; i++ ) + for( i = 0U; i < 2U; i++ ) { - if ( verbose != 0 ) - { + if( verbose != 0 ) mbedtls_printf( " ChaCha20 test %u ", i ); - } result = mbedtls_chacha20_crypt( test_keys[i], test_nonces[i], @@ -538,36 +549,18 @@ int mbedtls_chacha20_self_test( int verbose ) test_lengths[i], test_input[i], output ); - if ( result != 0) - { - if ( verbose != 0 ) - { - mbedtls_printf( "error code: %i\n", result ); - } - return( -1 ); - } + ASSERT( 0 == result, ( "error code: %i\n", result ) ); - if ( 0 != memcmp( output, test_output[i], test_lengths[i] ) ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "failed\n" ); - } + ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ), + ( "failed (output)\n" ) ); - return( -1 ); - } - - if ( verbose != 0 ) - { + if( verbose != 0 ) mbedtls_printf( "passed\n" ); - } } if( verbose != 0 ) - { mbedtls_printf( "\n" ); - } return( 0 ); } diff --git a/library/chachapoly.c b/library/chachapoly.c index fd05886fb..ebf25bbbb 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -452,6 +452,19 @@ static const unsigned char test_mac[1][16] = } }; +#define ASSERT( cond, args ) \ + do \ + { \ + if( ! ( cond ) ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf args; \ + \ + return( -1 ); \ + } \ + } \ + while( 0 ) + int mbedtls_chachapoly_self_test( int verbose ) { mbedtls_chachapoly_context ctx; @@ -460,24 +473,15 @@ int mbedtls_chachapoly_self_test( int verbose ) unsigned char output[200]; unsigned char mac[16]; - for ( i = 0U; i < 1U; i++ ) + for( i = 0U; i < 1U; i++ ) { - if ( verbose != 0 ) - { + if( verbose != 0 ) mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); - } mbedtls_chachapoly_init( &ctx ); result = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); - if ( result != 0 ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "setkey() error code: %i\n", result ); - } - return( -1 ); - } + ASSERT( 0 == result, ( "setkey() error code: %i\n", result ) ); result = mbedtls_chachapoly_crypt_and_tag( &ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, @@ -488,45 +492,23 @@ int mbedtls_chachapoly_self_test( int verbose ) test_input[i], output, mac ); - if ( result != 0 ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "crypt_and_tag() error code: %i\n", result ); - } - return( -1 ); - } - if ( memcmp( output, test_output[i], test_input_len[i] ) != 0 ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "failure (wrong output)\n" ); - } - return( -1 ); - } + ASSERT( 0 == result, ( "crypt_and_tag() error code: %i\n", result ) ); - if ( memcmp( mac, test_mac[i], 16U ) != 0 ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "failure (wrong MAC)\n" ); - } - return( -1 ); - } + ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ), + ( "failure (wrong output)\n" ) ); + + ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), + ( "failure (wrong MAC)\n" ) ); mbedtls_chachapoly_free( &ctx ); - if ( verbose != 0 ) - { + if( verbose != 0 ) mbedtls_printf( "passed\n" ); - } } if( verbose != 0 ) - { mbedtls_printf( "\n" ); - } return( 0 ); } diff --git a/library/poly1305.c b/library/poly1305.c index 0aa453356..a9fff4757 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -487,53 +487,44 @@ static const unsigned char test_mac[2][16] = } }; +#define ASSERT( cond, args ) \ + do \ + { \ + if( ! ( cond ) ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf args; \ + \ + return( -1 ); \ + } \ + } \ + while( 0 ) + int mbedtls_poly1305_self_test( int verbose ) { unsigned char mac[16]; unsigned i; int result; - for ( i = 0U; i < 2U; i++ ) + for( i = 0U; i < 2U; i++ ) { - if ( verbose != 0 ) - { + if( verbose != 0 ) mbedtls_printf( " Poly1305 test %u ", i ); - } result = mbedtls_poly1305_mac( test_keys[i], test_data[i], test_data_len[i], mac ); - if ( result != 0 ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "error code: %i\n", result ); - } + ASSERT( 0 == result, ( "error code: %i\n", result ) ); - return( -1 ); - } + ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) ); - if ( memcmp( mac, test_mac[i], 16U ) != 0 ) - { - if ( verbose != 0 ) - { - mbedtls_printf( "failed\n" ); - } - - return( -1 ); - } - - if ( verbose != 0 ) - { + if( verbose != 0 ) mbedtls_printf( "passed\n" ); - } } if( verbose != 0 ) - { mbedtls_printf( "\n" ); - } return( 0 ); } From e363ac78ec2526d27f4c9feef8f6d4b052e6623b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 12:30:19 +0200 Subject: [PATCH 41/42] cipher: handle ChaCha20 as a stream cipher That's what it is. So we shouldn't set a block size != 1. While at it, move call to chachapoly_update() closer to the one for GCM, as they are similar (AEAD). --- include/mbedtls/cipher.h | 2 +- library/cipher.c | 34 +++++++++------------------------- library/cipher_wrap.c | 21 +++++++++++++++++---- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index 591aa79aa..1ae847d20 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -193,7 +193,7 @@ enum { /** Maximum length of any IV, in Bytes. */ #define MBEDTLS_MAX_IV_LENGTH 16 /** Maximum block size of any cipher, in Bytes. */ -#define MBEDTLS_MAX_BLOCK_LENGTH 64 +#define MBEDTLS_MAX_BLOCK_LENGTH 16 /** * Base cipher information (opaque struct). diff --git a/library/cipher.c b/library/cipher.c index 2463a6148..cf10094f6 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -367,6 +367,15 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) + { + *olen = ilen; + return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ilen, input, output ); + } +#endif + if ( 0 == block_size ) { return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; @@ -378,31 +387,6 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } - -#if defined(MBEDTLS_CHACHA20_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20 ) - { - *olen = ilen; - return mbedtls_chacha20_update( (mbedtls_chacha20_context*) ctx->cipher_ctx, - ilen, input, output ); - } -#endif - - if( input == output && - ( ctx->unprocessed_len != 0 || ilen % mbedtls_cipher_get_block_size( ctx ) ) ) - { - return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - } - -#if defined(MBEDTLS_CHACHAPOLY_C) - if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) - { - *olen = ilen; - return mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, - ilen, input, output ); - } -#endif - #if defined(MBEDTLS_CIPHER_MODE_CBC) if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) { diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index 5c8082850..9110b968c 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -1305,6 +1305,19 @@ static int chacha20_setkey_wrap( void *ctx, const unsigned char *key, return( 0 ); } +static int chacha20_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + + ret = mbedtls_chacha20_update( ctx, length, input, output ); + if( ret == MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( ret ); +} + static void * chacha20_ctx_alloc( void ) { mbedtls_chacha20_context *ctx; @@ -1337,7 +1350,7 @@ static const mbedtls_cipher_base_t chacha20_base_info = { NULL, #endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) - NULL, + chacha20_stream_wrap, #endif chacha20_setkey_wrap, chacha20_setkey_wrap, @@ -1346,12 +1359,12 @@ static const mbedtls_cipher_base_t chacha20_base_info = { }; static const mbedtls_cipher_info_t chacha20_info = { MBEDTLS_CIPHER_CHACHA20, - MBEDTLS_MODE_NONE, + MBEDTLS_MODE_STREAM, 256, "CHACHA20", 12, 0, - 64, + 1, &chacha20_base_info }; #endif /* MBEDTLS_CHACHA20_C */ @@ -1417,7 +1430,7 @@ static const mbedtls_cipher_info_t chachapoly_info = { "CHACHA20-POLY1305", 12, 0, - 64, + 1, &chachapoly_base_info }; #endif /* MBEDTLS_CHACHAPOLY_C */ From f66a4bd11d3b672e577838569001c3060423585d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 10 May 2018 12:54:32 +0200 Subject: [PATCH 42/42] cipher: add stream test vectors for chacha20(poly1305) --- tests/suites/test_suite_cipher.chacha20.data | 6 +++++- tests/suites/test_suite_cipher.chachapoly.data | 4 ++++ tests/suites/test_suite_cipher.function | 6 +++--- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_cipher.chacha20.data b/tests/suites/test_suite_cipher.chacha20.data index 5f3e07d0b..c67e582e7 100644 --- a/tests/suites/test_suite_cipher.chacha20.data +++ b/tests/suites/test_suite_cipher.chacha20.data @@ -1,7 +1,11 @@ Decrypt empty buffer -depends_on:MBEDTLS_CHACHA20_C: +depends_on:MBEDTLS_CHACHA20_C dec_empty_buf: +Chacha20 RFC 7539 Test Vector #1 +depends_on:MBEDTLS_CHACHA20_C +decrypt_test_vec:MBEDTLS_CIPHER_CHACHA20:-1:"0000000000000000000000000000000000000000000000000000000000000000":"000000000000000000000000":"76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586":"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000":"":"":0:0 + ChaCha20 Encrypt and decrypt 0 bytes depends_on:MBEDTLS_CHACHA20_C enc_dec_buf:MBEDTLS_CIPHER_CHACHA20:"CHACHA20":256:0:-1 diff --git a/tests/suites/test_suite_cipher.chachapoly.data b/tests/suites/test_suite_cipher.chachapoly.data index d91dc2432..1760dc09d 100644 --- a/tests/suites/test_suite_cipher.chachapoly.data +++ b/tests/suites/test_suite_cipher.chachapoly.data @@ -117,3 +117,7 @@ auth_crypt_tv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"1c9240a5eb55d38af333888604f6b5f0 ChaCha20+Poly1305 RFC 7539 Test Vector #1 Unauthentic (1st bit flipped) depends_on:MBEDTLS_CHACHAPOLY_C auth_crypt_tv:MBEDTLS_CIPHER_CHACHA20_POLY1305:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"f33388860000000000004e91":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"6ead9d67890cbb22392336fea1851f38":"FAIL" + +Chacha20+Poly1305 RFC 7539 Test Vector #1 (streaming) +depends_on:MBEDTLS_CHACHAPOLY_C +decrypt_test_vec:MBEDTLS_CIPHER_CHACHA20_POLY1305:-1:"1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0":"000000000102030405060708":"64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b":"496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d":"f33388860000000000004e91":"eead9d67890cbb22392336fea1851f38":0:0 diff --git a/tests/suites/test_suite_cipher.function b/tests/suites/test_suite_cipher.function index e4b7e4365..b7037a068 100644 --- a/tests/suites/test_suite_cipher.function +++ b/tests/suites/test_suite_cipher.function @@ -479,8 +479,9 @@ void decrypt_test_vec( int cipher_id, int pad_mode, { unsigned char key[50]; unsigned char iv[50]; - unsigned char cipher[200]; - unsigned char clear[200]; + unsigned char cipher[265]; /* max length of test data so far */ + unsigned char clear[265]; + unsigned char output[265]; unsigned char ad[200]; unsigned char tag[20]; size_t key_len, iv_len, cipher_len, clear_len; @@ -488,7 +489,6 @@ void decrypt_test_vec( int cipher_id, int pad_mode, size_t ad_len, tag_len; #endif mbedtls_cipher_context_t ctx; - unsigned char output[200]; size_t outlen, total_len; mbedtls_cipher_init( &ctx );