From 34b822ce7b1f8765356c189d5a926970af090686 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Sun, 15 May 2016 17:28:08 -0300 Subject: [PATCH 01/63] 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 00000000..ab10a96a --- /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 7c9acb23..4c8fc3c3 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 8b4d3a87..ace0c47a 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 6177ca2b..78bab7fc 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 b155c720..4fab5984 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 00000000..75fd9e91 --- /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 222d85b6..2aaf359e 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 a452caf5..febd506b 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 cecf3e36..bc473cf8 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 ac0fbff0..36ee60b7 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 16e19a92..1525bc2a 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 d85617fd..233259b7 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 00000000..79f0408a --- /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 00000000..2825a614 --- /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 bd92062269997a882e6214360da21307fc0bae9b Mon Sep 17 00:00:00 2001 From: Daniel King Date: Sun, 15 May 2016 19:56:20 -0300 Subject: [PATCH 02/63] 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 ab10a96a..d23618ee 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 3ee2ab7d..c5a50c0d 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 75fd9e91..8206a3bf 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 a5cd61cd..68d0c10f 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 dc76af8f..f4e7964d 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 1525bc2a..3821657a 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 233259b7..34a0a891 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 00000000..5f3e07d0 --- /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 adc32c0b507e706b076b0978d63d8c5d99cbd474 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Mon, 16 May 2016 18:25:45 -0300 Subject: [PATCH 03/63] 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 4c8fc3c3..7d0960a2 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 ace0c47a..feeda79e 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 00000000..1aa55aee --- /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 78bab7fc..251b6c62 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 4fab5984..5fd693b2 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 2aaf359e..12bd2101 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 00000000..9a61a85c --- /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 febd506b..babf2c78 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 bc473cf8..c4196658 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 36ee60b7..1dac39bf 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 3821657a..82f15541 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 34a0a891..90b2028f 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 00000000..f259e848 --- /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 00000000..af69a031 --- /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 b8025c58265e3fe89d123900477818c57b94434c Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 17 May 2016 14:43:01 -0300 Subject: [PATCH 04/63] 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 00000000..a1ccf319 --- /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 d23618ee..ab87f66b 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 7d0960a2..22d465cd 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 feeda79e..72b7f18f 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 251b6c62..b8f663d9 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 5fd693b2..de4bd5c4 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 00000000..ab29dfa1 --- /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 8206a3bf..b20c7ad5 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 12bd2101..d0a75ca5 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 babf2c78..64aa9f64 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 1dac39bf..b5d14132 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 82f15541..03797ec3 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 90b2028f..4a23e64c 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 00000000..1cbfa24d --- /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 00000000..6abd0541 --- /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 a310c5e42baf0ca4192228be1f04ca95491b57b4 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 17 May 2016 15:56:26 -0300 Subject: [PATCH 05/63] 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 a1ccf319..6c8e420b 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 ab87f66b..ccce1227 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 1aa55aee..ea9364a3 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 ab29dfa1..2dea5c9c 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 b20c7ad5..35112454 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 9a61a85c..f9bdf2c9 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 8fe4701abe99a765837e9c995376528e0edff4ac Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 17 May 2016 20:33:28 -0300 Subject: [PATCH 06/63] 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 c5a50c0d..f954ccec 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 68d0c10f..b51a40bc 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 f4e7964d..d8c5f061 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 64aa9f64..b73410c6 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 03797ec3..c7d9fad3 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 4a23e64c..e6ff26cf 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 00000000..9cd1ed02 --- /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 dedf4a3e7b61c2d791f8b01164bcb31e6f7d750a Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 10:07:53 -0300 Subject: [PATCH 07/63] 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 2dea5c9c..3aa8d637 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 35112454..f3ddd9b9 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 f9bdf2c9..d7c9ce16 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 4d8f87b1cada5041fa60012dcb502cd452a2bc42 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 10:09:28 -0300 Subject: [PATCH 08/63] 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 72a37342..57f9924c 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 6155cc82ba04a53e0cef88aed72bf9fc081a46b3 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 11:51:22 -0300 Subject: [PATCH 09/63] 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 79f0408a..86094604 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 2825a614..75d2d0fc 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 dca6abb24bae3694325c61dcf0bf3c2c4e0c1047 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 12:04:41 -0300 Subject: [PATCH 10/63] 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 8f1109ee..e5a252fd 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 16b04ce641b0ecb98a0500e2534ff51687d1ba17 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Wed, 18 May 2016 13:38:22 -0300 Subject: [PATCH 11/63] 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 b51a40bc..71fa6f53 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 b6897f67a4e584a69154ffe6c828a8f1bdf6ef32 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Thu, 19 May 2016 09:57:59 -0300 Subject: [PATCH 12/63] 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 3aa8d637..dac96ae3 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 f3ddd9b9..437e3806 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 d7c9ce16..004d8574 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 e6e7968c3ab2111a7f5cad51fd9ae45a608d5752 Mon Sep 17 00:00:00 2001 From: Daniel King Date: Tue, 24 May 2016 11:16:17 -0300 Subject: [PATCH 13/63] 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 dac96ae3..8d7b63a7 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 437e3806..4c2d8ef9 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 004d8574..842a4d46 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 ce8314f5f0856bc72e0bd26c83770086712d969b 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/63] Add ChangeLog entry for new features. Fixes #346 --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 348864c0..10dd8689 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 95d0bdbd84817cb4defeb8030b8b2fc39f5d54b5 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/63] 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 6c8e420b..6f7ab6f7 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 ccce1227..a2856a7e 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 ea9364a3..915f8ab0 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 8d7b63a7..2e07f1ed 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 4c2d8ef9..5d2c3e5b 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 842a4d46..6acbc7fa 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 823b7a0ce7f8f4e1b4e7381ad1d38176bb52823a 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/63] 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 6f7ab6f7..21c3158b 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 a2856a7e..f88bd28b 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 915f8ab0..c911b9fd 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 b7e99006f9c85df28a9f15464e1fd5ed28559028 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/63] 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 2e07f1ed..f00380c0 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 5d2c3e5b..28133a67 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 6acbc7fa..5a096586 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 4edd51babec6fa560c3197805d3d4ff946c2b85e 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/63] 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 c911b9fd..f6919157 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 f00380c0..04180081 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 5a096586..66f932c4 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 dca3a5d8842d50833c2f5bc5ad225aefeeb874b0 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/63] 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 21c3158b..810675dd 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 f954ccec..ac1f564f 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 22d465cd..69d2b63b 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 72b7f18f..e056975a 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 b8f663d9..582769ba 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 de4bd5c4..a4c6e35b 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 04180081..3ba19542 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 71fa6f53..acc986fa 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 d8c5f061..5c808285 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 d0a75ca5..aeef9303 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 b73410c6..cce1a384 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 57f9924c..13fa98cd 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 b5d14132..811648a0 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 c7d9fad3..96305386 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 e6ff26cf..f9d97686 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 1cbfa24d..00000000 --- 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 00000000..08129aa3 --- /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 6abd0541..fb1a738f 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 9cd1ed02..de5b3d64 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 e5a252fd..92462e52 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 802cce71..b04935a6 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 502f189253fe65d66df7e11000da7f0056379155 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/63] 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 f88bd28b..7999702f 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 28133a67..1abb96ef 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 56206c4db19f472b8429e71d3ae2570072bb5dac 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/63] 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 7999702f..d32da1b7 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 1abb96ef..5ede4553 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 3ba19542..35ae99e1 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 346b8d5050dd66875d1ae15ebff94b25b9694092 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/63] 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 810675dd..e7413b36 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 35ae99e1..0dba5ed9 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 fb1a738f..b205c4ce 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 fe725defaee76f91aa1f8d6b13469107e53556f0 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/63] 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 acc986fa..1827770b 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 b500f8b9113a54e194a116338eb9b606c4628d45 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/63] 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 d32da1b7..579ea388 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 e7413b36..ddcd5497 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 ac1f564f..591aa79a 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 f6919157..c2e2655e 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 b1ac5e7842376fd2f2fa02094d2f49061c6bb703 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/63] 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 c2e2655e..19f52377 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 0dba5ed9..d599c524 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 66f932c4..14c362d5 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 c4196658..17f9d0e2 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 af69a031..a633c2ba 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 5ef92d309a759d9d2acdaf613021d7bfc66d6241 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/63] 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 ddcd5497..ce9737c2 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 d599c524..9ca21b39 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 1827770b..2463a614 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 b8bd80aa026f9e84b267eb155b910b0d09526c27 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/63] 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 579ea388..7a8cd531 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 ce9737c2..a55a3eea 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 e056975a..21fa9fce 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 19f52377..021a3a0d 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 aeef9303..d9c21cd3 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 d6aea18749e1bf29f061633dda6e970497692039 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/63] 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 17f9d0e2..3e9ab0a2 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 528524bf3c6eb6f9873bc38a101952fbc4943b2a 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/63] 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 75d2d0fc..9c0b9852 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 b205c4ce..3d6a2b6d 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 a633c2ba..5ede635c 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 7296771194379fec7b1b47606e4ad461722c320f 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/63] 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 08129aa3..f0b4a0de 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 3d6a2b6d..a613870b 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 55c0d096b7747b89394be4063d2d35275aa0ced7 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/63] 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 5ede4553..d89000da 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 9c0b9852..fb3ad3e7 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 1465602ee14779f4a21b87ec81aebcabf47fbcac 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/63] 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 14c362d5..542a8500 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 fb3ad3e7..bac1ef3c 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 5ede635c..964d1297 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 69767d1c7b8796fb02b93ee0b437e68267a0ee42 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/63] 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 de5b3d64..d91dc243 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 92462e52..e4b7e436 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 fce88b25333a7ba655b07ded57a96a40b2e4a821 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/63] 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 bac1ef3c..124e5100 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 964d1297..682eb05a 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 2aca2368817ce558d20624ad06b33d2e2d44ae2d 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/63] 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 86094604..3f9033ee 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 124e5100..669d91e7 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 a8fa8b8f964fec5468a9a4a224fda3b04f726ddd 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/63] 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 542a8500..0aa45335 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 f259e848..13912e99 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 682eb05a..c5e7989f 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 59d2c30ebae033e0050eef3382972665d64b8e03 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/63] 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 9ca21b39..fd05886f 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 f0b4a0de..b0eedea2 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 a613870b..3f8145a5 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 444f71121685facd1a8c9b52719bdb1459892219 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/63] 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 c5e7989f..62d2ad95 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 ceb1225d4610d975e1f5a75df9df3f48ae5d96af 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/63] 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 b0eedea2..34cb5683 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 3f8145a5..e379309c 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 c0dfcd4bf195f3f3b547e6a19336a9d3b359473a 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/63] 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 d89000da..5a753eba 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 fd05886f..ebf25bbb 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 0aa45335..a9fff475 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 32902e6eae89af32a406a68f4a7c8dbf318305a0 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/63] 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 591aa79a..1ae847d2 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 2463a614..cf10094f 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 5c808285..9110b968 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 234e1cef735d12f24b569271c8af02edbad6e07c 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/63] 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 5f3e07d0..c67e582e 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 d91dc243..1760dc09 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 e4b7e436..b7037a06 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 ); From 3798b6be6be7a8a9b3ecd1f7e43df3a72382f365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 13:27:45 +0200 Subject: [PATCH 43/63] Add some error codes and merge others - need HW failure codes too - re-use relevant poly codes for chachapoly to save on limited space Values were chosen to leave 3 free slots at the end of the NET odd range. --- include/mbedtls/chacha20.h | 5 ++- include/mbedtls/chachapoly.h | 23 +++++------ include/mbedtls/error.h | 8 ++-- include/mbedtls/poly1305.h | 1 + library/chachapoly.c | 16 +++---- library/error.c | 8 ++-- tests/suites/test_suite_chachapoly.function | 46 ++++++++++----------- 7 files changed, 54 insertions(+), 53 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index 7a8cd531..c33aef37 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -42,8 +42,9 @@ #include #include -#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. */ +#define MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA -0x0051 /**< Invalid input parameter(s). */ +#define MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE -0x0053 /**< Feature not available. For example, s part of the API is not implemented. */ +#define MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED -0x0055 /**< Chacha20 hardware accelerator failed. */ #ifdef __cplusplus extern "C" { diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index a55a3eea..ae786e04 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -39,11 +39,11 @@ #include MBEDTLS_CONFIG_FILE #endif -#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. */ +/* for shared error codes */ +#include "poly1305.h" +#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */ +#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */ #ifdef __cplusplus extern "C" { @@ -59,7 +59,6 @@ mbedtls_chachapoly_mode_t; #if !defined(MBEDTLS_CHACHAPOLY_ALT) #include "chacha20.h" -#include "poly1305.h" typedef struct { @@ -117,7 +116,7 @@ void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); * \param key The 256-bit (32 bytes) key. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA * if \p ctx or \p key are NULL. */ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, @@ -141,7 +140,7 @@ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, * #MBEDTLS_CHACHAPOLY_DECRYPT. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA * if \p ctx or \p mac are NULL. */ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, @@ -177,7 +176,7 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, * This pointer can be NULL if aad_len == 0. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA * if \p ctx or \p aad are NULL. * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE * if the operations has not been started or has been @@ -210,7 +209,7 @@ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, * This pointer can be NULL if len == 0. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_POLY1305_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 @@ -229,7 +228,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, * \param mac The buffer to where the 128-bit (16 bytes) MAC is written. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_POLY1305_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 @@ -265,7 +264,7 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, * \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 + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA * if one or more of the required parameters are NULL. */ int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, @@ -298,7 +297,7 @@ int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, * This pointer can be NULL if ilen == 0. * * \return \c 0 on success. - * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA + * \return #MBEDTLS_ERR_POLY1305_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. diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h index 21fa9fce..12f045ab 100644 --- a/include/mbedtls/error.h +++ b/include/mbedtls/error.h @@ -62,7 +62,7 @@ * DES 2 0x0032-0x0032 0x0033-0x0033 * CTR_DBRG 4 0x0034-0x003A * ENTROPY 3 0x003C-0x0040 0x003D-0x003F - * NET 11 0x0042-0x0052 0x0043-0x0045 + * NET 13 0x0042-0x0052 0x0043-0x0049 * ASN1 7 0x0060-0x006C * CMAC 1 0x007A-0x007A * PBKDF2 1 0x007C-0x007C @@ -76,9 +76,9 @@ * SHA1 1 0x0035-0x0035 * SHA256 1 0x0037-0x0037 * SHA512 1 0x0039-0x0039 - * CHACHA20 2 0x0053-0x0055 - * POLY1305 2 0x0057-0x0059 - * CHACHAPOLY 4 0x0054-0x005A + * CHACHA20 3 0x0051-0x0055 + * POLY1305 3 0x0057-0x005B + * CHACHAPOLY 2 0x0054-0x0056 * * 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 021a3a0d..babbc15f 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -44,6 +44,7 @@ #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. */ +#define MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED -0x005B /**< Poly1305 hardware accelerator failed. */ #ifdef __cplusplus extern "C" { diff --git a/library/chachapoly.c b/library/chachapoly.c index ebf25bbb..de9e66cc 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -123,7 +123,7 @@ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, if ( ( ctx == NULL ) || ( key == NULL ) ) { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } result = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); @@ -140,7 +140,7 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, if ( ( ctx == NULL ) || ( nonce == NULL ) ) { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } /* Set counter = 0, will be update to 1 when generating Poly1305 key */ @@ -180,12 +180,12 @@ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, { if ( ctx == NULL ) { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_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_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } else if ( ctx->state != CHACHAPOLY_STATE_AAD ) { @@ -204,12 +204,12 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, { if ( ctx == NULL ) { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_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_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } else if ( ( ctx->state != CHACHAPOLY_STATE_AAD ) && ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) @@ -251,7 +251,7 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, if ( ( ctx == NULL ) || ( mac == NULL ) ) { - return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } else if ( ctx->state == CHACHAPOLY_STATE_INIT ) { @@ -340,7 +340,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, int diff; if( tag == NULL ) - return( MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); if( ( ret = mbedtls_chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, diff --git a/library/error.c b/library/error.c index d9c21cd3..512831f0 100644 --- a/library/error.c +++ b/library/error.c @@ -670,17 +670,15 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) 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" ); + if( use_ret == -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "CHACHA20 - Chacha20 hardware accelerator failed" ); #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" ); 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) @@ -800,6 +798,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) 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" ); + if( use_ret == -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "POLY1305 - Poly1305 hardware accelerator failed" ); #endif /* MBEDTLS_POLY1305_C */ #if defined(MBEDTLS_RIPEMD160_C) diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index e379309c..7baa2299 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -145,77 +145,77 @@ void chachapoly_bad_params() mbedtls_chachapoly_init( &ctx ); TEST_ASSERT( mbedtls_chachapoly_setkey( NULL, key ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, NULL ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_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 ); + == MBEDTLS_ERR_POLY1305_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 ); + == MBEDTLS_ERR_POLY1305_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 ); + == MBEDTLS_ERR_POLY1305_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 ); + == MBEDTLS_ERR_POLY1305_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 ); + == MBEDTLS_ERR_POLY1305_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 ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( NULL, 0, nonce, aad, 0, mac, input, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, 0, NULL, aad, 0, mac, input, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, 0, nonce, NULL, aad_len, mac, input, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, 0, nonce, aad, 0, NULL, input, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, input_len, nonce, aad, 0, mac, NULL, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_auth_decrypt( &ctx, input_len, nonce, aad, 0, mac, input, NULL ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, @@ -242,26 +242,26 @@ void chachapoly_bad_params() == 0 ); TEST_ASSERT( mbedtls_chachapoly_starts( NULL, nonce, MBEDTLS_CHACHAPOLY_ENCRYPT ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_starts( &ctx, NULL, MBEDTLS_CHACHAPOLY_ENCRYPT ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_update_aad( NULL, aad, aad_len ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_update_aad( &ctx, NULL, aad_len ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_update( NULL, input_len, input, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, NULL, output ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_update( &ctx, input_len, input, NULL ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_finish( NULL, mac ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); TEST_ASSERT( mbedtls_chachapoly_finish( &ctx, NULL ) - == MBEDTLS_ERR_CHACHAPOLY_BAD_INPUT_DATA ); + == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); exit: mbedtls_chachapoly_free( &ctx ); From fb78c901389043d37a3076a745835084c63b8d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 13:46:15 +0200 Subject: [PATCH 44/63] Use recently-introduced platform_util module --- library/chacha20.c | 23 ++++++++++------------- library/chachapoly.c | 11 ++++------- library/poly1305.c | 16 ++++++---------- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/library/chacha20.c b/library/chacha20.c index 5a753eba..7f760354 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -22,7 +22,6 @@ * * This file is part of mbed TLS (https://tls.mbed.org) */ -#include "mbedtls/chacha20.h" #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" @@ -32,7 +31,8 @@ #if defined(MBEDTLS_CHACHA20_C) -#if !defined(MBEDTLS_CHACHA20_ALT) +#include "mbedtls/chacha20.h" +#include "mbedtls/platform_util.h" #include #include @@ -46,6 +46,8 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ +#if !defined(MBEDTLS_CHACHA20_ALT) + #define BYTES_TO_U32_LE( data, offset ) \ ( (uint32_t) data[offset] \ | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \ @@ -59,11 +61,6 @@ #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. * @@ -182,9 +179,9 @@ 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 ) ); + mbedtls_platform_zeroize( ctx->initial_state, sizeof( ctx->initial_state ) ); + mbedtls_platform_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); + mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); /* Initially, there's no keystream bytes available */ ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; @@ -195,7 +192,7 @@ void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) { if ( ctx != NULL ) { - mbedtls_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); } } @@ -243,8 +240,8 @@ 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 ) ); + mbedtls_platform_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); + mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); /* Initially, there's no keystream bytes available */ ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; diff --git a/library/chachapoly.c b/library/chachapoly.c index de9e66cc..5ce27f21 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -29,6 +29,8 @@ #if defined(MBEDTLS_CHACHAPOLY_C) #include "mbedtls/chachapoly.h" +#include "mbedtls/platform_util.h" + #include #if defined(MBEDTLS_SELF_TEST) @@ -47,11 +49,6 @@ #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 ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; -} - /** * \brief Adds padding bytes (zeroes) to pad the AAD for Poly1305. * @@ -170,7 +167,7 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, } cleanup: - mbedtls_zeroize( poly1305_key, 64U ); + mbedtls_platform_zeroize( poly1305_key, 64U ); return( result ); } @@ -355,7 +352,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, if( diff != 0 ) { - mbedtls_zeroize( output, length ); + mbedtls_platform_zeroize( output, length ); return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ); } diff --git a/library/poly1305.c b/library/poly1305.c index a9fff475..bdd67447 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -28,9 +28,8 @@ #if defined(MBEDTLS_POLY1305_C) -#if !defined(MBEDTLS_POLY1305_ALT) - #include "mbedtls/poly1305.h" +#include "mbedtls/platform_util.h" #include @@ -43,6 +42,8 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ +#if !defined(MBEDTLS_POLY1305_ALT) + #define POLY1305_BLOCK_SIZE_BYTES ( 16U ) #define BYTES_TO_U32_LE( data, offset ) \ @@ -52,11 +53,6 @@ | (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. * @@ -244,7 +240,7 @@ void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) { if ( ctx != NULL ) { - mbedtls_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); } } @@ -252,7 +248,7 @@ void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) { if ( ctx != NULL ) { - mbedtls_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); } } @@ -283,7 +279,7 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, ctx->acc[4] = 0U; /* Queue initially empty */ - mbedtls_zeroize( ctx->queue, sizeof( ctx->queue ) ); + mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) ); ctx->queue_len = 0U; return( 0 ); From c22e61a081b0aa1309429cc7f73a22220f419d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 13:51:05 +0200 Subject: [PATCH 45/63] Add ifdef for selftest in header file See https://github.com/ARMmbed/mbedtls/pull/975 --- include/mbedtls/chacha20.h | 2 ++ include/mbedtls/chachapoly.h | 2 ++ include/mbedtls/poly1305.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index c33aef37..56ee57aa 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -196,6 +196,7 @@ int mbedtls_chacha20_crypt( const unsigned char key[32], const unsigned char* input, unsigned char* output ); +#if defined(MBEDTLS_SELF_TEST) /** * \brief The ChaCha20 checkup routine. * @@ -203,6 +204,7 @@ int mbedtls_chacha20_crypt( const unsigned char key[32], * \return \c 1 on failure. */ int mbedtls_chacha20_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index ae786e04..249dba18 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -311,6 +311,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, const unsigned char *input, unsigned char *output ); +#if defined(MBEDTLS_SELF_TEST) /** * \brief The ChaCha20-Poly1305 checkup routine. * @@ -318,6 +319,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, * \return \c 1 on failure. */ int mbedtls_chachapoly_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index babbc15f..abe36900 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -164,6 +164,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32], size_t ilen, unsigned char mac[16] ); +#if defined(MBEDTLS_SELF_TEST) /** * \brief The Poly1305 checkup routine. * @@ -171,6 +172,7 @@ int mbedtls_poly1305_mac( const unsigned char key[32], * \return \c 1 on failure. */ int mbedtls_poly1305_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } From 9620f9b99e59a789e71154d0ca13d310f05247e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 16:52:19 +0200 Subject: [PATCH 46/63] Rm mbedtls_ prefix form static functions - prefix is no necessary for static ids and makes lines longer - most often omitted (even though we're not fully consistent) --- library/chacha20.c | 42 ++++++++++++++++++++---------------------- library/chachapoly.c | 10 +++++----- library/poly1305.c | 27 +++++++++++---------------- 3 files changed, 36 insertions(+), 43 deletions(-) diff --git a/library/chacha20.c b/library/chacha20.c index 7f760354..81bb3b70 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -76,11 +76,11 @@ * \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 ) +static inline void 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]; @@ -111,17 +111,17 @@ static inline void mbedtls_chacha20_quarter_round( uint32_t state[16], * * \param state The ChaCha20 state to update. */ -static void mbedtls_chacha20_inner_block( uint32_t state[16] ) +static void 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 ); + chacha20_quarter_round( state, 0, 4, 8, 12 ); + chacha20_quarter_round( state, 1, 5, 9, 13 ); + chacha20_quarter_round( state, 2, 6, 10, 14 ); + 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 ); + chacha20_quarter_round( state, 0, 5, 10, 15 ); + chacha20_quarter_round( state, 1, 6, 11, 12 ); + chacha20_quarter_round( state, 2, 7, 8, 13 ); + chacha20_quarter_round( state, 3, 4, 9, 14 ); } /** @@ -131,9 +131,9 @@ 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( const uint32_t initial_state[16], - uint32_t working_state[16], - unsigned char keystream[64] ) +static void chacha20_block( const uint32_t initial_state[16], + uint32_t working_state[16], + unsigned char keystream[64] ) { size_t i; size_t offset; @@ -143,9 +143,7 @@ static void mbedtls_chacha20_block( const uint32_t initial_state[16], CHACHA20_BLOCK_SIZE_BYTES ); for ( i = 0U; i < 10U; i++ ) - { - mbedtls_chacha20_inner_block( working_state ); - } + chacha20_inner_block( working_state ); working_state[0] += initial_state[0]; working_state[1] += initial_state[1]; @@ -281,7 +279,7 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, while ( size >= CHACHA20_BLOCK_SIZE_BYTES ) { /* Generate new keystream block and increment counter */ - mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); + chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); ctx->initial_state[CHACHA20_CTR_INDEX]++; for ( i = 0U; i < 64U; i += 8U ) @@ -304,7 +302,7 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, if ( size > 0U ) { /* Generate new keystream block and increment counter */ - mbedtls_chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); + chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); ctx->initial_state[CHACHA20_CTR_INDEX]++; for ( i = 0U; i < size; i++) diff --git a/library/chachapoly.c b/library/chachapoly.c index 5ce27f21..d0c35511 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -54,7 +54,7 @@ * * \param ctx The ChaCha20-Poly1305 context. */ -static void mbedtls_chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) +static void chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) { uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); unsigned char zeroes[15]; @@ -73,7 +73,7 @@ static void mbedtls_chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) * * \param ctx The ChaCha20-Poly1305 context. */ -static void mbedtls_chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) +static void chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) { uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); unsigned char zeroes[15]; @@ -218,7 +218,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, { ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; - mbedtls_chachapoly_pad_aad( ctx ); + chachapoly_pad_aad( ctx ); } ctx->ciphertext_len += len; @@ -257,11 +257,11 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, if ( ctx->state == CHACHAPOLY_STATE_AAD ) { - mbedtls_chachapoly_pad_aad( ctx ); + chachapoly_pad_aad( ctx ); } else if ( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) { - mbedtls_chachapoly_pad_ciphertext( ctx ); + chachapoly_pad_ciphertext( ctx ); } ctx->state = CHACHAPOLY_STATE_FINISHED; diff --git a/library/poly1305.c b/library/poly1305.c index bdd67447..091684e1 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -64,10 +64,10 @@ * 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 ) +static void 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; @@ -167,8 +167,8 @@ static void mbedtls_poly1305_process( mbedtls_poly1305_context *ctx, * \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] ) +static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, + unsigned char mac[16] ) { uint64_t d; uint32_t g0, g1, g2, g3, g4; @@ -330,10 +330,7 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, ctx->queue_len = 0U; - mbedtls_poly1305_process( ctx, - 1U, - ctx->queue, - 1U ); /* add padding bit */ + poly1305_process( ctx, 1U, ctx->queue, 1U ); /* add padding bit */ offset += queue_free_len; remaining -= queue_free_len; @@ -344,7 +341,7 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, { nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; - mbedtls_poly1305_process( ctx, nblocks, &input[offset], 1U ); + poly1305_process( ctx, nblocks, &input[offset], 1U ); offset += nblocks * POLY1305_BLOCK_SIZE_BYTES; remaining %= POLY1305_BLOCK_SIZE_BYTES; @@ -380,13 +377,11 @@ int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, 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) */ + 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 ); + poly1305_compute_mac( ctx, mac ); return( 0 ); } From 98fae6d8003f3fa1222f11fd843781fc7433874d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 17:23:41 +0200 Subject: [PATCH 47/63] ChaCha20: move working state from ctx to stack No need to keep it around. --- include/mbedtls/chacha20.h | 3 +-- library/chacha20.c | 52 ++++++++++++++++++-------------------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index 56ee57aa..d7a0750c 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -54,8 +54,7 @@ extern "C" { typedef struct { - uint32_t initial_state[16]; /*! The initial state (before round operations). */ - uint32_t working_state[16]; /*! The working state (after round operations). */ + uint32_t state[16]; /*! The state (before round operations). */ uint8_t keystream8[64]; /*! Leftover keystream bytes. */ size_t keystream_bytes_used; /*! Number of keystream bytes already used. */ } diff --git a/library/chacha20.c b/library/chacha20.c index 81bb3b70..f782e8c3 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -128,15 +128,13 @@ static void chacha20_inner_block( uint32_t state[16] ) * \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 chacha20_block( const uint32_t initial_state[16], - uint32_t working_state[16], unsigned char keystream[64] ) { + uint32_t working_state[16]; size_t i; - size_t offset; memcpy( working_state, initial_state, @@ -164,21 +162,22 @@ static void chacha20_block( const uint32_t initial_state[16], for ( i = 0U; i < 16; i++ ) { - offset = i * 4U; + size_t 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 ); } + + mbedtls_platform_zeroize( working_state, sizeof( working_state ) ); } void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) { if ( ctx != NULL ) { - mbedtls_platform_zeroize( ctx->initial_state, sizeof( ctx->initial_state ) ); - mbedtls_platform_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); + mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) ); mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); /* Initially, there's no keystream bytes available */ @@ -203,20 +202,20 @@ int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, } /* 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; + ctx->state[0] = 0x61707865; + ctx->state[1] = 0x3320646e; + ctx->state[2] = 0x79622d32; + ctx->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 ); + ctx->state[4] = BYTES_TO_U32_LE( key, 0 ); + ctx->state[5] = BYTES_TO_U32_LE( key, 4 ); + ctx->state[6] = BYTES_TO_U32_LE( key, 8 ); + ctx->state[7] = BYTES_TO_U32_LE( key, 12 ); + ctx->state[8] = BYTES_TO_U32_LE( key, 16 ); + ctx->state[9] = BYTES_TO_U32_LE( key, 20 ); + ctx->state[10] = BYTES_TO_U32_LE( key, 24 ); + ctx->state[11] = BYTES_TO_U32_LE( key, 28 ); return( 0 ); } @@ -231,14 +230,13 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, } /* Counter */ - ctx->initial_state[12] = counter; + ctx->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 ); + ctx->state[13] = BYTES_TO_U32_LE( nonce, 0 ); + ctx->state[14] = BYTES_TO_U32_LE( nonce, 4 ); + ctx->state[15] = BYTES_TO_U32_LE( nonce, 8 ); - mbedtls_platform_zeroize( ctx->working_state, sizeof( ctx->working_state ) ); mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); /* Initially, there's no keystream bytes available */ @@ -279,8 +277,8 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, while ( size >= CHACHA20_BLOCK_SIZE_BYTES ) { /* Generate new keystream block and increment counter */ - chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); - ctx->initial_state[CHACHA20_CTR_INDEX]++; + chacha20_block( ctx->state, ctx->keystream8 ); + ctx->state[CHACHA20_CTR_INDEX]++; for ( i = 0U; i < 64U; i += 8U ) { @@ -302,8 +300,8 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, if ( size > 0U ) { /* Generate new keystream block and increment counter */ - chacha20_block( ctx->initial_state, ctx->working_state, ctx->keystream8 ); - ctx->initial_state[CHACHA20_CTR_INDEX]++; + chacha20_block( ctx->state, ctx->keystream8 ); + ctx->state[CHACHA20_CTR_INDEX]++; for ( i = 0U; i < size; i++) { From 17297890757e6fa86a90cd172275c4f8d96dfa04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 17:53:41 +0200 Subject: [PATCH 48/63] Misc style adjustments - fix some whitespace - fix most overlong lines - remove some superfluous parentheses - s/result/ret/ for consistency with the rest of the library --- library/chacha20.c | 108 ++++++++++++++++--------------- library/chachapoly.c | 150 +++++++++++++++++++++---------------------- library/poly1305.c | 113 ++++++++++++++++---------------- 3 files changed, 189 insertions(+), 182 deletions(-) diff --git a/library/chacha20.c b/library/chacha20.c index f782e8c3..903f55f3 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -55,7 +55,8 @@ | (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 ) @@ -127,7 +128,7 @@ static void chacha20_inner_block( uint32_t state[16] ) /** * \brief Generates a keystream block. * - * \param initial_state The initial ChaCha20 state (containing the key, nonce, counter). + * \param initial_state The initial ChaCha20 state (key, nonce, counter). * \param keystream Generated keystream bytes are written to this buffer. */ static void chacha20_block( const uint32_t initial_state[16], @@ -140,19 +141,19 @@ static void chacha20_block( const uint32_t initial_state[16], initial_state, CHACHA20_BLOCK_SIZE_BYTES ); - for ( i = 0U; i < 10U; i++ ) + for( i = 0U; i < 10U; i++ ) chacha20_inner_block( working_state ); - 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[ 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]; @@ -160,14 +161,14 @@ static void chacha20_block( const uint32_t initial_state[16], working_state[14] += initial_state[14]; working_state[15] += initial_state[15]; - for ( i = 0U; i < 16; i++ ) + for( i = 0U; i < 16; i++ ) { size_t 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 ); } mbedtls_platform_zeroize( working_state, sizeof( working_state ) ); @@ -175,7 +176,7 @@ static void chacha20_block( const uint32_t initial_state[16], void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) { - if ( ctx != NULL ) + if( ctx != NULL ) { mbedtls_platform_zeroize( ctx->state, sizeof( ctx->state ) ); mbedtls_platform_zeroize( ctx->keystream8, sizeof( ctx->keystream8 ) ); @@ -187,7 +188,7 @@ void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx ) void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) { - if ( ctx != NULL ) + if( ctx != NULL ) { mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) ); } @@ -196,7 +197,7 @@ void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ) int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx, const unsigned char key[32] ) { - if ( ( ctx == NULL ) || ( key == NULL ) ) + if( ( ctx == NULL ) || ( key == NULL ) ) { return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); } @@ -224,7 +225,7 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, const unsigned char nonce[12], uint32_t counter ) { - if ( ( ctx == NULL ) || ( nonce == NULL ) ) + if( ( ctx == NULL ) || ( nonce == NULL ) ) { return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); } @@ -253,20 +254,21 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, size_t offset = 0U; size_t i; - if ( ctx == NULL ) + if( ctx == NULL ) { return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA ); } - else if ( ( size > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) ) + 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 ) ) + while( size > 0U && ctx->keystream_bytes_used < CHACHA20_BLOCK_SIZE_BYTES ) { - output[offset] = input[offset] ^ ctx->keystream8[ctx->keystream_bytes_used]; + output[offset] = input[offset] + ^ ctx->keystream8[ctx->keystream_bytes_used]; ctx->keystream_bytes_used++; offset++; @@ -274,22 +276,22 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, } /* Process full blocks */ - while ( size >= CHACHA20_BLOCK_SIZE_BYTES ) + while( size >= CHACHA20_BLOCK_SIZE_BYTES ) { /* Generate new keystream block and increment counter */ chacha20_block( ctx->state, ctx->keystream8 ); ctx->state[CHACHA20_CTR_INDEX]++; - for ( i = 0U; i < 64U; i += 8U ) + for( i = 0U; i < 64U; i += 8U ) { - 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 ]; + output[offset + i ] = input[offset + i ] ^ ctx->keystream8[i ]; + output[offset + i+1] = input[offset + i+1] ^ ctx->keystream8[i+1]; + output[offset + i+2] = input[offset + i+2] ^ ctx->keystream8[i+2]; + output[offset + i+3] = input[offset + i+3] ^ ctx->keystream8[i+3]; + output[offset + i+4] = input[offset + i+4] ^ ctx->keystream8[i+4]; + output[offset + i+5] = input[offset + i+5] ^ ctx->keystream8[i+5]; + output[offset + i+6] = input[offset + i+6] ^ ctx->keystream8[i+6]; + output[offset + i+7] = input[offset + i+7] ^ ctx->keystream8[i+7]; } offset += CHACHA20_BLOCK_SIZE_BYTES; @@ -297,13 +299,13 @@ int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, } /* Last (partial) block */ - if ( size > 0U ) + if( size > 0U ) { /* Generate new keystream block and increment counter */ chacha20_block( ctx->state, ctx->keystream8 ); ctx->state[CHACHA20_CTR_INDEX]++; - for ( i = 0U; i < size; i++) + for( i = 0U; i < size; i++) { output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; } @@ -323,23 +325,23 @@ int mbedtls_chacha20_crypt( const unsigned char key[32], unsigned char* output ) { mbedtls_chacha20_context ctx; - int result; + int ret; mbedtls_chacha20_init( &ctx ); - result = mbedtls_chacha20_setkey( &ctx, key ); - if ( result != 0 ) + ret = mbedtls_chacha20_setkey( &ctx, key ); + if( ret != 0 ) goto cleanup; - result = mbedtls_chacha20_starts( &ctx, nonce, counter ); - if ( result != 0 ) + ret = mbedtls_chacha20_starts( &ctx, nonce, counter ); + if( ret != 0 ) goto cleanup; - result = mbedtls_chacha20_update( &ctx, data_len, input, output ); + ret = mbedtls_chacha20_update( &ctx, data_len, input, output ); cleanup: mbedtls_chacha20_free( &ctx ); - return( result ); + return( ret ); } #endif /* !MBEDTLS_CHACHA20_ALT */ @@ -529,21 +531,21 @@ int mbedtls_chacha20_self_test( int verbose ) { unsigned char output[381]; unsigned i; - int result; + int ret; for( i = 0U; i < 2U; i++ ) { if( verbose != 0 ) mbedtls_printf( " ChaCha20 test %u ", i ); - result = mbedtls_chacha20_crypt( test_keys[i], - test_nonces[i], - test_counters[i], - test_lengths[i], - test_input[i], - output ); + ret = mbedtls_chacha20_crypt( test_keys[i], + test_nonces[i], + test_counters[i], + test_lengths[i], + test_input[i], + output ); - ASSERT( 0 == result, ( "error code: %i\n", result ) ); + ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ), ( "failed (output)\n" ) ); diff --git a/library/chachapoly.c b/library/chachapoly.c index d0c35511..12fce808 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -50,7 +50,7 @@ #define CHACHAPOLY_STATE_FINISHED ( 3 ) /** - * \brief Adds padding bytes (zeroes) to pad the AAD for Poly1305. + * \brief Adds nul bytes to pad the AAD for Poly1305. * * \param ctx The ChaCha20-Poly1305 context. */ @@ -59,7 +59,7 @@ static void chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) uint32_t partial_block_len = (uint32_t) ( ctx->aad_len % 16U ); unsigned char zeroes[15]; - if ( partial_block_len > 0U ) + if( partial_block_len > 0U ) { memset( zeroes, 0, sizeof( zeroes ) ); (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, @@ -69,7 +69,7 @@ static void chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) } /** - * \brief Adds padding bytes (zeroes) to pad the ciphertext for Poly1305. + * \brief Adds nul bytes to pad the ciphertext for Poly1305. * * \param ctx The ChaCha20-Poly1305 context. */ @@ -78,7 +78,7 @@ static void chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); unsigned char zeroes[15]; - if ( partial_block_len > 0U ) + if( partial_block_len > 0U ) { memset( zeroes, 0, sizeof( zeroes ) ); (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, @@ -89,7 +89,7 @@ static void chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) { - if ( ctx != NULL ) + if( ctx != NULL ) { mbedtls_chacha20_init( &ctx->chacha20_ctx ); mbedtls_poly1305_init( &ctx->poly1305_ctx ); @@ -102,7 +102,7 @@ void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ) { - if ( ctx != NULL ) + if( ctx != NULL ) { mbedtls_chacha20_free( &ctx->chacha20_ctx ); mbedtls_poly1305_free( &ctx->poly1305_ctx ); @@ -116,49 +116,49 @@ void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ) int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, const unsigned char key[32] ) { - int result; + int ret; - if ( ( ctx == NULL ) || ( key == NULL ) ) + if( ( ctx == NULL ) || ( key == NULL ) ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - result = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); + ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); - return( result ); + return( ret ); } int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, const unsigned char nonce[12], mbedtls_chachapoly_mode_t mode ) { - int result; + int ret; unsigned char poly1305_key[64]; - if ( ( ctx == NULL ) || ( nonce == NULL ) ) + if( ( ctx == NULL ) || ( nonce == NULL ) ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } /* Set counter = 0, will be update to 1 when generating Poly1305 key */ - result = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U ); - if ( result != 0 ) + ret = mbedtls_chacha20_starts( &ctx->chacha20_ctx, nonce, 0U ); + if( ret != 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. + /* 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. */ memset( poly1305_key, 0, sizeof( poly1305_key ) ); - result = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), + ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), poly1305_key, poly1305_key ); - if ( result != 0 ) + if( ret != 0 ) goto cleanup; - result = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); + ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); - if ( result == 0 ) + if( ret == 0 ) { ctx->aad_len = 0U; ctx->ciphertext_len = 0U; @@ -168,23 +168,23 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, cleanup: mbedtls_platform_zeroize( poly1305_key, 64U ); - return( result ); + return( ret ); } int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, const unsigned char *aad, size_t aad_len ) { - if ( ctx == NULL ) + if( ctx == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - else if ( ( aad_len > 0U ) && ( aad == NULL ) ) + else if( ( aad_len > 0U ) && ( aad == NULL ) ) { /* aad pointer is allowed to be NULL if aad_len == 0 */ return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - else if ( ctx->state != CHACHAPOLY_STATE_AAD ) + else if( ctx->state != CHACHAPOLY_STATE_AAD ) { return(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } @@ -199,22 +199,22 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, const unsigned char *input, unsigned char *output ) { - if ( ctx == NULL ) + if( ctx == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - else if ( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) ) + else if( ( len > 0U ) && ( ( input == NULL ) || ( output == NULL ) ) ) { /* input and output pointers are allowed to be NULL if len == 0 */ return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - else if ( ( ctx->state != CHACHAPOLY_STATE_AAD ) && + else if( ( ctx->state != CHACHAPOLY_STATE_AAD ) && ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) { return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } - if ( ctx->state == CHACHAPOLY_STATE_AAD ) + if( ctx->state == CHACHAPOLY_STATE_AAD ) { ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; @@ -223,11 +223,11 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, ctx->ciphertext_len += len; - if ( ctx->mode == MBEDTLS_CHACHAPOLY_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 - * above, we can safety ignore the return value. + * 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, output, len ); @@ -246,20 +246,20 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, { unsigned char len_block[16]; - if ( ( ctx == NULL ) || ( mac == NULL ) ) + if( ( ctx == NULL ) || ( mac == NULL ) ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - else if ( ctx->state == CHACHAPOLY_STATE_INIT ) + else if( ctx->state == CHACHAPOLY_STATE_INIT ) { return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } - if ( ctx->state == CHACHAPOLY_STATE_AAD ) + if( ctx->state == CHACHAPOLY_STATE_AAD ) { chachapoly_pad_aad( ctx ); } - else if ( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) + else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) { chachapoly_pad_ciphertext( ctx ); } @@ -269,22 +269,22 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, /* 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, len_block, 16U ); (void) mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); @@ -302,24 +302,24 @@ int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, unsigned char *output, unsigned char tag[16] ) { - int result; + int ret; - result = mbedtls_chachapoly_starts( ctx, nonce, mode ); - if ( result != 0 ) + ret = mbedtls_chachapoly_starts( ctx, nonce, mode ); + if( ret != 0 ) goto cleanup; - result = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); - if ( result != 0 ) - goto cleanup; + ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); + if( ret != 0 ) + goto cleanup; - result = mbedtls_chachapoly_update( ctx, length, input, output ); - if ( result != 0 ) - goto cleanup; + ret = mbedtls_chachapoly_update( ctx, length, input, output ); + if( ret != 0 ) + goto cleanup; - result = mbedtls_chachapoly_finish( ctx, tag ); + ret = mbedtls_chachapoly_finish( ctx, tag ); cleanup: - return( result ); + return( ret ); } int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, @@ -466,7 +466,7 @@ int mbedtls_chachapoly_self_test( int verbose ) { mbedtls_chachapoly_context ctx; unsigned i; - int result; + int ret; unsigned char output[200]; unsigned char mac[16]; @@ -477,20 +477,20 @@ int mbedtls_chachapoly_self_test( int verbose ) mbedtls_chachapoly_init( &ctx ); - result = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); - ASSERT( 0 == result, ( "setkey() error code: %i\n", result ) ); + ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); + ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) ); - result = mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, - test_input_len[i], - test_nonce[i], - test_aad[i], - test_aad_len[i], - test_input[i], - output, - mac ); + ret = mbedtls_chachapoly_crypt_and_tag( &ctx, + MBEDTLS_CHACHAPOLY_ENCRYPT, + test_input_len[i], + test_nonce[i], + test_aad[i], + test_aad_len[i], + test_input[i], + output, + mac ); - ASSERT( 0 == result, ( "crypt_and_tag() error code: %i\n", result ) ); + ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) ); ASSERT( 0 == memcmp( output, test_output[i], test_input_len[i] ), ( "failure (wrong output)\n" ) ); diff --git a/library/poly1305.c b/library/poly1305.c index 091684e1..41e83f3f 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -57,12 +57,12 @@ * \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 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. + * \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 poly1305_process( mbedtls_poly1305_context *ctx, size_t nblocks, @@ -92,14 +92,19 @@ static void poly1305_process( mbedtls_poly1305_context *ctx, acc4 = ctx->acc[4]; /* Process full blocks */ - for ( i = 0U; i < nblocks; i++ ) + 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 ); + /* The input block is treated as a 128-bit little-endian integer */ + d0 = BYTES_TO_U32_LE( input, offset + 0 ); + d1 = BYTES_TO_U32_LE( input, offset + 4 ); + d2 = BYTES_TO_U32_LE( input, offset + 8 ); + d3 = BYTES_TO_U32_LE( input, offset + 12 ); + + /* Compute: acc += (padded) block as a 130-bit integer */ + d0 += (uint64_t) acc0; + d1 += (uint64_t) acc1 + ( d0 >> 32U ); + d2 += (uint64_t) acc2 + ( d1 >> 32U ); + d3 += (uint64_t) acc3 + ( d2 >> 32U ); acc0 = (uint32_t) d0; acc1 = (uint32_t) d1; acc2 = (uint32_t) d2; @@ -182,7 +187,7 @@ static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, acc3 = ctx->acc[3]; acc4 = ctx->acc[4]; - /* Before adding 's' we need to ensure that the accumulator is mod 2^130 - 5. + /* Before adding 's' we 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) */ @@ -218,27 +223,27 @@ static void poly1305_compute_mac( const mbedtls_poly1305_context *ctx, acc3 += ctx->s[3] + (uint32_t) ( d >> 32U ); /* Compute MAC (128 least significant bits of the accumulator) */ - 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 ); + 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 ) + if( ctx != NULL ) { mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); } @@ -246,7 +251,7 @@ void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx ) void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) { - if ( ctx != NULL ) + if( ctx != NULL ) { mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); } @@ -255,7 +260,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 || key == NULL ) + if( ctx == NULL || key == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } @@ -294,21 +299,21 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, size_t queue_free_len; size_t nblocks; - if ( ctx == NULL ) + if( ctx == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } - else if ( ( ilen > 0U ) && ( input == NULL ) ) + 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 ( ( remaining > 0U ) && ( ctx->queue_len > 0U ) ) + if( ( remaining > 0U ) && ( ctx->queue_len > 0U ) ) { queue_free_len = ( POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); - if ( ilen < queue_free_len ) + if( ilen < queue_free_len ) { /* Not enough data to complete the block. * Store this data with the other leftovers. @@ -337,7 +342,7 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, } } - if ( remaining >= POLY1305_BLOCK_SIZE_BYTES ) + if( remaining >= POLY1305_BLOCK_SIZE_BYTES ) { nblocks = remaining / POLY1305_BLOCK_SIZE_BYTES; @@ -347,7 +352,7 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, remaining %= POLY1305_BLOCK_SIZE_BYTES; } - if ( remaining > 0U ) + if( remaining > 0U ) { /* Store partial block */ ctx->queue_len = remaining; @@ -360,13 +365,13 @@ int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, unsigned char mac[16] ) { - if ( ( ctx == NULL ) || ( mac == NULL ) ) + if( ( ctx == NULL ) || ( mac == NULL ) ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); } /* Process any leftover data */ - if ( ctx->queue_len > 0U ) + if( ctx->queue_len > 0U ) { /* Add padding bit */ ctx->queue[ctx->queue_len] = 1U; @@ -378,7 +383,7 @@ int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx, POLY1305_BLOCK_SIZE_BYTES - ctx->queue_len ); poly1305_process( ctx, 1U, /* Process 1 block */ - ctx->queue, 0U ); /* Don't add padding bit (it was just added above) */ + ctx->queue, 0U ); /* Already padded above */ } poly1305_compute_mac( ctx, mac ); @@ -392,23 +397,23 @@ int mbedtls_poly1305_mac( const unsigned char key[32], unsigned char mac[16] ) { mbedtls_poly1305_context ctx; - int result; + int ret; mbedtls_poly1305_init( &ctx ); - result = mbedtls_poly1305_starts( &ctx, key ); - if ( result != 0 ) + ret = mbedtls_poly1305_starts( &ctx, key ); + if( ret != 0 ) goto cleanup; - result = mbedtls_poly1305_update( &ctx, input, ilen ); - if ( result != 0 ) + ret = mbedtls_poly1305_update( &ctx, input, ilen ); + if( ret != 0 ) goto cleanup; - result = mbedtls_poly1305_finish( &ctx, mac ); + ret = mbedtls_poly1305_finish( &ctx, mac ); cleanup: mbedtls_poly1305_free( &ctx ); - return( result ); + return( ret ); } #endif /* MBEDTLS_POLY1305_ALT */ @@ -495,18 +500,18 @@ int mbedtls_poly1305_self_test( int verbose ) { unsigned char mac[16]; unsigned i; - int result; + int ret; for( i = 0U; i < 2U; i++ ) { if( verbose != 0 ) mbedtls_printf( " Poly1305 test %u ", i ); - result = mbedtls_poly1305_mac( test_keys[i], - test_data[i], - test_data_len[i], - mac ); - ASSERT( 0 == result, ( "error code: %i\n", result ) ); + ret = mbedtls_poly1305_mac( test_keys[i], + test_data[i], + test_data_len[i], + mac ); + ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); ASSERT( 0 == memcmp( mac, test_mac[i], 16U ), ( "failed (mac)\n" ) ); From f4f01b6b7ad1604e8cd8f25c55b5f32da1a52d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 18:43:42 +0200 Subject: [PATCH 49/63] Check return values from lower modules The cast to void was motivated by the assumption that the functions only return non-zero when passed bad arguments, but that might not be true of alternative implementation, for example on hardware failure. --- library/chachapoly.c | 77 +++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/library/chachapoly.c b/library/chachapoly.c index 12fce808..ba3cf3c0 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -54,18 +54,19 @@ * * \param ctx The ChaCha20-Poly1305 context. */ -static void chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) +static int chachapoly_pad_aad( mbedtls_chachapoly_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, - zeroes, - 16U - partial_block_len ); - } + if( partial_block_len == 0U ) + return( 0 ); + + memset( zeroes, 0, sizeof( zeroes ) ); + + return( mbedtls_poly1305_update( &ctx->poly1305_ctx, + zeroes, + 16U - partial_block_len ) ); } /** @@ -78,13 +79,13 @@ static void chachapoly_pad_ciphertext( mbedtls_chachapoly_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, - zeroes, - 16U - partial_block_len ); - } + if( partial_block_len == 0U ) + return( 0 ); + + memset( zeroes, 0, sizeof( zeroes ) ); + return( mbedtls_poly1305_update( &ctx->poly1305_ctx, + zeroes, + 16U - partial_block_len ) ); } void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ) @@ -199,6 +200,8 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, const unsigned char *input, unsigned char *output ) { + int ret; + if( ctx == NULL ) { return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); @@ -218,24 +221,32 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, { ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; - chachapoly_pad_aad( ctx ); + ret = chachapoly_pad_aad( ctx ); + if( ret != 0 ) + return( ret ); } ctx->ciphertext_len += len; 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 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, output, len ); + ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, output, len ); + if( ret != 0 ) + return( ret ); } else /* DECRYPT */ { - (void) mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len ); - (void) mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, input, len ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, len, input, output ); + if( ret != 0 ) + return( ret ); } return( 0 ); @@ -244,6 +255,7 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, unsigned char mac[16] ) { + int ret; unsigned char len_block[16]; if( ( ctx == NULL ) || ( mac == NULL ) ) @@ -257,11 +269,15 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, if( ctx->state == CHACHAPOLY_STATE_AAD ) { - chachapoly_pad_aad( ctx ); + ret = chachapoly_pad_aad( ctx ); + if( ret != 0 ) + return( ret ); } else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) { - chachapoly_pad_ciphertext( ctx ); + ret = chachapoly_pad_ciphertext( ctx ); + if( ret != 0 ) + return( ret ); } ctx->state = CHACHAPOLY_STATE_FINISHED; @@ -286,10 +302,13 @@ 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, len_block, 16U ); - (void) mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); + ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U ); + if( ret != 0 ) + return( ret ); - return( 0 ); + ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); + + return( ret ); } int mbedtls_chachapoly_crypt_and_tag( mbedtls_chachapoly_context *ctx, From be78b07015f302a9c4897139206d5abb95fbf5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 24 May 2018 19:33:59 +0200 Subject: [PATCH 50/63] chachapoly: warn against piecewise decryption --- include/mbedtls/chachapoly.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index 249dba18..be10cfd3 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -89,13 +89,31 @@ mbedtls_chachapoly_context; * \c mbedtls_chachapoly_crypt_and_tag() or * \c mbedtls_chachapoly_auth_decrypt(). * - * In order to encrypt or decrypt messages piecewise, for each + * In order to encrypt messages piecewise, for each * message you should make a call to * \c mbedtls_chachapoly_starts(), then 0 or more calls to * \c mbedtls_chachapoly_update_aad(), then 0 or more calls to * \c mbedtls_chachapoly_update(), then one call to * \c mbedtls_chachapoly_finish(). * + * \warning Decryption with the piecewise API is discouraged! Always + * use \c mbedtls_chachapoly_auth_decrypt() when possible! + * + * If however this is not possible because the data is too + * large to fit in memory, you need to: + * + * - call \c mbedtls_chachapoly_starts() and (if needed) + * \c mbedtls_chachapoly_update_aad() as above, + * - call \c mbedtls_chachapoly_update() multiple times and + * ensure its output (the plaintext) is NOT used in any other + * way than placing it in temporary storage at this point, + * - call \c mbedtls_chachapoly_finish() to compute the + * authentication tag and compared it in constant time to the + * tag received with the ciphertext. + * + * If the tags are not equal, you must immediately discard + * all previous outputs of \c mbedtls_chachapoly_update(), + * otherwise you can now safely use the plaintext. * * \param ctx The ChachaPoly context to initialize. */ @@ -134,10 +152,13 @@ int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, * \note If the context is being used for AAD only (no data to * encrypt or decrypt) then \p mode can be set to any value. * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * * \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. + * #MBEDTLS_CHACHAPOLY_DECRYPT (discouraged, see warning). * * \return \c 0 on success. * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA @@ -169,6 +190,9 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, * been processed by \c mbedtls_chachapoly_update(), * or if the context has been finished. * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * * \param ctx The ChaCha20-Poly1305 context to use. * \param aad_len The length (in bytes) of the AAD. The length has no * restrictions. @@ -200,6 +224,9 @@ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, * this function 0 times, if no data is to be encrypted * or decrypted. * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * * \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. @@ -227,6 +254,9 @@ int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, * \param ctx The ChaCha20-Poly1305 context to use. * \param mac The buffer to where the 128-bit (16 bytes) MAC is written. * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * * \return \c 0 on success. * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA * if \p ctx or \p mac are NULL. From 26c3b0a4b18fc7c24a00499d3f5a909509ce2bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 4 Jun 2018 12:06:23 +0200 Subject: [PATCH 51/63] Fix return type of internal function Fixes incomplete change in f4f01b6b7ad1 --- library/chachapoly.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/chachapoly.c b/library/chachapoly.c index ba3cf3c0..8f785883 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -74,7 +74,7 @@ static int chachapoly_pad_aad( mbedtls_chachapoly_context *ctx ) * * \param ctx The ChaCha20-Poly1305 context. */ -static void chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) +static int chachapoly_pad_ciphertext( mbedtls_chachapoly_context *ctx ) { uint32_t partial_block_len = (uint32_t) ( ctx->ciphertext_len % 16U ); unsigned char zeroes[15]; From 3dc62a0a9b6776ca1f58724c5be01c77012edf94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 4 Jun 2018 12:18:19 +0200 Subject: [PATCH 52/63] chachapoly: force correct mode for integrated API Allowing DECRYPT with crypt_and_tag is a risk as people might fail to check the tag correctly (or at all). So force them to use auth_decrypt() instead. See also https://github.com/ARMmbed/mbedtls/pull/1668 --- include/mbedtls/chachapoly.h | 21 ++++----- library/chachapoly.c | 51 +++++++++++++-------- library/cipher.c | 3 +- programs/test/benchmark.c | 5 +- tests/suites/test_suite_chachapoly.function | 27 ++++------- 5 files changed, 53 insertions(+), 54 deletions(-) diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index be10cfd3..649749a0 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -269,7 +269,7 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, /** * \brief This function performs a complete ChaCha20-Poly1305 - * operation with the previously-set key. + * authenticated encryption with the previously-set key. * * \note Before using this function, you must set the key with * \c mbedtls_chachapoly_setkey(). @@ -280,8 +280,6 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, * 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). @@ -297,15 +295,14 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, * \return #MBEDTLS_ERR_POLY1305_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, - 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] ); +int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, + size_t length, + const unsigned char nonce[12], + const unsigned char *aad, + size_t aad_len, + const unsigned char *input, + unsigned char *output, + unsigned char tag[16] ); /** * \brief This function performs a complete ChaCha20-Poly1305 diff --git a/library/chachapoly.c b/library/chachapoly.c index 8f785883..80c1ebf8 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -311,15 +311,15 @@ int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, return( ret ); } -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] ) +static int 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] ) { int ret; @@ -341,6 +341,20 @@ cleanup: return( ret ); } +int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, + size_t length, + const unsigned char nonce[12], + const unsigned char *aad, + size_t aad_len, + const unsigned char *input, + unsigned char *output, + unsigned char tag[16] ) +{ + return( chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_ENCRYPT, + length, nonce, aad, aad_len, + input, output, tag ) ); +} + int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, size_t length, const unsigned char nonce[12], @@ -358,7 +372,7 @@ int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, if( tag == NULL ) return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - if( ( ret = mbedtls_chachapoly_crypt_and_tag( ctx, + if( ( ret = chachapoly_crypt_and_tag( ctx, MBEDTLS_CHACHAPOLY_DECRYPT, length, nonce, aad, aad_len, input, output, check_tag ) ) != 0 ) { @@ -499,15 +513,14 @@ int mbedtls_chachapoly_self_test( int verbose ) ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) ); - ret = mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, - test_input_len[i], - test_nonce[i], - test_aad[i], - test_aad_len[i], - test_input[i], - output, - mac ); + ret = mbedtls_chachapoly_encrypt_and_tag( &ctx, + test_input_len[i], + test_nonce[i], + test_aad[i], + test_aad_len[i], + test_input[i], + output, + mac ); ASSERT( 0 == ret, ( "crypt_and_tag() error code: %i\n", ret ) ); diff --git a/library/cipher.c b/library/cipher.c index cf10094f..5a96e2bc 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -992,8 +992,7 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, } *olen = ilen; - return( mbedtls_chachapoly_crypt_and_tag( ctx->cipher_ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, ilen, iv, ad, ad_len, input, output, tag ) ); } #endif /* MBEDTLS_CHACHAPOLY_C */ diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index 3e9ab0a2..f266b82f 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -491,9 +491,8 @@ int main( int argc, char *argv[] ) 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_encrypt_and_tag( &chachapoly, + BUFSIZE, tmp, NULL, 0, buf, buf, tmp ) ); mbedtls_chachapoly_free( &chachapoly ); } diff --git a/tests/suites/test_suite_chachapoly.function b/tests/suites/test_suite_chachapoly.function index 7baa2299..95dfd8a9 100644 --- a/tests/suites/test_suite_chachapoly.function +++ b/tests/suites/test_suite_chachapoly.function @@ -48,8 +48,7 @@ void mbedtls_chachapoly_enc( char *hex_key_string, char *hex_nonce_string, char TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, key_str ) == 0 ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, input_len, nonce_str, aad_str, aad_len, input_str, output, mac ) == 0 ); @@ -149,38 +148,32 @@ void chachapoly_bad_params() TEST_ASSERT( mbedtls_chachapoly_setkey( &ctx, NULL ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( NULL, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( NULL, 0, nonce, aad, 0, input, output, mac ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, 0, NULL, aad, 0, input, output, mac ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, 0, nonce, NULL, aad_len, input, output, mac ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, input_len, nonce, aad, 0, NULL, output, mac ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, input_len, nonce, aad, 0, input, NULL, mac ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, 0, nonce, aad, 0, input, output, NULL ) @@ -217,8 +210,7 @@ void chachapoly_bad_params() mac, input, NULL ) == MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, 0, nonce, aad, aad_len, NULL, NULL, mac ) @@ -229,8 +221,7 @@ void chachapoly_bad_params() mac, NULL, NULL ) == 0 ); - TEST_ASSERT( mbedtls_chachapoly_crypt_and_tag( &ctx, - MBEDTLS_CHACHAPOLY_ENCRYPT, + TEST_ASSERT( mbedtls_chachapoly_encrypt_and_tag( &ctx, input_len, nonce, NULL, 0, input, output, mac ) From e533b221536d1307278584b65065dc1df5b6cb79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 4 Jun 2018 12:23:19 +0200 Subject: [PATCH 53/63] Fix ordering and repetitions in config.h --- include/mbedtls/config.h | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 69d2b63b..663c9841 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -269,13 +269,13 @@ * digests and ciphers instead. * */ -//#define MBEDTLS_CHACHAPOLY_ALT //#define MBEDTLS_AES_ALT //#define MBEDTLS_ARC4_ALT //#define MBEDTLS_BLOWFISH_ALT //#define MBEDTLS_CAMELLIA_ALT //#define MBEDTLS_CCM_ALT //#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT //#define MBEDTLS_CMAC_ALT //#define MBEDTLS_DES_ALT //#define MBEDTLS_DHM_ALT @@ -1689,17 +1689,6 @@ */ #define MBEDTLS_AES_C -/** - * \def MBEDTLS_CHACHAPOLY_C - * - * Enable the ChaCha20-Poly1305 AEAD algorithm. - * - * Module: library/chachapoly.c - * - * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C - */ -#define MBEDTLS_CHACHAPOLY_C - /** * \def MBEDTLS_ARC4_C * @@ -1849,16 +1838,6 @@ */ #define MBEDTLS_CAMELLIA_C -/** - * \def MBEDTLS_CHACHA20_C - * - * Enable the ChaCha20 block cipher. - * - * Module: library/chacha20.c - * Caller: library/chachapoly.c - */ -#define MBEDTLS_CHACHA20_C - /** * \def MBEDTLS_CCM_C * @@ -1894,6 +1873,17 @@ */ #define MBEDTLS_CHACHA20_C +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +#define MBEDTLS_CHACHAPOLY_C + /** * \def MBEDTLS_CIPHER_C * From 9c82e2ce49d466ee37db2fde177a84d49c095631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 4 Jun 2018 12:30:04 +0200 Subject: [PATCH 54/63] Fix some whitespace issues --- programs/test/benchmark.c | 2 +- tests/Makefile | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index f266b82f..0b927e2b 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -97,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, chachapoly,\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" diff --git a/tests/Makefile b/tests/Makefile index f9d97686..16423193 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -45,7 +45,7 @@ ifdef ZLIB LOCAL_LDFLAGS += -lz endif -APPS = 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) \ @@ -209,7 +209,6 @@ 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_aes.ecb$(EXEXT): test_suite_aes.ecb.c $(DEP) echo " CC $<" $(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ From d2db09f435947b5dc12901390e782d68ba3baf77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 4 Jun 2018 12:31:12 +0200 Subject: [PATCH 55/63] Fix typo in documentation --- include/mbedtls/poly1305.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index abe36900..5c69a813 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -106,7 +106,7 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, const unsigned char key[32] ); /** - * \brief This functions feeds an input bufer into an ongoing + * \brief This functions feeds an input buffer into an ongoing * Poly1305 computation. * * It is called between \c mbedtls_cipher_cmac_starts() and From 94175a50f7ec89ecf704b92f6d90bfc9d33dbdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 4 Jun 2018 12:42:17 +0200 Subject: [PATCH 56/63] Refresh generated file --- library/version_features.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/library/version_features.c b/library/version_features.c index cce1a384..c0a5a3c6 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -84,9 +84,6 @@ static const char *features[] = { #if defined(MBEDTLS_TIMING_ALT) "MBEDTLS_TIMING_ALT", #endif /* MBEDTLS_TIMING_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 */ @@ -105,6 +102,9 @@ static const char *features[] = { #if defined(MBEDTLS_CHACHA20_ALT) "MBEDTLS_CHACHA20_ALT", #endif /* MBEDTLS_CHACHA20_ALT */ +#if defined(MBEDTLS_CHACHAPOLY_ALT) + "MBEDTLS_CHACHAPOLY_ALT", +#endif /* MBEDTLS_CHACHAPOLY_ALT */ #if defined(MBEDTLS_CMAC_ALT) "MBEDTLS_CMAC_ALT", #endif /* MBEDTLS_CMAC_ALT */ @@ -519,9 +519,6 @@ static const char *features[] = { #if defined(MBEDTLS_AES_C) "MBEDTLS_AES_C", #endif /* MBEDTLS_AES_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 */ @@ -543,9 +540,6 @@ 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 */ @@ -555,6 +549,9 @@ static const char *features[] = { #if defined(MBEDTLS_CHACHA20_C) "MBEDTLS_CHACHA20_C", #endif /* MBEDTLS_CHACHA20_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + "MBEDTLS_CHACHAPOLY_C", +#endif /* MBEDTLS_CHACHAPOLY_C */ #if defined(MBEDTLS_CIPHER_C) "MBEDTLS_CIPHER_C", #endif /* MBEDTLS_CIPHER_C */ From 2adb375c50e2db5f44dd1ce8b7cb4b33b035563a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 7 Jun 2018 10:51:44 +0200 Subject: [PATCH 57/63] Add option to avoid 64-bit multiplication Motivation is similar to NO_UDBL_DIVISION. The alternative implementation of 64-bit mult is straightforward and aims at obvious correctness. Also, visual examination of the generate assembly show that it's quite efficient with clang, armcc5 and arm-clang. However current GCC generates fairly inefficient code for it. I tried to rework the code in order to make GCC generate more efficient code. Unfortunately the only way to do that is to get rid of 64-bit add and handle the carry manually, but this causes other compilers to generate less efficient code with branches, which is not acceptable from a side-channel point of view. So let's keep the obvious code that works for most compilers and hope future versions of GCC learn to manage registers in a sensible way in that context. See https://bugs.launchpad.net/gcc-arm-embedded/+bug/1775263 --- include/mbedtls/config.h | 22 +++++++++++++ library/poly1305.c | 66 +++++++++++++++++++++++++++----------- library/version_features.c | 3 ++ scripts/config.pl | 1 + tests/scripts/all.sh | 53 +++++++++++++++++++++++++++++- 5 files changed, 125 insertions(+), 20 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 663c9841..bde5a458 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -84,6 +84,28 @@ */ //#define MBEDTLS_NO_UDBL_DIVISION +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + /** * \def MBEDTLS_HAVE_SSE2 * diff --git a/library/poly1305.c b/library/poly1305.c index 41e83f3f..bafe6138 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -53,6 +53,34 @@ | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \ ) +/* + * Our implementation is tuned for 32-bit platforms with a 64-bit multiplier. + * However we provided an alternative for platforms without such a multiplier. + */ +#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) +static uint64_t mul64( uint32_t a, uint32_t b ) +{ + /* a = al + 2**16 ah, b = bl + 2**16 bh */ + const uint16_t al = (uint16_t) a; + const uint16_t bl = (uint16_t) b; + const uint16_t ah = a >> 16; + const uint16_t bh = b >> 16; + + /* ab = al*bl + 2**16 (ah*bl + bl*bh) + 2**32 ah*bh */ + const uint32_t lo = (uint32_t) al * bl; + const uint64_t me = (uint64_t)( (uint32_t) ah * bl ) + (uint32_t) al * bh; + const uint32_t hi = (uint32_t) ah * bh; + + return( lo + ( me << 16 ) + ( (uint64_t) hi << 32 ) ); +} +#else +static inline uint64_t mul64( uint32_t a, uint32_t b ) +{ + return( (uint64_t) a * b ); +} +#endif + + /** * \brief Process blocks with Poly1305. * @@ -112,25 +140,25 @@ static void poly1305_process( mbedtls_poly1305_context *ctx, 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 = mul64( acc0, r0 ) + + mul64( acc1, rs3 ) + + mul64( acc2, rs2 ) + + mul64( acc3, rs1 ); + d1 = mul64( acc0, r1 ) + + mul64( acc1, r0 ) + + mul64( acc2, rs3 ) + + mul64( acc3, rs2 ) + + mul64( acc4, rs1 ); + d2 = mul64( acc0, r2 ) + + mul64( acc1, r1 ) + + mul64( acc2, r0 ) + + mul64( acc3, rs3 ) + + mul64( acc4, rs2 ); + d3 = mul64( acc0, r3 ) + + mul64( acc1, r2 ) + + mul64( acc2, r1 ) + + mul64( acc3, r0 ) + + mul64( acc4, rs3 ); acc4 *= r0; /* Compute: acc %= (2^130 - 5) (partial remainder) */ diff --git a/library/version_features.c b/library/version_features.c index c0a5a3c6..21b3477b 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -39,6 +39,9 @@ static const char *features[] = { #if defined(MBEDTLS_NO_UDBL_DIVISION) "MBEDTLS_NO_UDBL_DIVISION", #endif /* MBEDTLS_NO_UDBL_DIVISION */ +#if defined(MBEDTLS_NO_64BIT_MULTIPLICATION) + "MBEDTLS_NO_64BIT_MULTIPLICATION", +#endif /* MBEDTLS_NO_64BIT_MULTIPLICATION */ #if defined(MBEDTLS_HAVE_SSE2) "MBEDTLS_HAVE_SSE2", #endif /* MBEDTLS_HAVE_SSE2 */ diff --git a/scripts/config.pl b/scripts/config.pl index 5bf27859..a89787ae 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -95,6 +95,7 @@ MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION MBEDTLS_ZLIB_SUPPORT MBEDTLS_PKCS11_C MBEDTLS_NO_UDBL_DIVISION +MBEDTLS_NO_64BIT_MULTIPLICATION _ALT\s*$ ); diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index e6c7549e..83011f5a 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -344,6 +344,12 @@ if_build_succeeded () { fi } +# to be used instead of ! for commands run with +# record_status or if_build_succeeded +not() { + ! "$@" +} + msg "info: $0 configuration" echo "MEMORY: $MEMORY" echo "FORCE: $FORCE" @@ -691,6 +697,31 @@ make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64' msg "test: gcc, force 64-bit bignum limbs" make test + +msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s +cleanup +cp "$CONFIG_H" "$CONFIG_BAK" +scripts/config.pl full +scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests +scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION +make CFLAGS='-Werror -O1' + +msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s +make test + + +msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s +cleanup +cp "$CONFIG_H" "$CONFIG_BAK" +scripts/config.pl full +scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests +scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION +make CFLAGS='-Werror -O1' + +msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s +make test + + msg "build: arm-none-eabi-gcc, make" # ~ 10s cleanup cp "$CONFIG_H" "$CONFIG_BAK" @@ -726,7 +757,27 @@ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib echo "Checking that software 64-bit division is not required" -! grep __aeabi_uldiv library/*.o +if_build_succeeded not grep __aeabi_uldiv library/*.o + +msg "build: arm-none-eabi-gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s +cleanup +cp "$CONFIG_H" "$CONFIG_BAK" +scripts/config.pl full +scripts/config.pl unset MBEDTLS_NET_C +scripts/config.pl unset MBEDTLS_TIMING_C +scripts/config.pl unset MBEDTLS_FS_IO +scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED +scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY +# following things are not in the default config +scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c +scripts/config.pl unset MBEDTLS_THREADING_PTHREAD +scripts/config.pl unset MBEDTLS_THREADING_C +scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h +scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit +scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION +make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -O1 -march=armv6-m -mthumb' lib +echo "Checking that software 64-bit multiplication is not required" +if_build_succeeded not grep __aeabi_lmul library/*.o msg "build: ARM Compiler 5, make" cleanup From 21a65e00113d934da3a770d3741e319abc7c71f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 7 Jun 2018 11:54:17 +0200 Subject: [PATCH 58/63] Fix usage of inline with for some compilers --- library/chacha20.c | 5 +++++ library/poly1305.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/library/chacha20.c b/library/chacha20.c index 903f55f3..d14a51e0 100644 --- a/library/chacha20.c +++ b/library/chacha20.c @@ -48,6 +48,11 @@ #if !defined(MBEDTLS_CHACHA20_ALT) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + #define BYTES_TO_U32_LE( data, offset ) \ ( (uint32_t) data[offset] \ | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \ diff --git a/library/poly1305.c b/library/poly1305.c index bafe6138..e22d3afb 100644 --- a/library/poly1305.c +++ b/library/poly1305.c @@ -44,6 +44,11 @@ #if !defined(MBEDTLS_POLY1305_ALT) +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + #define POLY1305_BLOCK_SIZE_BYTES ( 16U ) #define BYTES_TO_U32_LE( data, offset ) \ From f30dbdcaf0fb4c06d083532334ee15c643bd2051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Thu, 7 Jun 2018 13:04:35 +0200 Subject: [PATCH 59/63] Update generated file --- visualc/VS2010/mbedTLS.vcxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index ad5a062e..446b4ba5 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -159,8 +159,8 @@ - - + + @@ -201,7 +201,7 @@ - + @@ -236,8 +236,8 @@ - - + + @@ -275,7 +275,7 @@ - + From c7bc9e122f7c9536277234fc484c224d686bb811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 18 Jun 2018 10:30:30 +0200 Subject: [PATCH 60/63] Fix a few typos --- include/mbedtls/chacha20.h | 2 +- include/mbedtls/chachapoly.h | 2 +- include/mbedtls/poly1305.h | 8 ++++---- library/chachapoly.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/mbedtls/chacha20.h b/include/mbedtls/chacha20.h index d7a0750c..47bd7d38 100644 --- a/include/mbedtls/chacha20.h +++ b/include/mbedtls/chacha20.h @@ -139,7 +139,7 @@ int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx, * \c mbedtls_chacha20_starts() must be called at least once * to setup the context before this function can be called. * - * \note This function can be called mutliple times in a row in + * \note This function can be called multiple times in a row in * order to encrypt of decrypt data piecewise with the same * key and nonce. * diff --git a/include/mbedtls/chachapoly.h b/include/mbedtls/chachapoly.h index 649749a0..42b2b230 100644 --- a/include/mbedtls/chachapoly.h +++ b/include/mbedtls/chachapoly.h @@ -175,7 +175,7 @@ int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, * 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 + * usually transmitted separately from the ciphertext or * computed locally by each party. * * \note This function is called before data is encrypted/decrypted. diff --git a/include/mbedtls/poly1305.h b/include/mbedtls/poly1305.h index 5c69a813..54b50abc 100644 --- a/include/mbedtls/poly1305.h +++ b/include/mbedtls/poly1305.h @@ -1,7 +1,7 @@ /** * \file poly1305.h * - * \brief This file containts Poly1305 definitions and functions. + * \brief This file contains Poly1305 definitions and functions. * * Poly1305 is a one-time message authenticator that can be used to * authenticate messages. Poly1305-AES was created by Daniel @@ -109,9 +109,9 @@ int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, * \brief This functions feeds an input buffer into an ongoing * Poly1305 computation. * - * 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. + * It is called between \c mbedtls_cipher_poly1305_starts() and + * \c mbedtls_cipher_poly1305_finish(). + * It can be called repeatedly to process a stream of data. * * \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. diff --git a/library/chachapoly.c b/library/chachapoly.c index 80c1ebf8..860f8776 100644 --- a/library/chachapoly.c +++ b/library/chachapoly.c @@ -187,7 +187,7 @@ int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, } else if( ctx->state != CHACHAPOLY_STATE_AAD ) { - return(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); } ctx->aad_len += aad_len; From a18034a8e28020ed93a941a9b5c07fecc4e8aec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Tue, 19 Jun 2018 11:30:32 +0200 Subject: [PATCH 61/63] Adjust to added fields in cipher_base_t This is a follow-up to the previous merge commit: two fields were added in the merged development branch --- library/cipher_wrap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index 5ab4071e..e22c172f 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -1949,9 +1949,15 @@ static const mbedtls_cipher_base_t chacha20_base_info = { #if defined(MBEDTLS_CIPHER_MODE_CFB) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) chacha20_stream_wrap, #endif @@ -2015,9 +2021,15 @@ static const mbedtls_cipher_base_t chachapoly_base_info = { #if defined(MBEDTLS_CIPHER_MODE_CFB) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif From f57bf8b467b8ca7ce82ffedb9846aa8b1e2f9a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 18 Jun 2018 11:14:09 +0200 Subject: [PATCH 62/63] Define specific mode for ChachaPoly The TLS layer is checking for mode, such as GCM, CCM, CBC, STREAM. ChachaPoly needs to have its own mode, even if it's used just one cipher, in order to allow consistent handling of mode in the TLS layer. --- include/mbedtls/cipher.h | 1 + library/cipher_wrap.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index e707808a..a1f4738a 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -186,6 +186,7 @@ typedef enum { MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ + MBEDTLS_MODE_CHACHAPOLY, /**< The ChaCha-Poly cipher mode. */ } mbedtls_cipher_mode_t; /** Supported cipher padding types. */ diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index e22c172f..893490ac 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -2040,7 +2040,7 @@ static const mbedtls_cipher_base_t chachapoly_base_info = { }; static const mbedtls_cipher_info_t chachapoly_info = { MBEDTLS_CIPHER_CHACHA20_POLY1305, - MBEDTLS_MODE_NONE, + MBEDTLS_MODE_CHACHAPOLY, 256, "CHACHA20-POLY1305", 12, From 51d7cfe026fa3f33d86a80d27ea9013830f33992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 25 Jun 2018 11:19:51 +0200 Subject: [PATCH 63/63] Fix coverity warnings in benchmark.c Functions time with TIME_AND_TSC() didn't have their return values checked. I'm not sure whether Coverity complained about existing uses, but it did about new ones, since we consistently check their return values everywhere but here, which it rightfully finds suspicious. So, let's check return values. This probably adds a few cycles to existing loop overhead, but on my machine (x86_64) the added overhead is less than the random-looking variation between various runs, so it's acceptable. Some calls had their own particular error checking; remove that in favour of the new general solution. --- programs/test/benchmark.c | 41 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index d577adb9..5277ceb7 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -119,25 +119,34 @@ int main( void ) #define TIME_AND_TSC( TITLE, CODE ) \ do { \ unsigned long ii, jj, tsc; \ + int ret = 0; \ \ mbedtls_printf( HEADER_FORMAT, TITLE ); \ fflush( stdout ); \ \ mbedtls_set_alarm( 1 ); \ - for( ii = 1; ! mbedtls_timing_alarmed; ii++ ) \ + for( ii = 1; ret == 0 && ! mbedtls_timing_alarmed; ii++ ) \ { \ - CODE; \ + ret = CODE; \ } \ \ tsc = mbedtls_timing_hardclock(); \ - for( jj = 0; jj < 1024; jj++ ) \ + for( jj = 0; ret == 0 && jj < 1024; jj++ ) \ { \ - CODE; \ + ret = CODE; \ } \ \ - mbedtls_printf( "%9lu KiB/s, %9lu cycles/byte\n", \ - ii * BUFSIZE / 1024, \ - ( mbedtls_timing_hardclock() - tsc ) / ( jj * BUFSIZE ) ); \ + if( ret != 0 ) \ + { \ + PRINT_ERROR; \ + } \ + else \ + { \ + mbedtls_printf( "%9lu KiB/s, %9lu cycles/byte\n", \ + ii * BUFSIZE / 1024, \ + ( mbedtls_timing_hardclock() - tsc ) \ + / ( jj * BUFSIZE ) ); \ + } \ } while( 0 ) #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && defined(MBEDTLS_MEMORY_DEBUG) @@ -664,15 +673,13 @@ int main( int argc, char *argv[] ) if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) mbedtls_exit(1); TIME_AND_TSC( "CTR_DRBG (NOPR)", - if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 ) - mbedtls_exit(1) ); + mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) ); if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 ) mbedtls_exit(1); mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON ); TIME_AND_TSC( "CTR_DRBG (PR)", - if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 ) - mbedtls_exit(1) ); + mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) ); mbedtls_ctr_drbg_free( &ctr_drbg ); } #endif @@ -692,8 +699,7 @@ int main( int argc, char *argv[] ) if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 ) mbedtls_exit(1); TIME_AND_TSC( "HMAC_DRBG SHA-1 (NOPR)", - if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 ) - mbedtls_exit(1) ); + mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) ); mbedtls_hmac_drbg_free( &hmac_drbg ); if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 ) @@ -701,8 +707,7 @@ int main( int argc, char *argv[] ) mbedtls_hmac_drbg_set_prediction_resistance( &hmac_drbg, MBEDTLS_HMAC_DRBG_PR_ON ); TIME_AND_TSC( "HMAC_DRBG SHA-1 (PR)", - if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 ) - mbedtls_exit(1) ); + mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) ); mbedtls_hmac_drbg_free( &hmac_drbg ); #endif @@ -713,8 +718,7 @@ int main( int argc, char *argv[] ) if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 ) mbedtls_exit(1); TIME_AND_TSC( "HMAC_DRBG SHA-256 (NOPR)", - if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 ) - mbedtls_exit(1) ); + mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) ); mbedtls_hmac_drbg_free( &hmac_drbg ); if( mbedtls_hmac_drbg_seed( &hmac_drbg, md_info, myrand, NULL, NULL, 0 ) != 0 ) @@ -722,8 +726,7 @@ int main( int argc, char *argv[] ) mbedtls_hmac_drbg_set_prediction_resistance( &hmac_drbg, MBEDTLS_HMAC_DRBG_PR_ON ); TIME_AND_TSC( "HMAC_DRBG SHA-256 (PR)", - if( mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) != 0 ) - mbedtls_exit(1) ); + mbedtls_hmac_drbg_random( &hmac_drbg, buf, BUFSIZE ) ); mbedtls_hmac_drbg_free( &hmac_drbg ); #endif }