diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2018-07-28 11:16:41 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2018-07-28 11:16:58 +0200 |
commit | d8e1cd7a109bc832826f21d6df1faf401be8dcc9 (patch) | |
tree | bfbce3426cb677827d6086a3e135aa4110af0fbf /thirdparty/mbedtls | |
parent | 4e4702e3868af342b0e2964c7753fa4a3aa83af8 (diff) |
mbedtls: Update to upstream version 2.12.0
_WIN32_WINNT redefinition fix is no longer needed as it was merged
upstream. PR 1453 is still not merged, diff updated to current state.
Diffstat (limited to 'thirdparty/mbedtls')
61 files changed, 7372 insertions, 588 deletions
diff --git a/thirdparty/mbedtls/1453.diff b/thirdparty/mbedtls/1453.diff index fef60fc0e6..6630ad861f 100644 --- a/thirdparty/mbedtls/1453.diff +++ b/thirdparty/mbedtls/1453.diff @@ -1,5 +1,5 @@ diff --git a/library/entropy_poll.c b/library/entropy_poll.c -index 67900c46..cefe882d 100644 +index 67900c46c8..cefe882d2a 100644 --- a/library/entropy_poll.c +++ b/library/entropy_poll.c @@ -54,28 +54,43 @@ @@ -54,7 +54,7 @@ index 67900c46..cefe882d 100644 return( 0 ); diff --git a/library/x509_crt.c b/library/x509_crt.c -index 290c1eb3..038eae02 100644 +index 290c1eb3d1..3cf1743821 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -65,6 +65,19 @@ @@ -81,7 +81,7 @@ index 290c1eb3..038eae02 100644 char filename[MAX_PATH]; char *p; size_t len = strlen( path ); -+ int lengthAsInt = 0; ++ int length_as_int = 0; WIN32_FIND_DATAW file_data; HANDLE hFind; @@ -90,7 +90,7 @@ index 290c1eb3..038eae02 100644 filename[len++] = '*'; - w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, -+ if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) ) ++ if ( FAILED ( SizeTToInt( len, &length_as_int ) ) ) + return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + + /* @@ -101,7 +101,7 @@ index 290c1eb3..038eae02 100644 + * incoming string are less than MAX_PATH to avoid a buffer overrun with + * MultiByteToWideChar(). + */ -+ w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir, ++ w_ret = MultiByteToWideChar( CP_ACP, 0, filename, length_as_int, szDir, MAX_PATH - 3 ); if( w_ret == 0 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); @@ -109,12 +109,12 @@ index 290c1eb3..038eae02 100644 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; -+ if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) ) ++ if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &length_as_int ) ) ) + return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, - lstrlenW( file_data.cFileName ), -+ lengthAsInt, ++ length_as_int, p, (int) len - 1, NULL, NULL ); if( w_ret == 0 ) diff --git a/thirdparty/mbedtls/include/mbedtls/aes.h b/thirdparty/mbedtls/include/mbedtls/aes.h index dd5c1183a5..f6603d5962 100644 --- a/thirdparty/mbedtls/include/mbedtls/aes.h +++ b/thirdparty/mbedtls/include/mbedtls/aes.h @@ -13,6 +13,11 @@ * <em>ISO/IEC 18033-2:2006: Information technology -- Security * techniques -- Encryption algorithms -- Part 2: Asymmetric * ciphers</em>. + * + * The AES-XTS block mode is standardized by NIST SP 800-38E + * <https://nvlpubs.nist.gov/nistpubs/legacy/sp/nistspecialpublication800-38e.pdf> + * and described in detail by IEEE P1619 + * <https://ieeexplore.ieee.org/servlet/opac?punumber=4375278>. */ /* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. @@ -89,6 +94,19 @@ typedef struct } mbedtls_aes_context; +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief The AES XTS context-type definition. + */ +typedef struct +{ + mbedtls_aes_context crypt; /*!< The AES context to use for AES block + encryption or decryption. */ + mbedtls_aes_context tweak; /*!< The AES context used for tweak + computation. */ +} mbedtls_aes_xts_context; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #else /* MBEDTLS_AES_ALT */ #include "aes_alt.h" #endif /* MBEDTLS_AES_ALT */ @@ -110,6 +128,25 @@ void mbedtls_aes_init( mbedtls_aes_context *ctx ); */ void mbedtls_aes_free( mbedtls_aes_context *ctx ); +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function initializes the specified AES XTS context. + * + * It must be the first API called before using + * the context. + * + * \param ctx The AES XTS context to initialize. + */ +void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ); + +/** + * \brief This function releases and clears the specified AES XTS context. + * + * \param ctx The AES XTS context to clear. + */ +void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + /** * \brief This function sets the encryption key. * @@ -142,6 +179,44 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, unsigned int keybits ); +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function prepares an XTS context for encryption and + * sets the encryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * \param key The encryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * \param keybits The size of \p key passed in bits. Valid options are: + * <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li> + * <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul> + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); + +/** + * \brief This function prepares an XTS context for decryption and + * sets the decryption key. + * + * \param ctx The AES XTS context to which the key should be bound. + * \param key The decryption key. This is comprised of the XTS key1 + * concatenated with the XTS key2. + * \param keybits The size of \p key passed in bits. Valid options are: + * <ul><li>256 bits (each of key1 and key2 is a 128-bit key)</li> + * <li>512 bits (each of key1 and key2 is a 256-bit key)</li></ul> + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_KEY_LENGTH on failure. + */ +int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + /** * \brief This function performs an AES single-block encryption or * decryption operation. @@ -213,6 +288,49 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, unsigned char *output ); #endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/** + * \brief This function performs an AES-XTS encryption or decryption + * operation for an entire XTS data unit. + * + * AES-XTS encrypts or decrypts blocks based on their location as + * defined by a data unit number. The data unit number must be + * provided by \p data_unit. + * + * NIST SP 800-38E limits the maximum size of a data unit to 2^20 + * AES blocks. If the data unit is larger than this, this function + * returns #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH. + * + * \param ctx The AES XTS context to use for AES XTS operations. + * \param mode The AES operation: #MBEDTLS_AES_ENCRYPT or + * #MBEDTLS_AES_DECRYPT. + * \param length The length of a data unit in bytes. This can be any + * length between 16 bytes and 2^24 bytes inclusive + * (between 1 and 2^20 block cipher blocks). + * \param data_unit The address of the data unit encoded as an array of 16 + * bytes in little-endian format. For disk encryption, this + * is typically the index of the block device sector that + * contains the data. + * \param input The buffer holding the input data (which is an entire + * data unit). This function reads \p length bytes from \p + * input. + * \param output The buffer holding the output data (which is an entire + * data unit). This function writes \p length bytes to \p + * output. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH if \p length is + * smaller than an AES block in size (16 bytes) or if \p + * length is larger than 2^20 blocks (16 MiB). + */ +int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #if defined(MBEDTLS_CIPHER_MODE_CFB) /** * \brief This function performs an AES-CFB128 encryption or decryption @@ -296,6 +414,56 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, unsigned char *output ); #endif /*MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/** + * \brief This function performs an AES-OFB (Output Feedback Mode) + * encryption or decryption operation. + * + * For OFB, you must set up the context with + * mbedtls_aes_setkey_enc(), regardless of whether you are + * performing an encryption or decryption operation. This is + * because OFB mode uses the same key schedule for encryption and + * decryption. + * + * The OFB operation is identical for encryption or decryption, + * therefore no operation mode needs to be specified. + * + * \note Upon exit, the content of iv, the Initialisation Vector, is + * updated so that you can call the same function again on the next + * block(s) of data and get the same result as if it was encrypted + * in one call. This allows a "streaming" usage, by initialising + * iv_off to 0 before the first call, and preserving its value + * between calls. + * + * For non-streaming use, the iv should be initialised on each call + * to a unique value, and iv_off set to 0 on each call. + * + * If you need to retain the contents of the initialisation vector, + * you must either save it manually or use the cipher module + * instead. + * + * \warning For the OFB mode, the initialisation vector must be unique + * every encryption operation. Reuse of an initialisation vector + * will compromise security. + * + * \param ctx The AES context to use for encryption or decryption. + * \param length The length of the input data. + * \param iv_off The offset in IV (updated after use). + * \param iv The initialization vector (updated after use). + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * + * \return \c 0 on success. + */ +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) /** * \brief This function performs an AES-CTR encryption or decryption diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h index f4b2b561d1..b587317d95 100644 --- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h +++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h @@ -49,7 +49,14 @@ /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */ #if defined(__GNUC__) && \ ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 ) -#if defined(__i386__) + +/* + * Disable use of the i386 assembly code below if option -O0, to disable all + * compiler optimisations, is passed, detected with __OPTIMIZE__ + * This is done as the number of registers used in the assembly code doesn't + * work with the -O0 option. + */ +#if defined(__i386__) && defined(__OPTIMIZE__) #define MULADDC_INIT \ asm( \ @@ -142,7 +149,7 @@ "movl %%esi, %3 \n\t" \ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ecx", "edx", "esi", "edi" \ + : "eax", "ebx", "ecx", "edx", "esi", "edi" \ ); #else @@ -154,7 +161,7 @@ "movl %%esi, %3 \n\t" \ : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ - : "eax", "ecx", "edx", "esi", "edi" \ + : "eax", "ebx", "ecx", "edx", "esi", "edi" \ ); #endif /* SSE2 */ #endif /* i386 */ diff --git a/thirdparty/mbedtls/include/mbedtls/ccm.h b/thirdparty/mbedtls/include/mbedtls/ccm.h index 8585ce5e7c..5d727e7cca 100644 --- a/thirdparty/mbedtls/include/mbedtls/ccm.h +++ b/thirdparty/mbedtls/include/mbedtls/ccm.h @@ -14,6 +14,18 @@ * <li>Nonce - A unique value that is assigned to the payload and the * associated data.</li></ul> * + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + * + * Definition of CCM*: + * IEEE 802.15.4 - IEEE Standard for Local and metropolitan area networks + * Integer representation is fixed most-significant-octet-first order and + * the representation of octets is most-significant-bit-first order. This is + * consistent with RFC 3610. */ /* * Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved @@ -102,7 +114,6 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); /** * \brief This function encrypts a buffer using CCM. * - * * \note The tag is written to a separate buffer. To concatenate * the \p tag with the \p output, as done in <em>RFC-3610: * Counter with CBC-MAC (CCM)</em>, use @@ -112,15 +123,17 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ); * \param ctx The CCM context to use for encryption. * \param length The length of the input data in Bytes. * \param iv Initialization vector (nonce). - * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. * \param add The additional data field. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag to generate in Bytes: + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field to generate in Bytes: * 4, 6, 8, 10, 12, 14 or 16. * * \return \c 0 on success. @@ -133,21 +146,64 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, unsigned char *tag, size_t tag_len ); /** + * \brief This function encrypts a buffer using CCM*. + * + * \note The tag is written to a separate buffer. To concatenate + * the \p tag with the \p output, as done in <em>RFC-3610: + * Counter with CBC-MAC (CCM)</em>, use + * \p tag = \p output + \p length, and make sure that the + * output buffer is at least \p length + \p tag_len wide. + * + * \note When using this function in a variable tag length context, + * the tag length has to be encoded into the \p iv passed to + * this function. + * + * \param ctx The CCM context to use for encryption. + * \param length The length of the input data in Bytes. + * \param iv Initialization vector (nonce). + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. + * \param add_len The length of additional data in Bytes. + * Must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * Must be at least \p length Bytes wide. + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field to generate in Bytes: + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. + * \return A CCM or cipher-specific error code on failure. + */ +int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** * \brief This function performs a CCM authenticated decryption of a * buffer. * * \param ctx The CCM context to use for decryption. * \param length The length of the input data in Bytes. - * \param iv Initialization vector. - * \param iv_len The length of the IV in Bytes: 7, 8, 9, 10, 11, 12, or 13. + * \param iv Initialization vector (nonce). + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. * \param add The additional data field. * \param add_len The length of additional data in Bytes. * Must be less than 2^16 - 2^8. * \param input The buffer holding the input data. * \param output The buffer holding the output data. * Must be at least \p length Bytes wide. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag in Bytes. + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field in Bytes. * 4, 6, 8, 10, 12, 14 or 16. * * \return \c 0 on success. This indicates that the message is authentic. @@ -160,6 +216,43 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len ); +/** + * \brief This function performs a CCM* authenticated decryption of a + * buffer. + * + * \note When using this function in a variable tag length context, + * the tag length has to be decoded from \p iv and passed to + * this function as \p tag_len. (\p tag needs to be adjusted + * accordingly.) + * + * \param ctx The CCM context to use for decryption. + * \param length The length of the input data in Bytes. + * \param iv Initialization vector (nonce). + * \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12, + * or 13. The length L of the message length field is + * 15 - \p iv_len. + * \param add The additional data field. + * \param add_len The length of additional data in Bytes. + * Must be less than 2^16 - 2^8. + * \param input The buffer holding the input data. + * \param output The buffer holding the output data. + * Must be at least \p length Bytes wide. + * \param tag The buffer holding the authentication field. + * \param tag_len The length of the authentication field in Bytes. + * 0, 4, 6, 8, 10, 12, 14 or 16. + * + * \warning Passing 0 as \p tag_len means that the message is no + * longer authenticated. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CCM_AUTH_FAILED if the tag does not match. + * \return A cipher-specific error code on calculation failure. + */ +int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) /** diff --git a/thirdparty/mbedtls/include/mbedtls/chacha20.h b/thirdparty/mbedtls/include/mbedtls/chacha20.h new file mode 100644 index 0000000000..47bd7d38b9 --- /dev/null +++ b/thirdparty/mbedtls/include/mbedtls/chacha20.h @@ -0,0 +1,212 @@ +/** + * \file chacha20.h + * + * \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 <damaki.gh@gmail.com> + */ + +/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CHACHA20_H +#define MBEDTLS_CHACHA20_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include <stdint.h> +#include <stddef.h> + +#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" { +#endif + +#if !defined(MBEDTLS_CHACHA20_ALT) + +typedef struct +{ + 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. */ +} +mbedtls_chacha20_context; + +#else /* MBEDTLS_CHACHA20_ALT */ +#include "chacha20_alt.h" +#endif /* MBEDTLS_CHACHA20_ALT */ + +/** + * \brief This function initializes the specified ChaCha20 context. + * + * 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 This function releases and clears the specified ChaCha20 context. + * + * \param ctx The ChaCha20 context to clear. + */ +void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx ); + +/** + * \brief This function sets the encryption/decryption key. + * + * \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(). + * + * \param ctx The ChaCha20 context to which the key should be bound. + * \param key The encryption/decryption key. Must be 32 bytes in length. + * + * \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 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. + * + * \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. + * + * \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 This function encrypts or decrypts 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 \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. + * + * \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. + * + * \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 The buffer holding the output data. + * Must be able to hold \p size bytes. + * This pointer can be NULL if size == 0. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if the ctx, input, or + * output pointers are NULL. + */ +int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, + size_t size, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function encrypts or decrypts data with ChaCha20 and + * the given key and nonce. + * + * Since ChaCha20 is a stream cipher, the same operation is + * used for encrypting and decrypting data. + * + * \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. + * + * \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 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 \c 0 on success. + * \return #MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA if key, nonce, input, + * or output is NULL. + */ +int mbedtls_chacha20_crypt( const unsigned char key[32], + const unsigned char nonce[12], + uint32_t counter, + size_t size, + const unsigned char* input, + unsigned char* output ); + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief The ChaCha20 checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_chacha20_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CHACHA20_H */ diff --git a/thirdparty/mbedtls/include/mbedtls/chachapoly.h b/thirdparty/mbedtls/include/mbedtls/chachapoly.h new file mode 100644 index 0000000000..42b2b230c5 --- /dev/null +++ b/thirdparty/mbedtls/include/mbedtls/chachapoly.h @@ -0,0 +1,355 @@ +/** + * \file chachapoly.h + * + * \brief This file contains the AEAD-ChaCha20-Poly1305 definitions and + * functions. + * + * ChaCha20-Poly1305 is an algorithm for Authenticated Encryption + * with Associated Data (AEAD) that can be used to encrypt and + * authenticate data. It is based on ChaCha20 and Poly1305 by Daniel + * Bernstein and was standardized in RFC 7539. + * + * \author Daniel King <damaki.gh@gmail.com> + */ + +/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_CHACHAPOLY_H +#define MBEDTLS_CHACHAPOLY_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +/* for shared error codes */ +#include "poly1305.h" + +#define MBEDTLS_ERR_CHACHAPOLY_BAD_STATE -0x0054 /**< The requested operation is not permitted in the current state. */ +#define MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED -0x0056 /**< Authenticated decryption failed: data was not authentic. */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + MBEDTLS_CHACHAPOLY_ENCRYPT, /**< The mode value for performing encryption. */ + MBEDTLS_CHACHAPOLY_DECRYPT /**< The mode value for performing decryption. */ +} +mbedtls_chachapoly_mode_t; + +#if !defined(MBEDTLS_CHACHAPOLY_ALT) + +#include "chacha20.h" + +typedef struct +{ + mbedtls_chacha20_context chacha20_ctx; /**< The ChaCha20 context. */ + mbedtls_poly1305_context poly1305_ctx; /**< The Poly1305 context. */ + uint64_t aad_len; /**< The length (bytes) of the Additional Authenticated Data. */ + uint64_t ciphertext_len; /**< The length (bytes) of the ciphertext. */ + int state; /**< The current state of the context. */ + mbedtls_chachapoly_mode_t mode; /**< Cipher mode (encrypt or decrypt). */ +} +mbedtls_chachapoly_context; + +#else /* !MBEDTLS_CHACHAPOLY_ALT */ +#include "chachapoly_alt.h" +#endif /* !MBEDTLS_CHACHAPOLY_ALT */ + +/** + * \brief This function initializes the specified ChaCha20-Poly1305 context. + * + * It must be the first API called before using + * the context. It must be followed by a call to + * \c mbedtls_chachapoly_setkey() before any operation can be + * done, and to \c mbedtls_chachapoly_free() once all + * operations with that context have been finished. + * + * In order to encrypt or decrypt full messages at once, for + * each message you should make a single call to + * \c mbedtls_chachapoly_crypt_and_tag() or + * \c mbedtls_chachapoly_auth_decrypt(). + * + * In order to encrypt messages piecewise, for each + * message you should make a call to + * \c mbedtls_chachapoly_starts(), then 0 or more calls to + * \c mbedtls_chachapoly_update_aad(), then 0 or more calls to + * \c mbedtls_chachapoly_update(), then one call to + * \c mbedtls_chachapoly_finish(). + * + * \warning Decryption with the piecewise API is discouraged! Always + * use \c mbedtls_chachapoly_auth_decrypt() when possible! + * + * If however this is not possible because the data is too + * large to fit in memory, you need to: + * + * - call \c mbedtls_chachapoly_starts() and (if needed) + * \c mbedtls_chachapoly_update_aad() as above, + * - call \c mbedtls_chachapoly_update() multiple times and + * ensure its output (the plaintext) is NOT used in any other + * way than placing it in temporary storage at this point, + * - call \c mbedtls_chachapoly_finish() to compute the + * authentication tag and compared it in constant time to the + * tag received with the ciphertext. + * + * If the tags are not equal, you must immediately discard + * all previous outputs of \c mbedtls_chachapoly_update(), + * otherwise you can now safely use the plaintext. + * + * \param ctx The ChachaPoly context to initialize. + */ +void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx ); + +/** + * \brief This function releases and clears the specified ChaCha20-Poly1305 context. + * + * \param ctx The ChachaPoly context to clear. + */ +void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx ); + +/** + * \brief This function sets the ChaCha20-Poly1305 symmetric encryption key. + * + * \param ctx The ChaCha20-Poly1305 context to which the key should be + * bound. + * \param key The 256-bit (32 bytes) key. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_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 This function starts a ChaCha20-Poly1305 encryption or + * decryption operation. + * + * \warning You must never use the same nonce twice with the same key. + * This would void any confidentiality and authenticity + * guarantees for the messages encrypted with the same nonce + * and key. + * + * \note If the context is being used for AAD only (no data to + * encrypt or decrypt) then \p mode can be set to any value. + * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * + * \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 (discouraged, see warning). + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_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 This function feeds additional data to be authenticated + * into an ongoing ChaCha20-Poly1305 operation. + * + * The Additional Authenticated Data (AAD), also called + * Associated Data (AD) is only authenticated but not + * encrypted nor included in the encrypted output. It is + * usually transmitted separately from the ciphertext or + * computed locally by each party. + * + * \note This function is called before data is encrypted/decrypted. + * I.e. call this function to process the AAD before calling + * \c mbedtls_chachapoly_update(). + * + * You may call this function multiple times to process + * an arbitrary amount of AAD. It is permitted to call + * this function 0 times, if no AAD is used. + * + * This function cannot be called any more if data has + * been processed by \c mbedtls_chachapoly_update(), + * or if the context has been finished. + * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * + * \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 \c 0 on success. + * \return #MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA + * if \p ctx or \p aad are NULL. + * \return #MBEDTLS_ERR_CHACHAPOLY_BAD_STATE + * if the operations has not been started or has been + * finished, or if the AAD has been finished. + */ +int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, + const unsigned char *aad, + size_t aad_len ); + +/** + * \brief Thus function feeds data to be encrypted or decrypted + * into an on-going ChaCha20-Poly1305 + * operation. + * + * The direction (encryption or decryption) depends on the + * mode that was given when calling + * \c mbedtls_chachapoly_starts(). + * + * You may call this function multiple times to process + * an arbitrary amount of data. It is permitted to call + * this function 0 times, if no data is to be encrypted + * or decrypted. + * + * \warning Decryption with the piecewise API is discouraged, see the + * warning on \c mbedtls_chachapoly_init(). + * + * \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 \c 0 on success. + * \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 + * finished. + */ +int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, + size_t len, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief This function finished the ChaCha20-Poly1305 operation and + * generates the MAC (authentication tag). + * + * \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. + * \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 This function performs a complete ChaCha20-Poly1305 + * authenticated encryption with the previously-set key. + * + * \note Before using this function, you must set the key with + * \c mbedtls_chachapoly_setkey(). + * + * \warning You must never use the same nonce twice with the same key. + * This would void any confidentiality and authenticity + * guarantees for the messages encrypted with the same nonce + * and key. + * + * \param ctx The ChaCha20-Poly1305 context to use (holds the key). + * \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_POLY1305_BAD_INPUT_DATA + * if one or more of the required parameters are NULL. + */ +int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx, + size_t length, + const unsigned char nonce[12], + const unsigned char *aad, + size_t aad_len, + const unsigned char *input, + unsigned char *output, + unsigned char tag[16] ); + +/** + * \brief This function performs a complete ChaCha20-Poly1305 + * authenticated decryption with the previously-set key. + * + * \note Before using this function, you must set the key with + * \c mbedtls_chachapoly_setkey(). + * + * \param ctx The ChaCha20-Poly1305 context to use (holds the key). + * \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_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. + */ +int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx, + size_t length, + const unsigned char nonce[12], + const unsigned char *aad, + size_t aad_len, + const unsigned char tag[16], + const unsigned char *input, + unsigned char *output ); + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief The ChaCha20-Poly1305 checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_chachapoly_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CHACHAPOLY_H */ diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h index be80332963..9e6bb8a46a 100644 --- a/thirdparty/mbedtls/include/mbedtls/check_config.h +++ b/thirdparty/mbedtls/include/mbedtls/check_config.h @@ -4,7 +4,7 @@ * \brief Consistency checks for configuration options */ /* - * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -87,6 +87,11 @@ #error "MBEDTLS_CMAC_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_NIST_KW_C) && \ + ( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) ) +#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C) #error "MBEDTLS_ECDH_C defined, but not all prerequisites" #endif @@ -191,6 +196,10 @@ #error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_HKDF_C) && !defined(MBEDTLS_MD_C) +#error "MBEDTLS_HKDF_C defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_HMAC_DRBG_C) && !defined(MBEDTLS_MD_C) #error "MBEDTLS_HMAC_DRBG_C defined, but not all prerequisites" #endif diff --git a/thirdparty/mbedtls/include/mbedtls/cipher.h b/thirdparty/mbedtls/include/mbedtls/cipher.h index 46b3bdfefa..ea0ce983f1 100644 --- a/thirdparty/mbedtls/include/mbedtls/cipher.h +++ b/thirdparty/mbedtls/include/mbedtls/cipher.h @@ -37,7 +37,7 @@ #include <stddef.h> -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) #define MBEDTLS_CIPHER_MODE_AEAD #endif @@ -45,7 +45,7 @@ #define MBEDTLS_CIPHER_MODE_WITH_PADDING #endif -#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) #define MBEDTLS_CIPHER_MODE_STREAM #endif @@ -87,6 +87,7 @@ typedef enum { MBEDTLS_CIPHER_ID_BLOWFISH, /**< The Blowfish cipher. */ MBEDTLS_CIPHER_ID_ARC4, /**< The RC4 cipher. */ MBEDTLS_CIPHER_ID_ARIA, /**< The Aria cipher. */ + MBEDTLS_CIPHER_ID_CHACHA20, /**< The ChaCha20 cipher. */ } mbedtls_cipher_id_t; /** @@ -164,6 +165,13 @@ typedef enum { MBEDTLS_CIPHER_ARIA_128_CCM, /**< Aria cipher with 128-bit key and CCM mode. */ MBEDTLS_CIPHER_ARIA_192_CCM, /**< Aria cipher with 192-bit key and CCM mode. */ MBEDTLS_CIPHER_ARIA_256_CCM, /**< Aria cipher with 256-bit key and CCM mode. */ + MBEDTLS_CIPHER_AES_128_OFB, /**< AES 128-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_192_OFB, /**< AES 192-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_256_OFB, /**< AES 256-bit cipher in OFB mode. */ + MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_CHACHA20, /**< ChaCha20 stream cipher. */ + MBEDTLS_CIPHER_CHACHA20_POLY1305, /**< ChaCha20-Poly1305 AEAD cipher. */ } mbedtls_cipher_type_t; /** Supported cipher modes. */ @@ -172,11 +180,13 @@ typedef enum { MBEDTLS_MODE_ECB, /**< The ECB cipher mode. */ MBEDTLS_MODE_CBC, /**< The CBC cipher mode. */ MBEDTLS_MODE_CFB, /**< The CFB cipher mode. */ - MBEDTLS_MODE_OFB, /**< The OFB cipher mode - unsupported. */ + MBEDTLS_MODE_OFB, /**< The OFB cipher mode. */ MBEDTLS_MODE_CTR, /**< The CTR cipher mode. */ MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ 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. */ @@ -292,7 +302,8 @@ typedef struct { /** Number of Bytes that have not been processed yet. */ size_t unprocessed_len; - /** Current IV or NONCE_COUNTER for CTR-mode. */ + /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number + * for XTS-mode. */ unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; /** IV size in Bytes, for ciphers with variable-length IVs. */ @@ -579,11 +590,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_CHACHAPOLY_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. @@ -594,7 +605,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_CHACHAPOLY_C */ /** * \brief The generic cipher update function. It encrypts or @@ -652,10 +663,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_CHACHAPOLY_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. @@ -670,7 +681,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. @@ -682,7 +693,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_CHACHAPOLY_C */ /** * \brief The generic all-in-one encryption/decryption function, diff --git a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h index 969ff9ccb8..c6def0bef7 100644 --- a/thirdparty/mbedtls/include/mbedtls/cipher_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/cipher_internal.h @@ -64,6 +64,14 @@ struct mbedtls_cipher_base_t unsigned char *output ); #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + /** Encrypt using OFB (Full length) */ + int (*ofb_func)( void *ctx, size_t length, size_t *iv_off, + unsigned char *iv, + const unsigned char *input, + unsigned char *output ); +#endif + #if defined(MBEDTLS_CIPHER_MODE_CTR) /** Encrypt using CTR */ int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, @@ -71,6 +79,13 @@ struct mbedtls_cipher_base_t const unsigned char *input, unsigned char *output ); #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + /** Encrypt or decrypt using XTS. */ + int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, + const unsigned char data_unit[16], + const unsigned char *input, unsigned char *output ); +#endif + #if defined(MBEDTLS_CIPHER_MODE_STREAM) /** Encrypt using STREAM */ int (*stream_func)( void *ctx, size_t length, diff --git a/thirdparty/mbedtls/include/mbedtls/cmac.h b/thirdparty/mbedtls/include/mbedtls/cmac.h index 913c05f8a7..a4fd552565 100644 --- a/thirdparty/mbedtls/include/mbedtls/cmac.h +++ b/thirdparty/mbedtls/include/mbedtls/cmac.h @@ -28,7 +28,7 @@ #ifndef MBEDTLS_CMAC_H #define MBEDTLS_CMAC_H -#include "mbedtls/cipher.h" +#include "cipher.h" #ifdef __cplusplus extern "C" { diff --git a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h index 600a0f154c..213b691403 100644 --- a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h +++ b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h @@ -1378,7 +1378,8 @@ #define SSL_ANTI_REPLAY_ENABLED MBEDTLS_SSL_ANTI_REPLAY_ENABLED #define SSL_ARC4_DISABLED MBEDTLS_SSL_ARC4_DISABLED #define SSL_ARC4_ENABLED MBEDTLS_SSL_ARC4_ENABLED -#define SSL_BUFFER_LEN MBEDTLS_SSL_BUFFER_LEN +#define SSL_BUFFER_LEN ( ( ( MBEDTLS_SSL_IN_BUFFER_LEN ) < ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) \ + ? ( MBEDTLS_SSL_IN_BUFFER_LEN ) : ( MBEDTLS_SSL_OUT_BUFFER_LEN ) ) #define SSL_CACHE_DEFAULT_MAX_ENTRIES MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES #define SSL_CACHE_DEFAULT_TIMEOUT MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT #define SSL_CBC_RECORD_SPLITTING_DISABLED MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h index ae10a4d728..70820be56f 100644 --- a/thirdparty/mbedtls/include/mbedtls/config.h +++ b/thirdparty/mbedtls/include/mbedtls/config.h @@ -8,7 +8,7 @@ * memory footprint. */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -89,6 +89,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 * * CPU supports SSE2 instruction set. @@ -279,14 +301,18 @@ //#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 //#define MBEDTLS_ECJPAKE_ALT //#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT //#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 @@ -516,6 +542,20 @@ #define MBEDTLS_CIPHER_MODE_CTR /** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +#define MBEDTLS_CIPHER_MODE_XTS + +/** * \def MBEDTLS_CIPHER_NULL_CIPHER * * Enable NULL cipher. @@ -1135,6 +1175,17 @@ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES /** + * \def MBEDTLS_SSL_ASYNC_PRIVATE + * + * Enable asynchronous external private key operations in SSL. This allows + * you to configure an SSL connection to call an external cryptographic + * module to perform private key operations instead of performing the + * operation inside the library. + * + */ +//#define MBEDTLS_SSL_ASYNC_PRIVATE + +/** * \def MBEDTLS_SSL_DEBUG_ALL * * Enable the debug messages in SSL module for all issues. @@ -1920,6 +1971,26 @@ #define MBEDTLS_CERTS_C /** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +#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 * * Enable the generic cipher layer. @@ -2150,6 +2221,21 @@ //#define MBEDTLS_HAVEGE_C /** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +#define MBEDTLS_HKDF_C + +/** * \def MBEDTLS_HMAC_DRBG_C * * Enable the HMAC_DRBG random generator. @@ -2164,6 +2250,19 @@ #define MBEDTLS_HMAC_DRBG_C /** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** * \def MBEDTLS_MD_C * * Enable the generic message digest layer. @@ -2447,6 +2546,16 @@ #define MBEDTLS_PLATFORM_C /** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +#define MBEDTLS_POLY1305_C + +/** * \def MBEDTLS_RIPEMD160_C * * Enable the RIPEMD-160 hash algorithm. @@ -2856,7 +2965,51 @@ //#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ /* SSL options */ -//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */ + +/** \def MBEDTLS_SSL_MAX_CONTENT_LEN + * + * Maximum fragment length in bytes. + * + * Determines the size of both the incoming and outgoing TLS I/O buffers. + * + * Uncommenting MBEDTLS_SSL_IN_CONTENT_LEN and/or MBEDTLS_SSL_OUT_CONTENT_LEN + * will override this length by setting maximum incoming and/or outgoing + * fragment length, respectively. + */ +//#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_IN_CONTENT_LEN + * + * Maximum incoming fragment length in bytes. + * + * Uncomment to set the size of the inward TLS buffer independently of the + * outward buffer. + */ +//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_OUT_CONTENT_LEN + * + * Maximum outgoing fragment length in bytes. + * + * Uncomment to set the size of the outward TLS buffer independently of the + * inward buffer. + * + * It is possible to save RAM by setting a smaller outward buffer, while keeping + * the default inward 16384 byte buffer to conform to the TLS specification. + * + * The minimum required outward buffer size is determined by the handshake + * protocol's usage. Handshaking will fail if the outward buffer is too small. + * The specific size requirement depends on the configured ciphers and any + * certificate data which is sent during the handshake. + * + * For absolute minimum RAM usage, it's best to enable + * MBEDTLS_SSL_MAX_FRAGMENT_LENGTH and reduce MBEDTLS_SSL_MAX_CONTENT_LEN. This + * reduces both incoming and outgoing buffer sizes. However this is only + * guaranteed if the other end of the connection also supports the TLS + * max_fragment_len extension. Otherwise the connection may fail. + */ +//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 + //#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ //#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ //#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ @@ -2933,7 +3086,7 @@ /* \} name SECTION: Customisation configuration options */ /* Target and application specific configurations */ -//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" +//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "target_config.h" #if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) #include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE diff --git a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h index dcbc047924..3835d7299b 100644 --- a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h +++ b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h @@ -36,7 +36,7 @@ #include "aes.h" #if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" +#include "threading.h" #endif #define MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ diff --git a/thirdparty/mbedtls/include/mbedtls/error.h b/thirdparty/mbedtls/include/mbedtls/error.h index a17f8d8ace..6b82d4fbbe 100644 --- a/thirdparty/mbedtls/include/mbedtls/error.h +++ b/thirdparty/mbedtls/include/mbedtls/error.h @@ -4,7 +4,7 @@ * \brief Error to string translation */ /* - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * Copyright (C) 2006-2018, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may @@ -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 * ARIA 4 0x0058-0x005E * ASN1 7 0x0060-0x006C * CMAC 1 0x007A-0x007A @@ -77,6 +77,9 @@ * SHA1 1 0x0035-0x0035 * SHA256 1 0x0037-0x0037 * SHA512 1 0x0039-0x0039 + * 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 @@ -89,8 +92,9 @@ * RSA 4 11 * ECP 4 9 (Started from top) * MD 5 5 + * HKDF 5 1 (Started from top) * CIPHER 6 8 - * SSL 6 17 (Started from top) + * SSL 6 22 (Started from top) * SSL 7 31 * * Module dependent error code (5 bits 0x.00.-0x.F8.) diff --git a/thirdparty/mbedtls/include/mbedtls/gcm.h b/thirdparty/mbedtls/include/mbedtls/gcm.h index bec5577142..87535ab957 100644 --- a/thirdparty/mbedtls/include/mbedtls/gcm.h +++ b/thirdparty/mbedtls/include/mbedtls/gcm.h @@ -113,21 +113,41 @@ int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, * the same as input buffer. If the buffers overlap, the output * buffer must trail at least 8 Bytes behind the input buffer. * + * \warning When this function performs a decryption, it outputs the + * authentication tag and does not verify that the data is + * authentic. You should use this function to perform encryption + * only. For decryption, use mbedtls_gcm_auth_decrypt() instead. + * * \param ctx The GCM context to use for encryption or decryption. - * \param mode The operation to perform: #MBEDTLS_GCM_ENCRYPT or - * #MBEDTLS_GCM_DECRYPT. - * \param length The length of the input data. This must be a multiple of - * 16 except in the last call before mbedtls_gcm_finish(). + * \param mode The operation to perform: + * - #MBEDTLS_GCM_ENCRYPT to perform authenticated encryption. + * The ciphertext is written to \p output and the + * authentication tag is written to \p tag. + * - #MBEDTLS_GCM_DECRYPT to perform decryption. + * The plaintext is written to \p output and the + * authentication tag is written to \p tag. + * Note that this mode is not recommended, because it does + * not verify the authenticity of the data. For this reason, + * you should use mbedtls_gcm_auth_decrypt() instead of + * calling this function in decryption mode. + * \param length The length of the input data, which is equal to the length + * of the output data. * \param iv The initialization vector. * \param iv_len The length of the IV. * \param add The buffer holding the additional data. * \param add_len The length of the additional data. - * \param input The buffer holding the input data. - * \param output The buffer for holding the output data. + * \param input The buffer holding the input data. Its size is \b length. + * \param output The buffer for holding the output data. It must have room + * for \b length bytes. * \param tag_len The length of the tag to generate. * \param tag The buffer for holding the tag. * - * \return \c 0 on success. + * \return \c 0 if the encryption or decryption was performed + * successfully. Note that in #MBEDTLS_GCM_DECRYPT mode, + * this does not indicate that the data is authentic. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid. + * \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific + * error code if the encryption or decryption failed. */ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, int mode, @@ -150,19 +170,23 @@ int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, * must trail at least 8 Bytes behind the input buffer. * * \param ctx The GCM context. - * \param length The length of the input data. This must be a multiple - * of 16 except in the last call before mbedtls_gcm_finish(). + * \param length The length of the ciphertext to decrypt, which is also + * the length of the decrypted plaintext. * \param iv The initialization vector. * \param iv_len The length of the IV. * \param add The buffer holding the additional data. * \param add_len The length of the additional data. - * \param tag The buffer holding the tag. - * \param tag_len The length of the tag. - * \param input The buffer holding the input data. - * \param output The buffer for holding the output data. + * \param tag The buffer holding the tag to verify. + * \param tag_len The length of the tag to verify. + * \param input The buffer holding the ciphertext. Its size is \b length. + * \param output The buffer for holding the decrypted plaintext. It must + * have room for \b length bytes. * - * \return 0 if successful and authenticated. - * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. + * \return \c 0 if successful and authenticated. + * \return #MBEDTLS_ERR_GCM_AUTH_FAILED if the tag does not match. + * \return #MBEDTLS_ERR_GCM_BAD_INPUT if the lengths are not valid. + * \return #MBEDTLS_ERR_GCM_HW_ACCEL_FAILED or a cipher-specific + * error code if the decryption failed. */ int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, size_t length, diff --git a/thirdparty/mbedtls/include/mbedtls/hkdf.h b/thirdparty/mbedtls/include/mbedtls/hkdf.h new file mode 100644 index 0000000000..6833e7272e --- /dev/null +++ b/thirdparty/mbedtls/include/mbedtls/hkdf.h @@ -0,0 +1,125 @@ +/** + * \file hkdf.h + * + * \brief This file contains the HKDF interface. + * + * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) is + * specified by RFC 5869. + */ +/* + * Copyright (C) 2016-2018, 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_HKDF_H +#define MBEDTLS_HKDF_H + +#include "md.h" + +/** + * \name HKDF Error codes + * \{ + */ +#define MBEDTLS_ERR_HKDF_BAD_INPUT_DATA -0x5F80 /**< Bad input parameters to function. */ +/* \} name */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief This is the HMAC-based Extract-and-Expand Key Derivation Function + * (HKDF). + * + * \param md A hash function; md.size denotes the length of the hash + * function output in bytes. + * \param salt An optional salt value (a non-secret random value); + * if the salt is not provided, a string of all zeros of + * md.size length is used as the salt. + * \param salt_len The length in bytes of the optional \p salt. + * \param ikm The input keying material. + * \param ikm_len The length in bytes of \p ikm. + * \param info An optional context and application specific information + * string. This can be a zero-length string. + * \param info_len The length of \p info in bytes. + * \param okm The output keying material of \p okm_len bytes. + * \param okm_len The length of the output keying material in bytes. This + * must be less than or equal to 255 * md.size bytes. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. + * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying + * MD layer. + */ +int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, + size_t salt_len, const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len ); + +/** + * \brief Take the input keying material \p ikm and extract from it a + * fixed-length pseudorandom key \p prk. + * + * \param md A hash function; md.size denotes the length of the + * hash function output in bytes. + * \param salt An optional salt value (a non-secret random value); + * if the salt is not provided, a string of all zeros + * of md.size length is used as the salt. + * \param salt_len The length in bytes of the optional \p salt. + * \param ikm The input keying material. + * \param ikm_len The length in bytes of \p ikm. + * \param[out] prk A pseudorandom key of at least md.size bytes. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. + * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying + * MD layer. + */ +int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *prk ); + +/** + * \brief Expand the supplied \p prk into several additional pseudorandom + * keys, which is the output of the HKDF. + * + * \param md A hash function; md.size denotes the length of the hash + * function output in bytes. + * \param prk A pseudorandom key of at least md.size bytes. \p prk is usually, + * the output from the HKDF extract step. + * \param prk_len The length in bytes of \p prk. + * \param info An optional context and application specific information + * string. This can be a zero-length string. + * \param info_len The length of \p info in bytes. + * \param okm The output keying material of \p okm_len bytes. + * \param okm_len The length of the output keying material in bytes. This + * must be less than or equal to 255 * md.size bytes. + * + * \return 0 on success. + * \return #MBEDTLS_ERR_HKDF_BAD_INPUT_DATA when the parameters are invalid. + * \return An MBEDTLS_ERR_MD_* error for errors returned from the underlying + * MD layer. + */ +int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, + size_t prk_len, const unsigned char *info, + size_t info_len, unsigned char *okm, size_t okm_len ); + +#ifdef __cplusplus +} +#endif + +#endif /* hkdf.h */ diff --git a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h index e0821cf788..2608de8595 100644 --- a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h +++ b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h @@ -27,7 +27,7 @@ #include "md.h" #if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" +#include "threading.h" #endif /* diff --git a/thirdparty/mbedtls/include/mbedtls/net.h b/thirdparty/mbedtls/include/mbedtls/net.h index 28ae8217c0..6c13b53fb9 100644 --- a/thirdparty/mbedtls/include/mbedtls/net.h +++ b/thirdparty/mbedtls/include/mbedtls/net.h @@ -1,7 +1,7 @@ /** * \file net.h * - * \brief Deprecated header file that includes mbedtls/net_sockets.h + * \brief Deprecated header file that includes net_sockets.h * * \deprecated Superseded by mbedtls/net_sockets.h */ @@ -25,7 +25,7 @@ */ #if !defined(MBEDTLS_DEPRECATED_REMOVED) -#include "mbedtls/net_sockets.h" +#include "net_sockets.h" #if defined(MBEDTLS_DEPRECATED_WARNING) #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" #endif /* MBEDTLS_DEPRECATED_WARNING */ diff --git a/thirdparty/mbedtls/include/mbedtls/net_sockets.h b/thirdparty/mbedtls/include/mbedtls/net_sockets.h index 0f9b31ebcb..9f07eeb4d3 100644 --- a/thirdparty/mbedtls/include/mbedtls/net_sockets.h +++ b/thirdparty/mbedtls/include/mbedtls/net_sockets.h @@ -1,7 +1,23 @@ /** * \file net_sockets.h * - * \brief Network communication functions + * \brief Network sockets abstraction layer to integrate Mbed TLS into a + * BSD-style sockets API. + * + * The network sockets module provides an example integration of the + * Mbed TLS library into a BSD sockets implementation. The module is + * intended to be an example of how Mbed TLS can be integrated into a + * networking stack, as well as to be Mbed TLS's network integration + * for its supported platforms. + * + * The module is intended only to be used with the Mbed TLS library and + * is not intended to be used by third party application software + * directly. + * + * The supported platforms are as follows: + * * Microsoft Windows and Windows CE + * * POSIX/Unix platforms including Linux, OS X + * */ /* * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved diff --git a/thirdparty/mbedtls/include/mbedtls/nist_kw.h b/thirdparty/mbedtls/include/mbedtls/nist_kw.h new file mode 100644 index 0000000000..5a0f656a8f --- /dev/null +++ b/thirdparty/mbedtls/include/mbedtls/nist_kw.h @@ -0,0 +1,178 @@ +/** + * \file nist_kw.h + * + * \brief This file provides an API for key wrapping (KW) and key wrapping with + * padding (KWP) as defined in NIST SP 800-38F. + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf + * + * Key wrapping specifies a deterministic authenticated-encryption mode + * of operation, according to <em>NIST SP 800-38F: Recommendation for + * Block Cipher Modes of Operation: Methods for Key Wrapping</em>. Its + * purpose is to protect cryptographic keys. + * + * Its equivalent is RFC 3394 for KW, and RFC 5649 for KWP. + * https://tools.ietf.org/html/rfc3394 + * https://tools.ietf.org/html/rfc5649 + * + */ +/* + * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_NIST_KW_H +#define MBEDTLS_NIST_KW_H + +#include "cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + MBEDTLS_KW_MODE_KW = 0, + MBEDTLS_KW_MODE_KWP = 1 +} mbedtls_nist_kw_mode_t; + +#if !defined(MBEDTLS_NIST_KW_ALT) +// Regular implementation +// + +/** + * \brief The key wrapping context-type definition. The key wrapping context is passed + * to the APIs called. + * + * \note The definition of this type may change in future library versions. + * Don't make any assumptions on this context! + */ +typedef struct { + mbedtls_cipher_context_t cipher_ctx; /*!< The cipher context used. */ +} mbedtls_nist_kw_context; + +#else /* MBEDTLS_NIST_key wrapping_ALT */ +#include "nist_kw_alt.h" +#endif /* MBEDTLS_NIST_KW_ALT */ + +/** + * \brief This function initializes the specified key wrapping context + * to make references valid and prepare the context + * for mbedtls_nist_kw_setkey() or mbedtls_nist_kw_free(). + * + * \param ctx The key wrapping context to initialize. + * + */ +void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ); + +/** + * \brief This function initializes the key wrapping context set in the + * \p ctx parameter and sets the encryption key. + * + * \param ctx The key wrapping context. + * \param cipher The 128-bit block cipher to use. Only AES is supported. + * \param key The Key Encryption Key (KEK). + * \param keybits The KEK size in bits. This must be acceptable by the cipher. + * \param is_wrap Specify whether the operation within the context is wrapping or unwrapping + * + * \return \c 0 on success. + * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for any invalid input. + * \return \c MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE for 128-bit block ciphers + * which are not supported. + * \return cipher-specific error code on failure of the underlying cipher. + */ +int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits, + const int is_wrap ); + +/** + * \brief This function releases and clears the specified key wrapping context + * and underlying cipher sub-context. + * + * \param ctx The key wrapping context to clear. + */ +void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ); + +/** + * \brief This function encrypts a buffer using key wrapping. + * + * \param ctx The key wrapping context to use for encryption. + * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) + * \param input The buffer holding the input data. + * \param in_len The length of the input data in Bytes. + * The input uses units of 8 Bytes called semiblocks. + * <ul><li>For KW mode: a multiple of 8 bytes between 16 and 2^57-8 inclusive. </li> + * <li>For KWP mode: any length between 1 and 2^32-1 inclusive.</li></ul> + * \param[out] output The buffer holding the output data. + * <ul><li>For KW mode: Must be at least 8 bytes larger than \p in_len.</li> + * <li>For KWP mode: Must be at least 8 bytes larger rounded up to a multiple of + * 8 bytes for KWP (15 bytes at most).</li></ul> + * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. + * \param[in] out_size The capacity of the output buffer. + * + * \return \c 0 on success. + * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. + * \return cipher-specific error code on failure of the underlying cipher. + */ +int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, + const unsigned char *input, size_t in_len, + unsigned char *output, size_t* out_len, size_t out_size ); + +/** + * \brief This function decrypts a buffer using key wrapping. + * + * \param ctx The key wrapping context to use for decryption. + * \param mode The key wrapping mode to use (MBEDTLS_KW_MODE_KW or MBEDTLS_KW_MODE_KWP) + * \param input The buffer holding the input data. + * \param in_len The length of the input data in Bytes. + * The input uses units of 8 Bytes called semiblocks. + * The input must be a multiple of semiblocks. + * <ul><li>For KW mode: a multiple of 8 bytes between 24 and 2^57 inclusive. </li> + * <li>For KWP mode: a multiple of 8 bytes between 16 and 2^32 inclusive.</li></ul> + * \param[out] output The buffer holding the output data. + * The output buffer's minimal length is 8 bytes shorter than \p in_len. + * \param[out] out_len The number of bytes written to the output buffer. \c 0 on failure. + * For KWP mode, the length could be up to 15 bytes shorter than \p in_len, + * depending on how much padding was added to the data. + * \param[in] out_size The capacity of the output buffer. + * + * \return \c 0 on success. + * \return \c MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA for invalid input length. + * \return \c MBEDTLS_ERR_CIPHER_AUTH_FAILED for verification failure of the ciphertext. + * \return cipher-specific error code on failure of the underlying cipher. + */ +int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, mbedtls_nist_kw_mode_t mode, + const unsigned char *input, size_t in_len, + unsigned char *output, size_t* out_len, size_t out_size); + + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/** + * \brief The key wrapping checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_nist_kw_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_NIST_KW_H */ diff --git a/thirdparty/mbedtls/include/mbedtls/oid.h b/thirdparty/mbedtls/include/mbedtls/oid.h index 408645ece7..f82554844c 100644 --- a/thirdparty/mbedtls/include/mbedtls/oid.h +++ b/thirdparty/mbedtls/include/mbedtls/oid.h @@ -97,6 +97,8 @@ /* ISO arc for standard certificate and CRL extensions */ #define MBEDTLS_OID_ID_CE MBEDTLS_OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */ +#define MBEDTLS_OID_NIST_ALG MBEDTLS_OID_GOV "\x03\x04" /** { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) */ + /** * Private Internet Extensions * { iso(1) identified-organization(3) dod(6) internet(1) @@ -219,12 +221,12 @@ #define MBEDTLS_OID_DIGEST_ALG_MD4 MBEDTLS_OID_RSA_COMPANY "\x02\x04" /**< id-mbedtls_md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */ #define MBEDTLS_OID_DIGEST_ALG_MD5 MBEDTLS_OID_RSA_COMPANY "\x02\x05" /**< id-mbedtls_md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ #define MBEDTLS_OID_DIGEST_ALG_SHA1 MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_SHA1 /**< id-mbedtls_sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_GOV "\x03\x04\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA224 MBEDTLS_OID_NIST_ALG "\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA256 MBEDTLS_OID_NIST_ALG "\x02\x01" /**< id-mbedtls_sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA384 MBEDTLS_OID_NIST_ALG "\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ -#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_GOV "\x03\x04\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ +#define MBEDTLS_OID_DIGEST_ALG_SHA512 MBEDTLS_OID_NIST_ALG "\x02\x03" /**< id-mbedtls_sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ #define MBEDTLS_OID_HMAC_SHA1 MBEDTLS_OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ @@ -241,8 +243,21 @@ */ #define MBEDTLS_OID_DES_CBC MBEDTLS_OID_ISO_IDENTIFIED_ORG MBEDTLS_OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */ #define MBEDTLS_OID_DES_EDE3_CBC MBEDTLS_OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */ +#define MBEDTLS_OID_AES MBEDTLS_OID_NIST_ALG "\x01" /** aes OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) 1 } */ /* + * Key Wrapping algorithms + */ +/* + * RFC 5649 + */ +#define MBEDTLS_OID_AES128_KW MBEDTLS_OID_AES "\x05" /** id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ +#define MBEDTLS_OID_AES128_KWP MBEDTLS_OID_AES "\x08" /** id-aes128-wrap-pad OBJECT IDENTIFIER ::= { aes 8 } */ +#define MBEDTLS_OID_AES192_KW MBEDTLS_OID_AES "\x19" /** id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ +#define MBEDTLS_OID_AES192_KWP MBEDTLS_OID_AES "\x1c" /** id-aes192-wrap-pad OBJECT IDENTIFIER ::= { aes 28 } */ +#define MBEDTLS_OID_AES256_KW MBEDTLS_OID_AES "\x2d" /** id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ +#define MBEDTLS_OID_AES256_KWP MBEDTLS_OID_AES "\x30" /** id-aes256-wrap-pad OBJECT IDENTIFIER ::= { aes 48 } */ +/* * PKCS#5 OIDs */ #define MBEDTLS_OID_PKCS5_PBKDF2 MBEDTLS_OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */ diff --git a/thirdparty/mbedtls/include/mbedtls/platform.h b/thirdparty/mbedtls/include/mbedtls/platform.h index bba770911e..624cc642ac 100644 --- a/thirdparty/mbedtls/include/mbedtls/platform.h +++ b/thirdparty/mbedtls/include/mbedtls/platform.h @@ -40,7 +40,7 @@ #endif #if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" +#include "platform_time.h" #endif #ifdef __cplusplus @@ -121,8 +121,8 @@ extern "C" { #else /* For size_t */ #include <stddef.h> -extern void * (*mbedtls_calloc)( size_t n, size_t size ); -extern void (*mbedtls_free)( void *ptr ); +extern void *mbedtls_calloc( size_t n, size_t size ); +extern void mbedtls_free( void *ptr ); /** * \brief This function dynamically sets the memory-management diff --git a/thirdparty/mbedtls/include/mbedtls/poly1305.h b/thirdparty/mbedtls/include/mbedtls/poly1305.h new file mode 100644 index 0000000000..54b50abc25 --- /dev/null +++ b/thirdparty/mbedtls/include/mbedtls/poly1305.h @@ -0,0 +1,181 @@ +/** + * \file poly1305.h + * + * \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 + * 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 <damaki.gh@gmail.com> + */ + +/* Copyright (C) 2006-2018, Arm Limited (or its affiliates), All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ + +#ifndef MBEDTLS_POLY1305_H +#define MBEDTLS_POLY1305_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include <stdint.h> +#include <stddef.h> + +#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" { +#endif + +#if !defined(MBEDTLS_POLY1305_ALT) + +typedef struct +{ + 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; + +#else /* MBEDTLS_POLY1305_ALT */ +#include "poly1305_alt.h" +#endif /* MBEDTLS_POLY1305_ALT */ + +/** + * \brief This function initializes the specified Poly1305 context. + * + * 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 This function releases and clears the specified Poly1305 context. + * + * \param ctx The Poly1305 context to clear. + */ +void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ); + +/** + * \brief This function sets the one-time authentication key. + * + * \warning The key must be unique and unpredictable for each + * invocation of Poly1305. + * + * \param ctx The Poly1305 context to which the key should be bound. + * \param key The buffer containing the 256-bit key. + * + * \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 This functions feeds an input buffer into an ongoing + * Poly1305 computation. + * + * 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. + * \param input The buffer holding the input data. + * This pointer can be NULL if ilen == 0. + * + * \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, + const unsigned char *input, + size_t ilen ); + +/** + * \brief This function generates the Poly1305 Message + * Authentication Code (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 \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 This function calculates the Poly1305 MAC of the input + * buffer with the provided key. + * + * \warning The key must be unique and unpredictable for each + * invocation of Poly1305. + * + * \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 \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], + const unsigned char *input, + size_t ilen, + unsigned char mac[16] ); + +#if defined(MBEDTLS_SELF_TEST) +/** + * \brief The Poly1305 checkup routine. + * + * \return \c 0 on success. + * \return \c 1 on failure. + */ +int mbedtls_poly1305_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_POLY1305_H */ diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h index 250031a6d3..2d511a8ea1 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl.h @@ -62,7 +62,7 @@ #endif #if defined(MBEDTLS_HAVE_TIME) -#include "mbedtls/platform_time.h" +#include "platform_time.h" #endif /* @@ -120,6 +120,7 @@ #define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */ #define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */ #define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ +#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ /* * Various constants @@ -219,7 +220,7 @@ #endif /* - * Maxium fragment length in bytes, + * Maximum fragment length in bytes, * determines the size of each of the two internal I/O buffers. * * Note: the RFC defines the default size of SSL / TLS messages. If you @@ -233,6 +234,14 @@ #define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ #endif +#if !defined(MBEDTLS_SSL_IN_CONTENT_LEN) +#define MBEDTLS_SSL_IN_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN +#endif + +#if !defined(MBEDTLS_SSL_OUT_CONTENT_LEN) +#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN +#endif + /* \} name SECTION: Module settings */ /* @@ -536,7 +545,6 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx, */ typedef int mbedtls_ssl_get_timer_t( void * ctx ); - /* Defined below */ typedef struct mbedtls_ssl_session mbedtls_ssl_session; typedef struct mbedtls_ssl_context mbedtls_ssl_context; @@ -553,6 +561,218 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; #endif +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Callback type: start external signature operation. + * + * This callback is called during an SSL handshake to start + * a signature decryption operation using an + * external processor. The parameter \p cert contains + * the public key; it is up to the callback function to + * determine how to access the associated private key. + * + * This function typically sends or enqueues a request, and + * does not wait for the operation to complete. This allows + * the handshake step to be non-blocking. + * + * The parameters \p ssl and \p cert are guaranteed to remain + * valid throughout the handshake. On the other hand, this + * function must save the contents of \p hash if the value + * is needed for later processing, because the \p hash buffer + * is no longer valid after this function returns. + * + * This function may call mbedtls_ssl_set_async_operation_data() + * to store an operation context for later retrieval + * by the resume or cancel callback. + * + * \note For RSA signatures, this function must produce output + * that is consistent with PKCS#1 v1.5 in the same way as + * mbedtls_rsa_pkcs1_sign(). Before the private key operation, + * apply the padding steps described in RFC 8017, section 9.2 + * "EMSA-PKCS1-v1_5" as follows. + * - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5 + * encoding, treating \p hash as the DigestInfo to be + * padded. In other words, apply EMSA-PKCS1-v1_5 starting + * from step 3, with `T = hash` and `tLen = hash_len`. + * - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5 + * encoding, treating \p hash as the hash to be encoded and + * padded. In other words, apply EMSA-PKCS1-v1_5 starting + * from step 2, with `digestAlgorithm` obtained by calling + * mbedtls_oid_get_oid_by_md() on \p md_alg. + * + * \note For ECDSA signatures, the output format is the DER encoding + * `Ecdsa-Sig-Value` defined in + * [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4). + * + * \param ssl The SSL connection instance. It should not be + * modified other than via + * mbedtls_ssl_set_async_operation_data(). + * \param cert Certificate containing the public key. + * In simple cases, this is one of the pointers passed to + * mbedtls_ssl_conf_own_cert() when configuring the SSL + * connection. However, if other callbacks are used, this + * property may not hold. For example, if an SNI callback + * is registered with mbedtls_ssl_conf_sni(), then + * this callback determines what certificate is used. + * \param md_alg Hash algorithm. + * \param hash Buffer containing the hash. This buffer is + * no longer valid when the function returns. + * \param hash_len Size of the \c hash buffer in bytes. + * + * \return 0 if the operation was started successfully and the SSL + * stack should call the resume callback immediately. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation + * was started successfully and the SSL stack should return + * immediately without calling the resume callback yet. + * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external + * processor does not support this key. The SSL stack will + * use the private key object instead. + * \return Any other error indicates a fatal failure and is + * propagated up the call chain. The callback should + * use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b> + * use \c MBEDTLS_ERR_SSL_xxx error codes except as + * directed in the documentation of this callback. + */ +typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *cert, + mbedtls_md_type_t md_alg, + const unsigned char *hash, + size_t hash_len ); + +/** + * \brief Callback type: start external decryption operation. + * + * This callback is called during an SSL handshake to start + * an RSA decryption operation using an + * external processor. The parameter \p cert contains + * the public key; it is up to the callback function to + * determine how to access the associated private key. + * + * This function typically sends or enqueues a request, and + * does not wait for the operation to complete. This allows + * the handshake step to be non-blocking. + * + * The parameters \p ssl and \p cert are guaranteed to remain + * valid throughout the handshake. On the other hand, this + * function must save the contents of \p input if the value + * is needed for later processing, because the \p input buffer + * is no longer valid after this function returns. + * + * This function may call mbedtls_ssl_set_async_operation_data() + * to store an operation context for later retrieval + * by the resume or cancel callback. + * + * \warning RSA decryption as used in TLS is subject to a potential + * timing side channel attack first discovered by Bleichenbacher + * in 1998. This attack can be remotely exploitable + * in practice. To avoid this attack, you must ensure that + * if the callback performs an RSA decryption, the time it + * takes to execute and return the result does not depend + * on whether the RSA decryption succeeded or reported + * invalid padding. + * + * \param ssl The SSL connection instance. It should not be + * modified other than via + * mbedtls_ssl_set_async_operation_data(). + * \param cert Certificate containing the public key. + * In simple cases, this is one of the pointers passed to + * mbedtls_ssl_conf_own_cert() when configuring the SSL + * connection. However, if other callbacks are used, this + * property may not hold. For example, if an SNI callback + * is registered with mbedtls_ssl_conf_sni(), then + * this callback determines what certificate is used. + * \param input Buffer containing the input ciphertext. This buffer + * is no longer valid when the function returns. + * \param input_len Size of the \p input buffer in bytes. + * + * \return 0 if the operation was started successfully and the SSL + * stack should call the resume callback immediately. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation + * was started successfully and the SSL stack should return + * immediately without calling the resume callback yet. + * \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external + * processor does not support this key. The SSL stack will + * use the private key object instead. + * \return Any other error indicates a fatal failure and is + * propagated up the call chain. The callback should + * use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b> + * use \c MBEDTLS_ERR_SSL_xxx error codes except as + * directed in the documentation of this callback. + */ +typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *cert, + const unsigned char *input, + size_t input_len ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/** + * \brief Callback type: resume external operation. + * + * This callback is called during an SSL handshake to resume + * an external operation started by the + * ::mbedtls_ssl_async_sign_t or + * ::mbedtls_ssl_async_decrypt_t callback. + * + * This function typically checks the status of a pending + * request or causes the request queue to make progress, and + * does not wait for the operation to complete. This allows + * the handshake step to be non-blocking. + * + * This function may call mbedtls_ssl_get_async_operation_data() + * to retrieve an operation context set by the start callback. + * It may call mbedtls_ssl_set_async_operation_data() to modify + * this context. + * + * Note that when this function returns a status other than + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any + * resources associated with the operation. + * + * \param ssl The SSL connection instance. It should not be + * modified other than via + * mbedtls_ssl_set_async_operation_data(). + * \param output Buffer containing the output (signature or decrypted + * data) on success. + * \param output_len On success, number of bytes written to \p output. + * \param output_size Size of the \p output buffer in bytes. + * + * \return 0 if output of the operation is available in the + * \p output buffer. + * \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation + * is still in progress. Subsequent requests for progress + * on the SSL connection will call the resume callback + * again. + * \return Any other error means that the operation is aborted. + * The SSL handshake is aborted. The callback should + * use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b> + * use \c MBEDTLS_ERR_SSL_xxx error codes except as + * directed in the documentation of this callback. + */ +typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl, + unsigned char *output, + size_t *output_len, + size_t output_size ); + +/** + * \brief Callback type: cancel external operation. + * + * This callback is called if an SSL connection is closed + * while an asynchronous operation is in progress. Note that + * this callback is not called if the + * ::mbedtls_ssl_async_resume_t callback has run and has + * returned a value other than + * #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case + * the asynchronous operation has already completed. + * + * This function may call mbedtls_ssl_get_async_operation_data() + * to retrieve an operation context set by the start callback. + * + * \param ssl The SSL connection instance. It should not be + * modified. + */ +typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl ); +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + /* * This structure is used for storing current session data. */ @@ -669,6 +889,16 @@ struct mbedtls_ssl_config mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +#if defined(MBEDTLS_X509_CRT_PARSE_C) + mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */ + mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */ +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */ + mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */ + void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */ +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) const int *sig_hashes; /*!< allowed signature hashes */ #endif @@ -1307,6 +1537,85 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, void *p_export_keys ); #endif /* MBEDTLS_SSL_EXPORT_KEYS */ +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +/** + * \brief Configure asynchronous private key operation callbacks. + * + * \param conf SSL configuration context + * \param f_async_sign Callback to start a signature operation. See + * the description of ::mbedtls_ssl_async_sign_t + * for more information. This may be \c NULL if the + * external processor does not support any signature + * operation; in this case the private key object + * associated with the certificate will be used. + * \param f_async_decrypt Callback to start a decryption operation. See + * the description of ::mbedtls_ssl_async_decrypt_t + * for more information. This may be \c NULL if the + * external processor does not support any decryption + * operation; in this case the private key object + * associated with the certificate will be used. + * \param f_async_resume Callback to resume an asynchronous operation. See + * the description of ::mbedtls_ssl_async_resume_t + * for more information. This may not be \c NULL unless + * \p f_async_sign and \p f_async_decrypt are both + * \c NULL. + * \param f_async_cancel Callback to cancel an asynchronous operation. See + * the description of ::mbedtls_ssl_async_cancel_t + * for more information. This may be \c NULL if + * no cleanup is needed. + * \param config_data A pointer to configuration data which can be + * retrieved with + * mbedtls_ssl_conf_get_async_config_data(). The + * library stores this value without dereferencing it. + */ +void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_async_sign_t *f_async_sign, + mbedtls_ssl_async_decrypt_t *f_async_decrypt, + mbedtls_ssl_async_resume_t *f_async_resume, + mbedtls_ssl_async_cancel_t *f_async_cancel, + void *config_data ); + +/** + * \brief Retrieve the configuration data set by + * mbedtls_ssl_conf_async_private_cb(). + * + * \param conf SSL configuration context + * \return The configuration data set by + * mbedtls_ssl_conf_async_private_cb(). + */ +void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ); + +/** + * \brief Retrieve the asynchronous operation user context. + * + * \note This function may only be called while a handshake + * is in progress. + * + * \param ssl The SSL context to access. + * + * \return The asynchronous operation user context that was last + * set during the current handshake. If + * mbedtls_ssl_set_async_operation_data() has not yet been + * called during the current handshake, this function returns + * \c NULL. + */ +void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ); + +/** + * \brief Retrieve the asynchronous operation user context. + * + * \note This function may only be called while a handshake + * is in progress. + * + * \param ssl The SSL context to access. + * \param ctx The new value of the asynchronous operation user context. + * Call mbedtls_ssl_get_async_operation_data() later during the + * same handshake to retrieve this value. + */ +void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, + void *ctx ); +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + /** * \brief Callback type: generate a cookie * @@ -2117,7 +2426,8 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) /** * \brief Set the maximum fragment length to emit and/or negotiate - * (Default: MBEDTLS_SSL_MAX_CONTENT_LEN, usually 2^14 bytes) + * (Default: the smaller of MBEDTLS_SSL_IN_CONTENT_LEN and + * MBEDTLS_SSL_OUT_CONTENT_LEN, usually 2^14 bytes) * (Server: set maximum fragment length to emit, * usually negotiated by the client during handshake * (Client: set maximum fragment length to emit *and* @@ -2436,7 +2746,6 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ss * \brief Save session in order to resume it later (client-side only) * Session data is copied to presented session structure. * - * \warning Currently, peer certificate is lost in the operation. * * \param ssl SSL context * \param session session context @@ -2444,7 +2753,18 @@ const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ss * \return 0 if successful, * MBEDTLS_ERR_SSL_ALLOC_FAILED if memory allocation failed, * MBEDTLS_ERR_SSL_BAD_INPUT_DATA if used server-side or - * arguments are otherwise invalid + * arguments are otherwise invalid. + * + * \note Only the server certificate is copied, and not the full chain, + * so you should not attempt to validate the certificate again + * by calling \c mbedtls_x509_crt_verify() on it. + * Instead, you should use the results from the verification + * in the original handshake by calling \c mbedtls_ssl_get_verify_result() + * after loading the session again into a new SSL context + * using \c mbedtls_ssl_set_session(). + * + * \note Once the session object is not needed anymore, you should + * free it by calling \c mbedtls_ssl_session_free(). * * \sa mbedtls_ssl_set_session() */ @@ -2606,17 +2926,19 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * or MBEDTLS_ERR_SSL_WANT_WRITE or MBEDTLS_ERR_SSL_WANT_READ, * or another negative error code. * - * \note If this function returns something other than a positive value - * or MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop using - * the SSL context for reading or writing, and either free it or - * call \c mbedtls_ssl_session_reset() on it before re-using it - * for a new connection; the current connection must be closed. + * \note If this function returns something other than 0, a positive + * value or MBEDTLS_ERR_SSL_WANT_READ/WRITE, you must stop + * using the SSL context for reading or writing, and either + * free it or call \c mbedtls_ssl_session_reset() on it before + * re-using it for a new connection; the current connection + * must be closed. * * \note When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, * it must be called later with the *same* arguments, - * until it returns a positive value. When the function returns - * MBEDTLS_ERR_SSL_WANT_WRITE there may be some partial - * data in the output buffer, however this is not yet sent. + * until it returns a value greater that or equal to 0. When + * the function returns MBEDTLS_ERR_SSL_WANT_WRITE there may be + * some partial data in the output buffer, however this is not + * yet sent. * * \note If the requested length is greater than the maximum * fragment length (either the built-in limit or the one set @@ -2625,6 +2947,9 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned. * \c mbedtls_ssl_get_max_frag_len() may be used to query the * active maximum fragment length. + * + * \note Attempting to write 0 bytes will result in an empty TLS + * application record being sent. */ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ); @@ -2717,6 +3042,9 @@ void mbedtls_ssl_session_init( mbedtls_ssl_session *session ); * \brief Free referenced items in an SSL session including the * peer certificate and clear memory * + * \note A session object can be freed even if the SSL context + * that was used to retrieve the session is still in use. + * * \param session SSL session */ void mbedtls_ssl_session_free( mbedtls_ssl_session *session ); diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h index 7d5eba0916..cda8b4835b 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h @@ -271,6 +271,15 @@ extern "C" { #define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */ +/* RFC 7905 */ +#define MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA8 /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0xCCA9 /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0xCCAA /**< TLS 1.2 */ +#define MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAB /**< TLS 1.2 */ +#define MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAC /**< TLS 1.2 */ +#define MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAD /**< TLS 1.2 */ +#define MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 0xCCAE /**< TLS 1.2 */ + /* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below */ diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h index 60b431a0f4..d214703d77 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h @@ -143,32 +143,73 @@ #define MBEDTLS_SSL_PADDING_ADD 0 #endif -#define MBEDTLS_SSL_PAYLOAD_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN \ - + MBEDTLS_SSL_COMPRESSION_ADD \ - + MBEDTLS_MAX_IV_LENGTH \ - + MBEDTLS_SSL_MAC_ADD \ - + MBEDTLS_SSL_PADDING_ADD \ - ) +#define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \ + MBEDTLS_MAX_IV_LENGTH + \ + MBEDTLS_SSL_MAC_ADD + \ + MBEDTLS_SSL_PADDING_ADD \ + ) + +#define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ + ( MBEDTLS_SSL_IN_CONTENT_LEN ) ) + +#define MBEDTLS_SSL_OUT_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ + ( MBEDTLS_SSL_OUT_CONTENT_LEN ) ) + +/* Maximum length we can advertise as our max content length for + RFC 6066 max_fragment_length extension negotiation purposes + (the lesser of both sizes, if they are unequal.) + */ +#define MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ( \ + (MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_OUT_CONTENT_LEN) \ + ? ( MBEDTLS_SSL_OUT_CONTENT_LEN ) \ + : ( MBEDTLS_SSL_IN_CONTENT_LEN ) \ + ) /* * Check that we obey the standard's message size bounds */ #if MBEDTLS_SSL_MAX_CONTENT_LEN > 16384 -#error Bad configuration - record content too large. +#error "Bad configuration - record content too large." +#endif + +#if MBEDTLS_SSL_IN_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN +#error "Bad configuration - incoming record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." +#endif + +#if MBEDTLS_SSL_OUT_CONTENT_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN +#error "Bad configuration - outgoing record content should not be larger than MBEDTLS_SSL_MAX_CONTENT_LEN." +#endif + +#if MBEDTLS_SSL_IN_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 +#error "Bad configuration - incoming protected record payload too large." #endif -#if MBEDTLS_SSL_PAYLOAD_LEN > 16384 + 2048 -#error Bad configuration - protected record payload too large. +#if MBEDTLS_SSL_OUT_PAYLOAD_LEN > MBEDTLS_SSL_MAX_CONTENT_LEN + 2048 +#error "Bad configuration - outgoing protected record payload too large." #endif +/* Calculate buffer sizes */ + /* Note: Even though the TLS record header is only 5 bytes long, we're internally using 8 bytes to store the implicit sequence number. */ #define MBEDTLS_SSL_HEADER_LEN 13 -#define MBEDTLS_SSL_BUFFER_LEN \ - ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_PAYLOAD_LEN ) ) +#define MBEDTLS_SSL_IN_BUFFER_LEN \ + ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) ) + +#define MBEDTLS_SSL_OUT_BUFFER_LEN \ + ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) ) + +#ifdef MBEDTLS_ZLIB_SUPPORT +/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */ +#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \ + ( MBEDTLS_SSL_IN_BUFFER_LEN > MBEDTLS_SSL_OUT_BUFFER_LEN ) \ + ? MBEDTLS_SSL_IN_BUFFER_LEN \ + : MBEDTLS_SSL_OUT_BUFFER_LEN \ + ) +#endif /* * TLS extension flags (for extensions with outgoing ServerHello content @@ -243,6 +284,7 @@ struct mbedtls_ssl_handshake_params mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_X509_CRT_PARSE_C */ + #if defined(MBEDTLS_SSL_PROTO_DTLS) unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ @@ -307,6 +349,19 @@ struct mbedtls_ssl_handshake_params #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) int extended_ms; /*!< use Extended Master Secret? */ #endif + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */ +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + /** Asynchronous operation context. This field is meant for use by the + * asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start, + * mbedtls_ssl_config::f_async_decrypt_start, + * mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel). + * The library does not use it internally. */ + void *user_async_ctx; +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ }; /* @@ -410,9 +465,9 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ); * \brief Free referenced items in an SSL handshake context and clear * memory * - * \param handshake SSL handshake context + * \param ssl SSL context */ -void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ); +void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); @@ -630,7 +685,13 @@ static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t volatile unsigned char diff = 0; for( i = 0; i < n; i++ ) - diff |= A[i] ^ B[i]; + { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } return( diff ); } @@ -646,9 +707,9 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *output, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ); + unsigned char *hash, size_t *hashlen, + unsigned char *data, size_t data_len, + mbedtls_md_type_t md_alg ); #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ MBEDTLS_SSL_PROTO_TLS1_2 */ diff --git a/thirdparty/mbedtls/include/mbedtls/threading.h b/thirdparty/mbedtls/include/mbedtls/threading.h index aeea5d0e1a..c25daa5cdf 100644 --- a/thirdparty/mbedtls/include/mbedtls/threading.h +++ b/thirdparty/mbedtls/include/mbedtls/threading.h @@ -99,9 +99,6 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); #if defined(MBEDTLS_FS_IO) extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; #endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; -#endif #endif /* MBEDTLS_THREADING_C */ #ifdef __cplusplus diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 83e3c1726b..eaf25d908c 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -39,7 +39,7 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 10 +#define MBEDTLS_VERSION_MINOR 12 #define MBEDTLS_VERSION_PATCH 0 /** @@ -47,9 +47,9 @@ * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x020A0000 -#define MBEDTLS_VERSION_STRING "2.10.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.10.0" +#define MBEDTLS_VERSION_NUMBER 0x020C0000 +#define MBEDTLS_VERSION_STRING "2.12.0" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.12.0" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c index fea9b5383d..5c939bba47 100644 --- a/thirdparty/mbedtls/library/aes.c +++ b/thirdparty/mbedtls/library/aes.c @@ -521,6 +521,20 @@ void mbedtls_aes_free( mbedtls_aes_context *ctx ) mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) ); } +#if defined(MBEDTLS_CIPHER_MODE_XTS) +void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx ) +{ + mbedtls_aes_init( &ctx->crypt ); + mbedtls_aes_init( &ctx->tweak ); +} + +void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx ) +{ + mbedtls_aes_free( &ctx->crypt ); + mbedtls_aes_free( &ctx->tweak ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + /* * AES key schedule (encryption) */ @@ -702,6 +716,78 @@ exit: return( ret ); } + +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int mbedtls_aes_xts_decode_keys( const unsigned char *key, + unsigned int keybits, + const unsigned char **key1, + unsigned int *key1bits, + const unsigned char **key2, + unsigned int *key2bits ) +{ + const unsigned int half_keybits = keybits / 2; + const unsigned int half_keybytes = half_keybits / 8; + + switch( keybits ) + { + case 256: break; + case 512: break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + + *key1bits = half_keybits; + *key2bits = half_keybits; + *key1 = &key[0]; + *key2 = &key[half_keybytes]; + + return 0; +} + +int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits) +{ + int ret; + const unsigned char *key1, *key2; + unsigned int key1bits, key2bits; + + ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, + &key2, &key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set the tweak key. Always set tweak key for the encryption mode. */ + ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set crypt key for encryption. */ + return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits ); +} + +int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, + const unsigned char *key, + unsigned int keybits) +{ + int ret; + const unsigned char *key1, *key2; + unsigned int key1bits, key2bits; + + ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits, + &key2, &key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set the tweak key. Always set tweak key for encryption. */ + ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits ); + if( ret != 0 ) + return( ret ); + + /* Set crypt key for decryption. */ + return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ @@ -983,6 +1069,165 @@ int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, } #endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) + +/* Endianess with 64 bits values */ +#ifndef GET_UINT64_LE +#define GET_UINT64_LE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \ + | ( (uint64_t) (b)[(i) + 6] << 48 ) \ + | ( (uint64_t) (b)[(i) + 5] << 40 ) \ + | ( (uint64_t) (b)[(i) + 4] << 32 ) \ + | ( (uint64_t) (b)[(i) + 3] << 24 ) \ + | ( (uint64_t) (b)[(i) + 2] << 16 ) \ + | ( (uint64_t) (b)[(i) + 1] << 8 ) \ + | ( (uint64_t) (b)[(i) ] ); \ +} +#endif + +#ifndef PUT_UINT64_LE +#define PUT_UINT64_LE(n,b,i) \ +{ \ + (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) ] = (unsigned char) ( (n) ); \ +} +#endif + +typedef unsigned char mbedtls_be128[16]; + +/* + * GF(2^128) multiplication function + * + * This function multiplies a field element by x in the polynomial field + * representation. It uses 64-bit word operations to gain speed but compensates + * for machine endianess and hence works correctly on both big and little + * endian machines. + */ +static void mbedtls_gf128mul_x_ble( unsigned char r[16], + const unsigned char x[16] ) +{ + uint64_t a, b, ra, rb; + + GET_UINT64_LE( a, x, 0 ); + GET_UINT64_LE( b, x, 8 ); + + ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) ); + rb = ( a >> 63 ) | ( b << 1 ); + + PUT_UINT64_LE( ra, r, 0 ); + PUT_UINT64_LE( rb, r, 8 ); +} + +/* + * AES-XTS buffer encryption/decryption + */ +int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx, + int mode, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t blocks = length / 16; + size_t leftover = length % 16; + unsigned char tweak[16]; + unsigned char prev_tweak[16]; + unsigned char tmp[16]; + + /* Sectors must be at least 16 bytes. */ + if( length < 16 ) + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + + /* NIST SP 80-38E disallows data units larger than 2**20 blocks. */ + if( length > ( 1 << 20 ) * 16 ) + return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH; + + /* Compute the tweak. */ + ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT, + data_unit, tweak ); + if( ret != 0 ) + return( ret ); + + while( blocks-- ) + { + size_t i; + + if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 ) + { + /* We are on the last block in a decrypt operation that has + * leftover bytes, so we need to use the next tweak for this block, + * and this tweak for the lefover bytes. Save the current tweak for + * the leftovers and then update the current tweak for use on this, + * the last full block. */ + memcpy( prev_tweak, tweak, sizeof( tweak ) ); + mbedtls_gf128mul_x_ble( tweak, tweak ); + } + + for( i = 0; i < 16; i++ ) + tmp[i] = input[i] ^ tweak[i]; + + ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); + if( ret != 0 ) + return( ret ); + + for( i = 0; i < 16; i++ ) + output[i] = tmp[i] ^ tweak[i]; + + /* Update the tweak for the next block. */ + mbedtls_gf128mul_x_ble( tweak, tweak ); + + output += 16; + input += 16; + } + + if( leftover ) + { + /* If we are on the leftover bytes in a decrypt operation, we need to + * use the previous tweak for these bytes (as saved in prev_tweak). */ + unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak; + + /* We are now on the final part of the data unit, which doesn't divide + * evenly by 16. It's time for ciphertext stealing. */ + size_t i; + unsigned char *prev_output = output - 16; + + /* Copy ciphertext bytes from the previous block to our output for each + * byte of cyphertext we won't steal. At the same time, copy the + * remainder of the input for this final round (since the loop bounds + * are the same). */ + for( i = 0; i < leftover; i++ ) + { + output[i] = prev_output[i]; + tmp[i] = input[i] ^ t[i]; + } + + /* Copy ciphertext bytes from the previous block for input in this + * round. */ + for( ; i < 16; i++ ) + tmp[i] = prev_output[i] ^ t[i]; + + ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp ); + if( ret != 0 ) + return ret; + + /* Write the result back to the previous block, overriding the previous + * output we copied. */ + for( i = 0; i < 16; i++ ) + prev_output[i] = tmp[i] ^ t[i]; + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #if defined(MBEDTLS_CIPHER_MODE_CFB) /* * AES-CFB128 buffer encryption/decryption @@ -1061,7 +1306,41 @@ int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, return( 0 ); } -#endif /*MBEDTLS_CIPHER_MODE_CFB */ +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB (Output Feedback Mode) buffer encryption/decryption + */ +int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int ret = 0; + size_t n = *iv_off; + + while( length-- ) + { + if( n == 0 ) + { + ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + if( ret != 0 ) + goto exit; + } + *output++ = *input++ ^ iv[n]; + + n = ( n + 1 ) & 0x0F; + } + + *iv_off = n; + +exit: + return( ret ); +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) /* @@ -1218,6 +1497,72 @@ static const unsigned char aes_test_cfb128_ct[3][64] = }; #endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) +/* + * AES-OFB test vectors from: + * + * https://csrc.nist.gov/publications/detail/sp/800-38a/final + */ +static const unsigned char aes_test_ofb_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_ofb_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_ofb_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_ofb_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, + 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25, + 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, + 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc, + 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, + 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, + 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01, + 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, + 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2, + 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, + 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, + 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d, + 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, + 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08, + 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, + 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 } +}; +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) /* * AES-CTR test vectors from: @@ -1281,6 +1626,74 @@ static const int aes_test_ctr_len[3] = { 16, 32, 36 }; #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +/* + * AES-XTS test vectors from: + * + * IEEE P1619/D16 Annex B + * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf + * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf) + */ +static const unsigned char aes_test_xts_key[][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 }, + { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, + { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }, +}; + +static const unsigned char aes_test_xts_pt32[][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 }, + { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, + { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }, +}; + +static const unsigned char aes_test_xts_ct32[][32] = +{ + { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec, + 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92, + 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85, + 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e }, + { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e, + 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b, + 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4, + 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 }, + { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a, + 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2, + 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53, + 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 }, +}; + +static const unsigned char aes_test_xts_data_unit[][16] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +}; + +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + /* * Checkup routine */ @@ -1297,11 +1710,14 @@ int mbedtls_aes_self_test( int verbose ) #if defined(MBEDTLS_CIPHER_MODE_CBC) unsigned char prv[16]; #endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \ + defined(MBEDTLS_CIPHER_MODE_OFB) size_t offset; #endif -#if defined(MBEDTLS_CIPHER_MODE_CTR) +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS) int len; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) unsigned char nonce_counter[16]; unsigned char stream_block[16]; #endif @@ -1509,6 +1925,69 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( "\n" ); #endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) + /* + * OFB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + keybits = 128 + u * 64; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-OFB-%3d (%s): ", keybits, + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_ofb_iv, 16 ); + memcpy( key, aes_test_ofb_key[u], keybits / 8 ); + + offset = 0; + ret = mbedtls_aes_setkey_enc( &ctx, key, keybits ); + /* + * AES-192 is an optional feature that may be unavailable when + * there is an alternative underlying implementation i.e. when + * MBEDTLS_AES_ALT is defined. + */ + if( ret == MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE && keybits == 192 ) + { + mbedtls_printf( "skipped\n" ); + continue; + } + else if( ret != 0 ) + { + goto exit; + } + + if( mode == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_ofb_ct[u], 64 ); + aes_tests = aes_test_ofb_pt; + } + else + { + memcpy( buf, aes_test_ofb_pt, 64 ); + aes_tests = aes_test_ofb_ct[u]; + } + + ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, aes_tests, 64 ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) /* * CTR mode @@ -1561,6 +2040,73 @@ int mbedtls_aes_self_test( int verbose ) mbedtls_printf( "\n" ); #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) + { + static const int num_tests = + sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key); + mbedtls_aes_xts_context ctx_xts; + + /* + * XTS mode + */ + mbedtls_aes_xts_init( &ctx_xts ); + + for( i = 0; i < num_tests << 1; i++ ) + { + const unsigned char *data_unit; + u = i >> 1; + mode = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-XTS-128 (%s): ", + ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( key, 0, sizeof( key ) ); + memcpy( key, aes_test_xts_key[u], 32 ); + data_unit = aes_test_xts_data_unit[u]; + + len = sizeof( *aes_test_xts_ct32 ); + + if( mode == MBEDTLS_AES_DECRYPT ) + { + ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 ); + if( ret != 0) + goto exit; + memcpy( buf, aes_test_xts_ct32[u], len ); + aes_tests = aes_test_xts_pt32[u]; + } + else + { + ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 ); + if( ret != 0) + goto exit; + memcpy( buf, aes_test_xts_pt32[u], len ); + aes_tests = aes_test_xts_ct32[u]; + } + + + ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit, + buf, buf ); + if( ret != 0 ) + goto exit; + + if( memcmp( buf, aes_tests, len ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + mbedtls_aes_xts_free( &ctx_xts ); + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + ret = 0; exit: diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c index c01c836550..72acdf3012 100644 --- a/thirdparty/mbedtls/library/asn1write.c +++ b/thirdparty/mbedtls/library/asn1write.c @@ -83,7 +83,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 4 ); } +#if SIZE_MAX > 0xFFFFFFFF if( len <= 0xFFFFFFFF ) +#endif { if( *p - start < 5 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); @@ -96,7 +98,9 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 5 ); } +#if SIZE_MAX > 0xFFFFFFFF return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); +#endif } int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c index cf6520935e..804eaf80f1 100644 --- a/thirdparty/mbedtls/library/ccm.c +++ b/thirdparty/mbedtls/library/ccm.c @@ -152,8 +152,10 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * Check length requirements: SP800-38C A.1 * Additional requirement: a < 2^16 - 2^8 to simplify the code. * 'length' checked later (when writing it to the first block) + * + * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4). */ - if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); /* Also implies q is within bounds */ @@ -302,7 +304,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, /* * Authenticated encryption */ -int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, +int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, @@ -312,10 +314,23 @@ int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, add, add_len, input, output, tag, tag_len ) ); } +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + if( tag_len == 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + return( mbedtls_ccm_star_encrypt_and_tag( ctx, length, iv, iv_len, add, + add_len, input, output, tag, tag_len ) ); +} + /* * Authenticated decryption */ -int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, +int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, @@ -346,6 +361,18 @@ int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, return( 0 ); } +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + if( tag_len == 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + return( mbedtls_ccm_star_auth_decrypt( ctx, length, iv, iv_len, add, + add_len, input, output, tag, tag_len ) ); +} #endif /* !MBEDTLS_CCM_ALT */ #if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c new file mode 100644 index 0000000000..d14a51e044 --- /dev/null +++ b/thirdparty/mbedtls/library/chacha20.c @@ -0,0 +1,570 @@ +/** + * \file chacha20.c + * + * \brief ChaCha20 cipher. + * + * \author Daniel King <damaki.gh@gmail.com> + * + * 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_CHACHA20_C) + +#include "mbedtls/chacha20.h" +#include "mbedtls/platform_util.h" + +#include <stddef.h> +#include <string.h> + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdio.h> +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#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 ) \ + | (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 ) + +/** + * \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 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 chacha20_inner_block( uint32_t state[16] ) +{ + 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 ); + + 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 ); +} + +/** + * \brief Generates a keystream block. + * + * \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], + unsigned char keystream[64] ) +{ + uint32_t working_state[16]; + size_t i; + + memcpy( working_state, + initial_state, + CHACHA20_BLOCK_SIZE_BYTES ); + + 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[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++ ) + { + 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->state, sizeof( ctx->state ) ); + mbedtls_platform_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_platform_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->state[0] = 0x61707865; + ctx->state[1] = 0x3320646e; + ctx->state[2] = 0x79622d32; + ctx->state[3] = 0x6b206574; + + /* Set key */ + 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 ); +} + +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->state[12] = counter; + + /* Nonce */ + 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->keystream8, sizeof( ctx->keystream8 ) ); + + /* Initially, there's no keystream bytes available */ + ctx->keystream_bytes_used = CHACHA20_BLOCK_SIZE_BYTES; + + return( 0 ); +} + +int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx, + size_t size, + const unsigned char *input, + unsigned char *output ) +{ + size_t offset = 0U; + size_t i; + + 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 ) + { + 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 ) + { + /* 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 ) + { + 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; + size -= CHACHA20_BLOCK_SIZE_BYTES; + } + + /* Last (partial) block */ + 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++) + { + output[offset + i] = input[offset + i] ^ ctx->keystream8[i]; + } + + ctx->keystream_bytes_used = size; + + } + + return( 0 ); +} + +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 ret; + + mbedtls_chacha20_init( &ctx ); + + ret = mbedtls_chacha20_setkey( &ctx, key ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_chacha20_starts( &ctx, nonce, counter ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_chacha20_update( &ctx, data_len, input, output ); + +cleanup: + mbedtls_chacha20_free( &ctx ); + return( ret ); +} + +#endif /* !MBEDTLS_CHACHA20_ALT */ + +#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 +}; + +#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 ret; + + for( i = 0U; i < 2U; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " ChaCha20 test %u ", i ); + + ret = mbedtls_chacha20_crypt( test_keys[i], + test_nonces[i], + test_counters[i], + test_lengths[i], + test_input[i], + output ); + + ASSERT( 0 == ret, ( "error code: %i\n", ret ) ); + + ASSERT( 0 == memcmp( output, test_output[i], test_lengths[i] ), + ( "failed (output)\n" ) ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* !MBEDTLS_CHACHA20_C */ diff --git a/thirdparty/mbedtls/library/chachapoly.c b/thirdparty/mbedtls/library/chachapoly.c new file mode 100644 index 0000000000..860f877653 --- /dev/null +++ b/thirdparty/mbedtls/library/chachapoly.c @@ -0,0 +1,547 @@ +/** + * \file chachapoly.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_CHACHAPOLY_C) + +#include "mbedtls/chachapoly.h" +#include "mbedtls/platform_util.h" + +#include <string.h> + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdio.h> +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_CHACHAPOLY_ALT) + +#define CHACHAPOLY_STATE_INIT ( 0 ) +#define CHACHAPOLY_STATE_AAD ( 1 ) +#define CHACHAPOLY_STATE_CIPHERTEXT ( 2 ) /* Encrypting or decrypting */ +#define CHACHAPOLY_STATE_FINISHED ( 3 ) + +/** + * \brief Adds nul bytes to pad the AAD for Poly1305. + * + * \param ctx The ChaCha20-Poly1305 context. + */ +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 ) + return( 0 ); + + memset( zeroes, 0, sizeof( zeroes ) ); + + return( mbedtls_poly1305_update( &ctx->poly1305_ctx, + zeroes, + 16U - partial_block_len ) ); +} + +/** + * \brief Adds nul bytes to pad the ciphertext for Poly1305. + * + * \param ctx The ChaCha20-Poly1305 context. + */ +static int 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 ) + 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 ) +{ + 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 = CHACHAPOLY_STATE_INIT; + ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; + } +} + +void mbedtls_chachapoly_free( mbedtls_chachapoly_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 = CHACHAPOLY_STATE_INIT; + ctx->mode = MBEDTLS_CHACHAPOLY_ENCRYPT; + } +} + +int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx, + const unsigned char key[32] ) +{ + int ret; + + if( ( ctx == NULL ) || ( key == NULL ) ) + { + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } + + ret = mbedtls_chacha20_setkey( &ctx->chacha20_ctx, key ); + + return( ret ); +} + +int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx, + const unsigned char nonce[12], + mbedtls_chachapoly_mode_t mode ) +{ + int ret; + unsigned char poly1305_key[64]; + + if( ( ctx == NULL ) || ( nonce == NULL ) ) + { + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } + + /* Set counter = 0, will be update to 1 when generating Poly1305 key */ + 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. + * 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 ) ); + ret = mbedtls_chacha20_update( &ctx->chacha20_ctx, sizeof( poly1305_key ), + poly1305_key, poly1305_key ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_poly1305_starts( &ctx->poly1305_ctx, poly1305_key ); + + if( ret == 0 ) + { + ctx->aad_len = 0U; + ctx->ciphertext_len = 0U; + ctx->state = CHACHAPOLY_STATE_AAD; + ctx->mode = mode; + } + +cleanup: + mbedtls_platform_zeroize( poly1305_key, 64U ); + return( ret ); +} + +int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx, + const unsigned char *aad, + size_t aad_len ) +{ + if( ctx == NULL ) + { + 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_POLY1305_BAD_INPUT_DATA ); + } + else if( ctx->state != CHACHAPOLY_STATE_AAD ) + { + return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + } + + ctx->aad_len += aad_len; + + return( mbedtls_poly1305_update( &ctx->poly1305_ctx, aad, aad_len ) ); +} + +int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx, + size_t len, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + + if( ctx == NULL ) + { + 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_POLY1305_BAD_INPUT_DATA ); + } + else if( ( ctx->state != CHACHAPOLY_STATE_AAD ) && + ( ctx->state != CHACHAPOLY_STATE_CIPHERTEXT ) ) + { + return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + } + + if( ctx->state == CHACHAPOLY_STATE_AAD ) + { + ctx->state = CHACHAPOLY_STATE_CIPHERTEXT; + + ret = chachapoly_pad_aad( ctx ); + if( ret != 0 ) + return( ret ); + } + + ctx->ciphertext_len += len; + + if( ctx->mode == MBEDTLS_CHACHAPOLY_ENCRYPT ) + { + 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 */ + { + 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 ); +} + +int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx, + unsigned char mac[16] ) +{ + int ret; + unsigned char len_block[16]; + + if( ( ctx == NULL ) || ( mac == NULL ) ) + { + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + } + else if( ctx->state == CHACHAPOLY_STATE_INIT ) + { + return( MBEDTLS_ERR_CHACHAPOLY_BAD_STATE ); + } + + if( ctx->state == CHACHAPOLY_STATE_AAD ) + { + ret = chachapoly_pad_aad( ctx ); + if( ret != 0 ) + return( ret ); + } + else if( ctx->state == CHACHAPOLY_STATE_CIPHERTEXT ) + { + ret = chachapoly_pad_ciphertext( ctx ); + if( ret != 0 ) + return( ret ); + } + + 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. + */ + 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 ); + + ret = mbedtls_poly1305_update( &ctx->poly1305_ctx, len_block, 16U ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_poly1305_finish( &ctx->poly1305_ctx, mac ); + + return( ret ); +} + +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; + + ret = mbedtls_chachapoly_starts( ctx, nonce, mode ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_chachapoly_update_aad( ctx, aad, aad_len ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_chachapoly_update( ctx, length, input, output ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_chachapoly_finish( ctx, tag ); + +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], + 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( tag == NULL ) + return( MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA ); + + if( ( ret = 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_platform_zeroize( output, length ); + return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ); + } + + return( 0 ); +} + +#endif /* MBEDTLS_CHACHAPOLY_ALT */ + +#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 + } +}; + +#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; + unsigned i; + int ret; + unsigned char output[200]; + unsigned char mac[16]; + + for( i = 0U; i < 1U; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " ChaCha20-Poly1305 test %u ", i ); + + mbedtls_chachapoly_init( &ctx ); + + ret = mbedtls_chachapoly_setkey( &ctx, test_key[i] ); + ASSERT( 0 == ret, ( "setkey() error code: %i\n", ret ) ); + + 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 ) ); + + 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 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_CHACHAPOLY_C */ diff --git a/thirdparty/mbedtls/library/cipher.c b/thirdparty/mbedtls/library/cipher.c index a5cd61cdf3..7ae6c4ac5d 100644 --- a/thirdparty/mbedtls/library/cipher.c +++ b/thirdparty/mbedtls/library/cipher.c @@ -38,6 +38,10 @@ #include <stdlib.h> #include <string.h> +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + #if defined(MBEDTLS_GCM_C) #include "mbedtls/gcm.h" #endif @@ -46,6 +50,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 @@ -57,9 +65,25 @@ #define mbedtls_free free #endif -#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) -#define MBEDTLS_CIPHER_MODE_STREAM -#endif +#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. + * 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; + 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; +} +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ static int supported_init = 0; @@ -191,10 +215,11 @@ int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *k ctx->operation = operation; /* - * For CFB and CTR mode always use the encryption key schedule + * For OFB, CFB and CTR mode always use the encryption key schedule */ if( MBEDTLS_ENCRYPT == operation || MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) { return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, @@ -231,6 +256,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; @@ -247,22 +284,45 @@ int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) return( 0 ); } -#if defined(MBEDTLS_GCM_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 ) { 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_CHACHAPOLY_C) + if (MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + int result; + mbedtls_chachapoly_mode_t mode; + + mode = ( ctx->operation == MBEDTLS_ENCRYPT ) + ? MBEDTLS_CHACHAPOLY_ENCRYPT + : MBEDTLS_CHACHAPOLY_DECRYPT; + + result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ctx->iv, + mode ); + if ( result != 0 ) + return( result ); + + return mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ad, ad_len ); + } +#endif return( 0 ); } -#endif /* MBEDTLS_GCM_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 ) @@ -303,6 +363,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; @@ -424,6 +493,21 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) + if( ctx->cipher_info->mode == MBEDTLS_MODE_OFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->ofb_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) { @@ -440,6 +524,27 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) + if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) + { + if( ctx->unprocessed_len > 0 ) { + /* We can only process an entire data unit at a time. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ); + if( ret != 0 ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #if defined(MBEDTLS_CIPHER_MODE_STREAM) if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) { @@ -639,13 +744,21 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, *olen = 0; if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_OFB == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ctx->cipher_info->mode || MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_XTS == ctx->cipher_info->mode || MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) { return( 0 ); } + if ( ( MBEDTLS_CIPHER_CHACHA20 == ctx->cipher_info->type ) || + ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) ) + { + return( 0 ); + } + if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) { if( ctx->unprocessed_len != 0 ) @@ -757,7 +870,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_CHACHAPOLY_C) int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, unsigned char *tag, size_t tag_len ) { @@ -767,8 +880,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_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_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + tag ); + } +#endif return( 0 ); } @@ -776,6 +903,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 || @@ -784,12 +912,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 ); @@ -800,18 +925,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( 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_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 ); - if( diff != 0 ) + ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_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_CHACHAPOLY_C */ return( 0 ); } -#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_GCM_C || MBEDTLS_CHACHAPOLY_C */ /* * Packet-oriented wrapper for non-AEAD modes @@ -870,6 +1015,21 @@ int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, tag, tag_len ) ); } #endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CHACHAPOLY_C) + if ( MBEDTLS_CIPHER_CHACHA20_POLY1305 == ctx->cipher_info->type ) + { + /* ChachaPoly has fixed length nonce and MAC (tag) */ + if ( ( iv_len != ctx->cipher_info->iv_size ) || + ( tag_len != 16U ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = ilen; + return( mbedtls_chachapoly_encrypt_and_tag( ctx->cipher_ctx, + ilen, iv, ad, ad_len, input, output, tag ) ); + } +#endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } @@ -916,6 +1076,28 @@ int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, return( ret ); } #endif /* MBEDTLS_CCM_C */ +#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 ) ) + { + 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 ); + + if( ret == MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_CHACHAPOLY_C */ return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); } diff --git a/thirdparty/mbedtls/library/cipher_wrap.c b/thirdparty/mbedtls/library/cipher_wrap.c index a9ef8195ca..893490acc8 100644 --- a/thirdparty/mbedtls/library/cipher_wrap.c +++ b/thirdparty/mbedtls/library/cipher_wrap.c @@ -33,6 +33,10 @@ #include "mbedtls/cipher_internal.h" +#if defined(MBEDTLS_CHACHAPOLY_C) +#include "mbedtls/chachapoly.h" +#endif + #if defined(MBEDTLS_AES_C) #include "mbedtls/aes.h" #endif @@ -57,6 +61,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 @@ -142,6 +150,15 @@ static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, } #endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) +static int aes_crypt_ofb_wrap( void *ctx, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ofb( (mbedtls_aes_context *) ctx, length, iv_off, + iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block, @@ -152,6 +169,33 @@ static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, } #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + int mode; + + switch( operation ) + { + case MBEDTLS_ENCRYPT: + mode = MBEDTLS_AES_ENCRYPT; + break; + case MBEDTLS_DECRYPT: + mode = MBEDTLS_AES_DECRYPT; + break; + default: + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_aes_crypt_xts( xts_ctx, mode, length, + data_unit, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_bitlen ) { @@ -191,9 +235,15 @@ static const mbedtls_cipher_base_t aes_info = { #if defined(MBEDTLS_CIPHER_MODE_CFB) aes_crypt_cfb128_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + aes_crypt_ofb_wrap, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) aes_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -306,6 +356,41 @@ static const mbedtls_cipher_info_t aes_256_cfb128_info = { }; #endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) +static const mbedtls_cipher_info_t aes_128_ofb_info = { + MBEDTLS_CIPHER_AES_128_OFB, + MBEDTLS_MODE_OFB, + 128, + "AES-128-OFB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ofb_info = { + MBEDTLS_CIPHER_AES_192_OFB, + MBEDTLS_MODE_OFB, + 192, + "AES-192-OFB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ofb_info = { + MBEDTLS_CIPHER_AES_256_OFB, + MBEDTLS_MODE_OFB, + 256, + "AES-256-OFB", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_OFB */ + #if defined(MBEDTLS_CIPHER_MODE_CTR) static const mbedtls_cipher_info_t aes_128_ctr_info = { MBEDTLS_CIPHER_AES_128_CTR, @@ -341,6 +426,92 @@ static const mbedtls_cipher_info_t aes_256_ctr_info = { }; #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); +} + +static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); +} + +static void *xts_aes_ctx_alloc( void ) +{ + mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); + + if( xts_ctx != NULL ) + mbedtls_aes_xts_init( xts_ctx ); + + return( xts_ctx ); +} + +static void xts_aes_ctx_free( void *ctx ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + + if( xts_ctx == NULL ) + return; + + mbedtls_aes_xts_free( xts_ctx ); + mbedtls_free( xts_ctx ); +} + +static const mbedtls_cipher_base_t xts_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#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) + aes_crypt_xts_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + xts_aes_setkey_enc_wrap, + xts_aes_setkey_dec_wrap, + xts_aes_ctx_alloc, + xts_aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_xts_info = { + MBEDTLS_CIPHER_AES_128_XTS, + MBEDTLS_MODE_XTS, + 256, + "AES-128-XTS", + 16, + 0, + 16, + &xts_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_xts_info = { + MBEDTLS_CIPHER_AES_256_XTS, + MBEDTLS_MODE_XTS, + 512, + "AES-256-XTS", + 16, + 0, + 16, + &xts_aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #if defined(MBEDTLS_GCM_C) static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_bitlen ) @@ -358,9 +529,15 @@ static const mbedtls_cipher_base_t gcm_aes_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 @@ -421,9 +598,15 @@ static const mbedtls_cipher_base_t ccm_aes_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 @@ -548,9 +731,15 @@ static const mbedtls_cipher_base_t camellia_info = { #if defined(MBEDTLS_CIPHER_MODE_CFB) camellia_crypt_cfb128_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) camellia_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -715,9 +904,15 @@ static const mbedtls_cipher_base_t gcm_camellia_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 @@ -778,9 +973,15 @@ static const mbedtls_cipher_base_t ccm_camellia_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 @@ -906,9 +1107,15 @@ static const mbedtls_cipher_base_t aria_info = { #if defined(MBEDTLS_CIPHER_MODE_CFB) aria_crypt_cfb128_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) aria_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -1073,9 +1280,15 @@ static const mbedtls_cipher_base_t gcm_aria_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 @@ -1136,9 +1349,15 @@ static const mbedtls_cipher_base_t ccm_aria_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 @@ -1312,9 +1531,15 @@ static const mbedtls_cipher_base_t des_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 @@ -1357,9 +1582,15 @@ static const mbedtls_cipher_base_t des_ede_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 @@ -1402,9 +1633,15 @@ static const mbedtls_cipher_base_t des_ede3_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 @@ -1511,9 +1748,15 @@ static const mbedtls_cipher_base_t blowfish_info = { #if defined(MBEDTLS_CIPHER_MODE_CFB) blowfish_crypt_cfb64_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) blowfish_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -1621,9 +1864,15 @@ static const mbedtls_cipher_base_t arc4_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) arc4_crypt_stream_wrap, #endif @@ -1645,6 +1894,162 @@ 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 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; + 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_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 + 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_STREAM, + 256, + "CHACHA20", + 12, + 0, + 1, + &chacha20_base_info +}; +#endif /* MBEDTLS_CHACHA20_C */ + +#if defined(MBEDTLS_CHACHAPOLY_C) + +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_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + return( 0 ); +} + +static void * chachapoly_ctx_alloc( void ) +{ + mbedtls_chachapoly_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_chachapoly_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_chachapoly_init( ctx ); + + return( ctx ); +} + +static void chachapoly_ctx_free( void *ctx ) +{ + mbedtls_chachapoly_free( (mbedtls_chachapoly_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t chachapoly_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_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 + chachapoly_setkey_wrap, + chachapoly_setkey_wrap, + chachapoly_ctx_alloc, + chachapoly_ctx_free +}; +static const mbedtls_cipher_info_t chachapoly_info = { + MBEDTLS_CIPHER_CHACHA20_POLY1305, + MBEDTLS_MODE_CHACHAPOLY, + 256, + "CHACHA20-POLY1305", + 12, + 0, + 1, + &chachapoly_base_info +}; +#endif /* MBEDTLS_CHACHAPOLY_C */ + #if defined(MBEDTLS_CIPHER_NULL_CIPHER) static int null_crypt_stream( void *ctx, size_t length, const unsigned char *input, @@ -1684,9 +2089,15 @@ static const mbedtls_cipher_base_t null_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_crypt_stream, #endif @@ -1724,11 +2135,20 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, #endif +#if defined(MBEDTLS_CIPHER_MODE_OFB) + { MBEDTLS_CIPHER_AES_128_OFB, &aes_128_ofb_info }, + { MBEDTLS_CIPHER_AES_192_OFB, &aes_192_ofb_info }, + { MBEDTLS_CIPHER_AES_256_OFB, &aes_256_ofb_info }, +#endif #if defined(MBEDTLS_CIPHER_MODE_CTR) { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, + { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, +#endif #if defined(MBEDTLS_GCM_C) { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, @@ -1831,6 +2251,14 @@ 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_CHACHAPOLY_C) + { MBEDTLS_CIPHER_CHACHA20_POLY1305, &chachapoly_info }, +#endif + #if defined(MBEDTLS_CIPHER_NULL_CIPHER) { MBEDTLS_CIPHER_NULL, &null_cipher_info }, #endif /* MBEDTLS_CIPHER_NULL_CIPHER */ diff --git a/thirdparty/mbedtls/library/cmac.c b/thirdparty/mbedtls/library/cmac.c index 4d7a1f1693..5d101e1c7d 100644 --- a/thirdparty/mbedtls/library/cmac.c +++ b/thirdparty/mbedtls/library/cmac.c @@ -828,6 +828,7 @@ static int cmac_test_subkeys( int verbose, mbedtls_cipher_free( &ctx ); } + ret = 0; goto exit; cleanup: @@ -883,6 +884,7 @@ static int cmac_test_wth_cipher( int verbose, if( verbose != 0 ) mbedtls_printf( "passed\n" ); } + ret = 0; exit: return( ret ); diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index cefe882d2a..f44a753f4d 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -19,19 +19,25 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ +#if defined(__linux__) +/* Ensure that syscall() is available even when compiling with -std=c99 */ +#define _GNU_SOURCE +#endif + #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif +#include <string.h> + #if defined(MBEDTLS_ENTROPY_C) #include "mbedtls/entropy.h" #include "mbedtls/entropy_poll.h" #if defined(MBEDTLS_TIMING_C) -#include <string.h> #include "mbedtls/timing.h" #endif #if defined(MBEDTLS_HAVEGE_C) @@ -44,7 +50,8 @@ #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) + !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ + !defined(__HAIKU__) #error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" #endif diff --git a/thirdparty/mbedtls/library/entropy_poll.c.orig b/thirdparty/mbedtls/library/entropy_poll.c.orig new file mode 100644 index 0000000000..040aa117dc --- /dev/null +++ b/thirdparty/mbedtls/library/entropy_poll.c.orig @@ -0,0 +1,275 @@ +/* + * Platform-specific and custom entropy polling functions + * + * 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(__linux__) +/* Ensure that syscall() is available even when compiling with -std=c99 */ +#define _GNU_SOURCE +#endif + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include <string.h> + +#if defined(MBEDTLS_ENTROPY_C) + +#include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" + +#if defined(MBEDTLS_TIMING_C) +#include "mbedtls/timing.h" +#endif +#if defined(MBEDTLS_HAVEGE_C) +#include "mbedtls/havege.h" +#endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#include "mbedtls/platform.h" +#endif + +#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) + +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ + !defined(__HAIKU__) +#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif +#include <windows.h> +#include <wincrypt.h> + +int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) +{ + HCRYPTPROV provider; + ((void) data); + *olen = 0; + + if( CryptAcquireContext( &provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) + { + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) + { + CryptReleaseContext( provider, 0 ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + CryptReleaseContext( provider, 0 ); + *olen = len; + + return( 0 ); +} +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +/* + * Test for Linux getrandom() support. + * Since there is no wrapper in the libc yet, use the generic syscall wrapper + * available in GNU libc and compatible libc's (eg uClibc). + */ +#if defined(__linux__) && defined(__GLIBC__) +#include <unistd.h> +#include <sys/syscall.h> +#if defined(SYS_getrandom) +#define HAVE_GETRANDOM + +static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) +{ + /* MemSan cannot understand that the syscall writes to the buffer */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + memset( buf, 0, buflen ); +#endif +#endif + + return( syscall( SYS_getrandom, buf, buflen, flags ) ); +} + +#include <sys/utsname.h> +/* Check if version is at least 3.17.0 */ +static int check_version_3_17_plus( void ) +{ + int minor; + struct utsname un; + const char *ver; + + /* Get version information */ + uname(&un); + ver = un.release; + + /* Check major version; assume a single digit */ + if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' ) + return( -1 ); + + if( ver[0] - '0' > 3 ) + return( 0 ); + + /* Ok, so now we know major == 3, check minor. + * Assume 1 or 2 digits. */ + if( ver[2] < '0' || ver[2] > '9' ) + return( -1 ); + + minor = ver[2] - '0'; + + if( ver[3] >= '0' && ver[3] <= '9' ) + minor = 10 * minor + ver[3] - '0'; + else if( ver [3] != '.' ) + return( -1 ); + + if( minor < 17 ) + return( -1 ); + + return( 0 ); +} +static int has_getrandom = -1; +#endif /* SYS_getrandom */ +#endif /* __linux__ */ + +#include <stdio.h> + +int mbedtls_platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + FILE *file; + size_t read_len; + ((void) data); + +#if defined(HAVE_GETRANDOM) + if( has_getrandom == -1 ) + has_getrandom = ( check_version_3_17_plus() == 0 ); + + if( has_getrandom ) + { + int ret; + + if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = ret; + return( 0 ); + } +#endif /* HAVE_GETRANDOM */ + + *olen = 0; + + file = fopen( "/dev/urandom", "rb" ); + if( file == NULL ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + read_len = fread( output, 1, len, file ); + if( read_len != len ) + { + fclose( file ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + fclose( file ); + *olen = len; + + return( 0 ); +} +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) +int mbedtls_null_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + ((void) data); + ((void) output); + *olen = 0; + + if( len < sizeof(unsigned char) ) + return( 0 ); + + *olen = sizeof(unsigned char); + + return( 0 ); +} +#endif + +#if defined(MBEDTLS_TIMING_C) +int mbedtls_hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned long timer = mbedtls_timing_hardclock(); + ((void) data); + *olen = 0; + + if( len < sizeof(unsigned long) ) + return( 0 ); + + memcpy( output, &timer, sizeof(unsigned long) ); + *olen = sizeof(unsigned long); + + return( 0 ); +} +#endif /* MBEDTLS_TIMING_C */ + +#if defined(MBEDTLS_HAVEGE_C) +int mbedtls_havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + mbedtls_havege_state *hs = (mbedtls_havege_state *) data; + *olen = 0; + + if( mbedtls_havege_random( hs, output, len ) != 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = len; + + return( 0 ); +} +#endif /* MBEDTLS_HAVEGE_C */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +int mbedtls_nv_seed_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; + size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; + ((void) data); + + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + if( len < use_len ) + use_len = len; + + memcpy( output, buf, use_len ); + *olen = use_len; + + return( 0 ); +} +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#endif /* MBEDTLS_ENTROPY_C */ diff --git a/thirdparty/mbedtls/library/error.c b/thirdparty/mbedtls/library/error.c index 8818054c56..774244b454 100644 --- a/thirdparty/mbedtls/library/error.c +++ b/thirdparty/mbedtls/library/error.c @@ -73,6 +73,14 @@ #include "mbedtls/ccm.h" #endif +#if defined(MBEDTLS_CHACHA20_C) +#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 @@ -105,6 +113,10 @@ #include "mbedtls/gcm.h" #endif +#if defined(MBEDTLS_HKDF_C) +#include "mbedtls/hkdf.h" +#endif + #if defined(MBEDTLS_HMAC_DRBG_C) #include "mbedtls/hmac_drbg.h" #endif @@ -153,6 +165,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 @@ -497,6 +513,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) ) mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" ); + if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) ) + mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" ); #endif /* MBEDTLS_SSL_TLS_C */ #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) @@ -670,6 +688,22 @@ 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)" ); + 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_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" ); +#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" ); @@ -715,6 +749,11 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); #endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_HKDF_C) + if( use_ret == -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "HKDF - Bad input parameters to function" ); +#endif /* MBEDTLS_HKDF_C */ + #if defined(MBEDTLS_HMAC_DRBG_C) if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); @@ -782,6 +821,15 @@ 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)" ); + 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) if( use_ret == -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED) ) mbedtls_snprintf( buf, buflen, "RIPEMD160 - RIPEMD160 hardware accelerator failed" ); diff --git a/thirdparty/mbedtls/library/hkdf.c b/thirdparty/mbedtls/library/hkdf.c new file mode 100644 index 0000000000..82d8a429f4 --- /dev/null +++ b/thirdparty/mbedtls/library/hkdf.c @@ -0,0 +1,192 @@ +/* + * HKDF implementation -- RFC 5869 + * + * Copyright (C) 2016-2018, 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_HKDF_C) + +#include <string.h> +#include "mbedtls/hkdf.h" +#include "mbedtls/platform_util.h" + +int mbedtls_hkdf( const mbedtls_md_info_t *md, const unsigned char *salt, + size_t salt_len, const unsigned char *ikm, size_t ikm_len, + const unsigned char *info, size_t info_len, + unsigned char *okm, size_t okm_len ) +{ + int ret; + unsigned char prk[MBEDTLS_MD_MAX_SIZE]; + + ret = mbedtls_hkdf_extract( md, salt, salt_len, ikm, ikm_len, prk ); + + if( ret == 0 ) + { + ret = mbedtls_hkdf_expand( md, prk, mbedtls_md_get_size( md ), + info, info_len, okm, okm_len ); + } + + mbedtls_platform_zeroize( prk, sizeof( prk ) ); + + return( ret ); +} + +int mbedtls_hkdf_extract( const mbedtls_md_info_t *md, + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len, + unsigned char *prk ) +{ + unsigned char null_salt[MBEDTLS_MD_MAX_SIZE] = { '\0' }; + + if( salt == NULL ) + { + size_t hash_len; + + if( salt_len != 0 ) + { + return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; + } + + hash_len = mbedtls_md_get_size( md ); + + if( hash_len == 0 ) + { + return MBEDTLS_ERR_HKDF_BAD_INPUT_DATA; + } + + salt = null_salt; + salt_len = hash_len; + } + + return( mbedtls_md_hmac( md, salt, salt_len, ikm, ikm_len, prk ) ); +} + +int mbedtls_hkdf_expand( const mbedtls_md_info_t *md, const unsigned char *prk, + size_t prk_len, const unsigned char *info, + size_t info_len, unsigned char *okm, size_t okm_len ) +{ + size_t hash_len; + size_t where = 0; + size_t n; + size_t t_len = 0; + size_t i; + int ret = 0; + mbedtls_md_context_t ctx; + unsigned char t[MBEDTLS_MD_MAX_SIZE]; + + if( okm == NULL ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + hash_len = mbedtls_md_get_size( md ); + + if( prk_len < hash_len || hash_len == 0 ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + if( info == NULL ) + { + info = (const unsigned char *) ""; + info_len = 0; + } + + n = okm_len / hash_len; + + if( (okm_len % hash_len) != 0 ) + { + n++; + } + + /* + * Per RFC 5869 Section 2.3, okm_len must not exceed + * 255 times the hash length + */ + if( n > 255 ) + { + return( MBEDTLS_ERR_HKDF_BAD_INPUT_DATA ); + } + + mbedtls_md_init( &ctx ); + + if( (ret = mbedtls_md_setup( &ctx, md, 1) ) != 0 ) + { + goto exit; + } + + /* + * Compute T = T(1) | T(2) | T(3) | ... | T(N) + * Where T(N) is defined in RFC 5869 Section 2.3 + */ + for( i = 1; i <= n; i++ ) + { + size_t num_to_copy; + unsigned char c = i & 0xff; + + ret = mbedtls_md_hmac_starts( &ctx, prk, prk_len ); + if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_md_hmac_update( &ctx, t, t_len ); + if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_md_hmac_update( &ctx, info, info_len ); + if( ret != 0 ) + { + goto exit; + } + + /* The constant concatenated to the end of each T(n) is a single octet. + * */ + ret = mbedtls_md_hmac_update( &ctx, &c, 1 ); + if( ret != 0 ) + { + goto exit; + } + + ret = mbedtls_md_hmac_finish( &ctx, t ); + if( ret != 0 ) + { + goto exit; + } + + num_to_copy = i != n ? hash_len : okm_len - where; + memcpy( okm + where, t, num_to_copy ); + where += hash_len; + t_len = hash_len; + } + +exit: + mbedtls_md_free( &ctx ); + mbedtls_platform_zeroize( t, sizeof( t ) ); + + return( ret ); +} + +#endif /* MBEDTLS_HKDF_C */ diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c index 8238c2b81a..2a740cda81 100644 --- a/thirdparty/mbedtls/library/md5.c +++ b/thirdparty/mbedtls/library/md5.c @@ -309,14 +309,6 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, } #endif -static const unsigned char md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - /* * MD5 final digest */ @@ -324,26 +316,48 @@ int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, unsigned char output[16] ) { int ret; - uint32_t last, padn; + uint32_t used; uint32_t high, low; - unsigned char msglen[8]; - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->total[0] & 0x3F; - PUT_UINT32_LE( low, msglen, 0 ); - PUT_UINT32_LE( high, msglen, 4 ); + ctx->buffer[used++] = 0x80; - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + if( used <= 56 ) + { + /* Enough room for padding + length in current block */ + memset( ctx->buffer + used, 0, 56 - used ); + } + else + { + /* We'll need an extra block */ + memset( ctx->buffer + used, 0, 64 - used ); - if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 ) + if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); - if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 ) - return( ret ); + memset( ctx->buffer, 0, 56 ); + } + + /* + * Add message length + */ + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, ctx->buffer, 56 ); + PUT_UINT32_LE( high, ctx->buffer, 60 ); + + if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + /* + * Output final state + */ PUT_UINT32_LE( ctx->state[0], output, 0 ); PUT_UINT32_LE( ctx->state[1], output, 4 ); PUT_UINT32_LE( ctx->state[2], output, 8 ); diff --git a/thirdparty/mbedtls/library/memory_buffer_alloc.c b/thirdparty/mbedtls/library/memory_buffer_alloc.c index ceaeda1e73..51ea7c41d7 100644 --- a/thirdparty/mbedtls/library/memory_buffer_alloc.c +++ b/thirdparty/mbedtls/library/memory_buffer_alloc.c @@ -518,7 +518,9 @@ void mbedtls_memory_buffer_alloc_status( void ) heap.alloc_count, heap.free_count ); if( heap.first->next == NULL ) + { mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); + } else { mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); diff --git a/thirdparty/mbedtls/library/net_sockets.c b/thirdparty/mbedtls/library/net_sockets.c index 9b0a375fb7..816b1303df 100644 --- a/thirdparty/mbedtls/library/net_sockets.c +++ b/thirdparty/mbedtls/library/net_sockets.c @@ -19,6 +19,11 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ +/* Enable definition of getaddrinfo() even when compiling with -std=c99. Must + * be set before config.h, which pulls in glibc's features.h indirectly. + * Harmless on other platforms. */ +#define _POSIX_C_SOURCE 200112L + #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" #else @@ -28,7 +33,8 @@ #if defined(MBEDTLS_NET_C) #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) + !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ + !defined(__HAIKU__) #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" #endif @@ -47,13 +53,11 @@ #define IS_EINTR( ret ) ( ( ret ) == WSAEINTR ) -/* GODOT ADDITION */ #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) #undef _WIN32_WINNT /* Enables getaddrinfo() & Co */ #define _WIN32_WINNT 0x0501 #endif -/* END GODOT ADDITION */ #include <ws2tcpip.h> diff --git a/thirdparty/mbedtls/library/nist_kw.c b/thirdparty/mbedtls/library/nist_kw.c new file mode 100644 index 0000000000..176af9fe08 --- /dev/null +++ b/thirdparty/mbedtls/library/nist_kw.c @@ -0,0 +1,755 @@ +/* + * Implementation of NIST SP 800-38F key wrapping, supporting KW and KWP modes + * only + * + * Copyright (C) 2018, Arm Limited (or its affiliates), All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + */ +/* + * Definition of Key Wrapping: + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf + * RFC 3394 "Advanced Encryption Standard (AES) Key Wrap Algorithm" + * RFC 5649 "Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm" + * + * Note: RFC 3394 defines different methodology for intermediate operations for + * the wrapping and unwrapping operation than the definition in NIST SP 800-38F. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_NIST_KW_C) + +#include "mbedtls/nist_kw.h" +#include "mbedtls/platform_util.h" + +#include <stdint.h> +#include <string.h> + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdio.h> +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#if !defined(MBEDTLS_NIST_KW_ALT) + +#define KW_SEMIBLOCK_LENGTH 8 +#define MIN_SEMIBLOCKS_COUNT 3 + +/* constant-time buffer comparison */ +static inline unsigned char mbedtls_nist_kw_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + volatile const unsigned char *A = (volatile const unsigned char *) a; + volatile const unsigned char *B = (volatile const unsigned char *) b; + volatile unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + { + /* Read volatile data in order before computing diff. + * This avoids IAR compiler warning: + * 'the order of volatile accesses is undefined ..' */ + unsigned char x = A[i], y = B[i]; + diff |= x ^ y; + } + + return( diff ); +} + +/*! The 64-bit default integrity check value (ICV) for KW mode. */ +static const unsigned char NIST_KW_ICV1[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; +/*! The 32-bit default integrity check value (ICV) for KWP mode. */ +static const unsigned char NIST_KW_ICV2[] = {0xA6, 0x59, 0x59, 0xA6}; + +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +do { \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} while( 0 ) +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +do { \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} while( 0 ) +#endif + +/* + * Initialize context + */ +void mbedtls_nist_kw_init( mbedtls_nist_kw_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_nist_kw_context ) ); +} + +int mbedtls_nist_kw_setkey( mbedtls_nist_kw_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits, + const int is_wrap ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, + keybits, + MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* + * SP 800-38F currently defines AES cipher as the only block cipher allowed: + * "For KW and KWP, the underlying block cipher shall be approved, and the + * block size shall be 128 bits. Currently, the AES block cipher, with key + * lengths of 128, 192, or 256 bits, is the only block cipher that fits + * this profile." + * Currently we don't support other 128 bit block ciphers for key wrapping, + * such as Camellia and Aria. + */ + if( cipher != MBEDTLS_CIPHER_ID_AES ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + is_wrap ? MBEDTLS_ENCRYPT : + MBEDTLS_DECRYPT ) + ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void mbedtls_nist_kw_free( mbedtls_nist_kw_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_nist_kw_context ) ); +} + +/* + * Helper function for Xoring the uint64_t "t" with the encrypted A. + * Defined in NIST SP 800-38F section 6.1 + */ +static void calc_a_xor_t( unsigned char A[KW_SEMIBLOCK_LENGTH], uint64_t t ) +{ + size_t i = 0; + for( i = 0; i < sizeof( t ); i++ ) + { + A[i] ^= ( t >> ( ( sizeof( t ) - 1 - i ) * 8 ) ) & 0xff; + } +} + +/* + * KW-AE as defined in SP 800-38F section 6.2 + * KWP-AE as defined in SP 800-38F section 6.3 + */ +int mbedtls_nist_kw_wrap( mbedtls_nist_kw_context *ctx, + mbedtls_nist_kw_mode_t mode, + const unsigned char *input, size_t in_len, + unsigned char *output, size_t *out_len, size_t out_size ) +{ + int ret = 0; + size_t semiblocks = 0; + size_t s; + size_t olen, padlen = 0; + uint64_t t = 0; + unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; + unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; + unsigned char *R2 = output + KW_SEMIBLOCK_LENGTH; + unsigned char *A = output; + + *out_len = 0; + /* + * Generate the String to work on + */ + if( mode == MBEDTLS_KW_MODE_KW ) + { + if( out_size < in_len + KW_SEMIBLOCK_LENGTH ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + /* + * According to SP 800-38F Table 1, the plaintext length for KW + * must be between 2 to 2^54-1 semiblocks inclusive. + */ + if( in_len < 16 || +#if SIZE_MAX > 0x1FFFFFFFFFFFFF8 + in_len > 0x1FFFFFFFFFFFFF8 || +#endif + in_len % KW_SEMIBLOCK_LENGTH != 0 ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( output, NIST_KW_ICV1, KW_SEMIBLOCK_LENGTH ); + memmove( output + KW_SEMIBLOCK_LENGTH, input, in_len ); + } + else + { + if( in_len % 8 != 0 ) + { + padlen = ( 8 - ( in_len % 8 ) ); + } + + if( out_size < in_len + KW_SEMIBLOCK_LENGTH + padlen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + /* + * According to SP 800-38F Table 1, the plaintext length for KWP + * must be between 1 and 2^32-1 octets inclusive. + */ + if( in_len < 1 +#if SIZE_MAX > 0xFFFFFFFF + || in_len > 0xFFFFFFFF +#endif + ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( output, NIST_KW_ICV2, KW_SEMIBLOCK_LENGTH / 2 ); + PUT_UINT32_BE( ( in_len & 0xffffffff ), output, + KW_SEMIBLOCK_LENGTH / 2 ); + + memcpy( output + KW_SEMIBLOCK_LENGTH, input, in_len ); + memset( output + KW_SEMIBLOCK_LENGTH + in_len, 0, padlen ); + } + semiblocks = ( ( in_len + padlen ) / KW_SEMIBLOCK_LENGTH ) + 1; + + s = 6 * ( semiblocks - 1 ); + + if( mode == MBEDTLS_KW_MODE_KWP + && in_len <= KW_SEMIBLOCK_LENGTH ) + { + memcpy( inbuff, output, 16 ); + ret = mbedtls_cipher_update( &ctx->cipher_ctx, + inbuff, 16, output, &olen ); + if( ret != 0 ) + goto cleanup; + } + else + { + /* + * Do the wrapping function W, as defined in RFC 3394 section 2.2.1 + */ + if( semiblocks < MIN_SEMIBLOCKS_COUNT ) + { + ret = MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + goto cleanup; + } + + /* Calculate intermediate values */ + for( t = 1; t <= s; t++ ) + { + memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); + memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R2, KW_SEMIBLOCK_LENGTH ); + + ret = mbedtls_cipher_update( &ctx->cipher_ctx, + inbuff, 16, outbuff, &olen ); + if( ret != 0 ) + goto cleanup; + + memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); + calc_a_xor_t( A, t ); + + memcpy( R2, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); + R2 += KW_SEMIBLOCK_LENGTH; + if( R2 >= output + ( semiblocks * KW_SEMIBLOCK_LENGTH ) ) + R2 = output + KW_SEMIBLOCK_LENGTH; + } + } + + *out_len = semiblocks * KW_SEMIBLOCK_LENGTH; + +cleanup: + + if( ret != 0) + { + memset( output, 0, semiblocks * KW_SEMIBLOCK_LENGTH ); + } + mbedtls_platform_zeroize( inbuff, KW_SEMIBLOCK_LENGTH * 2 ); + mbedtls_platform_zeroize( outbuff, KW_SEMIBLOCK_LENGTH * 2 ); + mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen ); + return( ret ); +} + +/* + * W-1 function as defined in RFC 3394 section 2.2.2 + * This function assumes the following: + * 1. Output buffer is at least of size ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH. + * 2. The input buffer is of size semiblocks * KW_SEMIBLOCK_LENGTH. + * 3. Minimal number of semiblocks is 3. + * 4. A is a buffer to hold the first semiblock of the input buffer. + */ +static int unwrap( mbedtls_nist_kw_context *ctx, + const unsigned char *input, size_t semiblocks, + unsigned char A[KW_SEMIBLOCK_LENGTH], + unsigned char *output, size_t* out_len ) +{ + int ret = 0; + const size_t s = 6 * ( semiblocks - 1 ); + size_t olen; + uint64_t t = 0; + unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; + unsigned char inbuff[KW_SEMIBLOCK_LENGTH * 2]; + unsigned char *R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; + *out_len = 0; + + if( semiblocks < MIN_SEMIBLOCKS_COUNT ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( A, input, KW_SEMIBLOCK_LENGTH ); + memmove( output, input + KW_SEMIBLOCK_LENGTH, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); + + /* Calculate intermediate values */ + for( t = s; t >= 1; t-- ) + { + calc_a_xor_t( A, t ); + + memcpy( inbuff, A, KW_SEMIBLOCK_LENGTH ); + memcpy( inbuff + KW_SEMIBLOCK_LENGTH, R, KW_SEMIBLOCK_LENGTH ); + + ret = mbedtls_cipher_update( &ctx->cipher_ctx, + inbuff, 16, outbuff, &olen ); + if( ret != 0 ) + goto cleanup; + + memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); + + /* Set R as LSB64 of outbuff */ + memcpy( R, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); + + if( R == output ) + R = output + ( semiblocks - 2 ) * KW_SEMIBLOCK_LENGTH; + else + R -= KW_SEMIBLOCK_LENGTH; + } + + *out_len = ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH; + +cleanup: + if( ret != 0) + memset( output, 0, ( semiblocks - 1 ) * KW_SEMIBLOCK_LENGTH ); + mbedtls_platform_zeroize( inbuff, sizeof( inbuff ) ); + mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); + + return( ret ); +} + +/* + * KW-AD as defined in SP 800-38F section 6.2 + * KWP-AD as defined in SP 800-38F section 6.3 + */ +int mbedtls_nist_kw_unwrap( mbedtls_nist_kw_context *ctx, + mbedtls_nist_kw_mode_t mode, + const unsigned char *input, size_t in_len, + unsigned char *output, size_t *out_len, size_t out_size ) +{ + int ret = 0; + size_t i, olen; + unsigned char A[KW_SEMIBLOCK_LENGTH]; + unsigned char diff, bad_padding = 0; + + *out_len = 0; + if( out_size < in_len - KW_SEMIBLOCK_LENGTH ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + if( mode == MBEDTLS_KW_MODE_KW ) + { + /* + * According to SP 800-38F Table 1, the ciphertext length for KW + * must be between 3 to 2^54 semiblocks inclusive. + */ + if( in_len < 24 || +#if SIZE_MAX > 0x200000000000000 + in_len > 0x200000000000000 || +#endif + in_len % KW_SEMIBLOCK_LENGTH != 0 ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, + A, output, out_len ); + if( ret != 0 ) + goto cleanup; + + /* Check ICV in "constant-time" */ + diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV1, A, KW_SEMIBLOCK_LENGTH ); + + if( diff != 0 ) + { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + goto cleanup; + } + + } + else if( mode == MBEDTLS_KW_MODE_KWP ) + { + size_t padlen = 0; + uint32_t Plen; + /* + * According to SP 800-38F Table 1, the ciphertext length for KWP + * must be between 2 to 2^29 semiblocks inclusive. + */ + if( in_len < KW_SEMIBLOCK_LENGTH * 2 || +#if SIZE_MAX > 0x100000000 + in_len > 0x100000000 || +#endif + in_len % KW_SEMIBLOCK_LENGTH != 0 ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + if( in_len == KW_SEMIBLOCK_LENGTH * 2 ) + { + unsigned char outbuff[KW_SEMIBLOCK_LENGTH * 2]; + ret = mbedtls_cipher_update( &ctx->cipher_ctx, + input, 16, outbuff, &olen ); + if( ret != 0 ) + goto cleanup; + + memcpy( A, outbuff, KW_SEMIBLOCK_LENGTH ); + memcpy( output, outbuff + KW_SEMIBLOCK_LENGTH, KW_SEMIBLOCK_LENGTH ); + mbedtls_platform_zeroize( outbuff, sizeof( outbuff ) ); + *out_len = KW_SEMIBLOCK_LENGTH; + } + else + { + /* in_len >= KW_SEMIBLOCK_LENGTH * 3 */ + ret = unwrap( ctx, input, in_len / KW_SEMIBLOCK_LENGTH, + A, output, out_len ); + if( ret != 0 ) + goto cleanup; + } + + /* Check ICV in "constant-time" */ + diff = mbedtls_nist_kw_safer_memcmp( NIST_KW_ICV2, A, KW_SEMIBLOCK_LENGTH / 2 ); + + if( diff != 0 ) + { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } + + GET_UINT32_BE( Plen, A, KW_SEMIBLOCK_LENGTH / 2 ); + + /* + * Plen is the length of the plaintext, when the input is valid. + * If Plen is larger than the plaintext and padding, padlen will be + * larger than 8, because of the type wrap around. + */ + padlen = in_len - KW_SEMIBLOCK_LENGTH - Plen; + if ( padlen > 7 ) + { + padlen &= 7; + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } + + /* Check padding in "constant-time" */ + for( diff = 0, i = 0; i < KW_SEMIBLOCK_LENGTH; i++ ) + { + if( i >= KW_SEMIBLOCK_LENGTH - padlen ) + diff |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; + else + bad_padding |= output[*out_len - KW_SEMIBLOCK_LENGTH + i]; + } + + if( diff != 0 ) + { + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + } + + if( ret != 0 ) + { + goto cleanup; + } + memset( output + Plen, 0, padlen ); + *out_len = Plen; + } + else + { + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto cleanup; + } + +cleanup: + if( ret != 0 ) + { + memset( output, 0, *out_len ); + *out_len = 0; + } + + mbedtls_platform_zeroize( &bad_padding, sizeof( bad_padding) ); + mbedtls_platform_zeroize( &diff, sizeof( diff ) ); + mbedtls_platform_zeroize( A, sizeof( A ) ); + mbedtls_cipher_finish( &ctx->cipher_ctx, NULL, &olen ); + return( ret ); +} + +#endif /* !MBEDTLS_NIST_KW_ALT */ + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) + +#define KW_TESTS 3 + +/* + * Test vectors taken from NIST + * https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/CAVP-TESTING-BLOCK-CIPHER-MODES#KW + */ +static const unsigned int key_len[KW_TESTS] = { 16, 24, 32 }; + +static const unsigned char kw_key[KW_TESTS][32] = { + { 0x75, 0x75, 0xda, 0x3a, 0x93, 0x60, 0x7c, 0xc2, + 0xbf, 0xd8, 0xce, 0xc7, 0xaa, 0xdf, 0xd9, 0xa6 }, + { 0x2d, 0x85, 0x26, 0x08, 0x1d, 0x02, 0xfb, 0x5b, + 0x85, 0xf6, 0x9a, 0xc2, 0x86, 0xec, 0xd5, 0x7d, + 0x40, 0xdf, 0x5d, 0xf3, 0x49, 0x47, 0x44, 0xd3 }, + { 0x11, 0x2a, 0xd4, 0x1b, 0x48, 0x56, 0xc7, 0x25, + 0x4a, 0x98, 0x48, 0xd3, 0x0f, 0xdd, 0x78, 0x33, + 0x5b, 0x03, 0x9a, 0x48, 0xa8, 0x96, 0x2c, 0x4d, + 0x1c, 0xb7, 0x8e, 0xab, 0xd5, 0xda, 0xd7, 0x88 } +}; + +static const unsigned char kw_msg[KW_TESTS][40] = { + { 0x42, 0x13, 0x6d, 0x3c, 0x38, 0x4a, 0x3e, 0xea, + 0xc9, 0x5a, 0x06, 0x6f, 0xd2, 0x8f, 0xed, 0x3f }, + { 0x95, 0xc1, 0x1b, 0xf5, 0x35, 0x3a, 0xfe, 0xdb, + 0x98, 0xfd, 0xd6, 0xc8, 0xca, 0x6f, 0xdb, 0x6d, + 0xa5, 0x4b, 0x74, 0xb4, 0x99, 0x0f, 0xdc, 0x45, + 0xc0, 0x9d, 0x15, 0x8f, 0x51, 0xce, 0x62, 0x9d, + 0xe2, 0xaf, 0x26, 0xe3, 0x25, 0x0e, 0x6b, 0x4c }, + { 0x1b, 0x20, 0xbf, 0x19, 0x90, 0xb0, 0x65, 0xd7, + 0x98, 0xe1, 0xb3, 0x22, 0x64, 0xad, 0x50, 0xa8, + 0x74, 0x74, 0x92, 0xba, 0x09, 0xa0, 0x4d, 0xd1 } +}; + +static const size_t kw_msg_len[KW_TESTS] = { 16, 40, 24 }; +static const size_t kw_out_len[KW_TESTS] = { 24, 48, 32 }; +static const unsigned char kw_res[KW_TESTS][48] = { + { 0x03, 0x1f, 0x6b, 0xd7, 0xe6, 0x1e, 0x64, 0x3d, + 0xf6, 0x85, 0x94, 0x81, 0x6f, 0x64, 0xca, 0xa3, + 0xf5, 0x6f, 0xab, 0xea, 0x25, 0x48, 0xf5, 0xfb }, + { 0x44, 0x3c, 0x6f, 0x15, 0x09, 0x83, 0x71, 0x91, + 0x3e, 0x5c, 0x81, 0x4c, 0xa1, 0xa0, 0x42, 0xec, + 0x68, 0x2f, 0x7b, 0x13, 0x6d, 0x24, 0x3a, 0x4d, + 0x6c, 0x42, 0x6f, 0xc6, 0x97, 0x15, 0x63, 0xe8, + 0xa1, 0x4a, 0x55, 0x8e, 0x09, 0x64, 0x16, 0x19, + 0xbf, 0x03, 0xfc, 0xaf, 0x90, 0xb1, 0xfc, 0x2d }, + { 0xba, 0x8a, 0x25, 0x9a, 0x47, 0x1b, 0x78, 0x7d, + 0xd5, 0xd5, 0x40, 0xec, 0x25, 0xd4, 0x3d, 0x87, + 0x20, 0x0f, 0xda, 0xdc, 0x6d, 0x1f, 0x05, 0xd9, + 0x16, 0x58, 0x4f, 0xa9, 0xf6, 0xcb, 0xf5, 0x12 } +}; + +static const unsigned char kwp_key[KW_TESTS][32] = { + { 0x78, 0x65, 0xe2, 0x0f, 0x3c, 0x21, 0x65, 0x9a, + 0xb4, 0x69, 0x0b, 0x62, 0x9c, 0xdf, 0x3c, 0xc4 }, + { 0xf5, 0xf8, 0x96, 0xa3, 0xbd, 0x2f, 0x4a, 0x98, + 0x23, 0xef, 0x16, 0x2b, 0x00, 0xb8, 0x05, 0xd7, + 0xde, 0x1e, 0xa4, 0x66, 0x26, 0x96, 0xa2, 0x58 }, + { 0x95, 0xda, 0x27, 0x00, 0xca, 0x6f, 0xd9, 0xa5, + 0x25, 0x54, 0xee, 0x2a, 0x8d, 0xf1, 0x38, 0x6f, + 0x5b, 0x94, 0xa1, 0xa6, 0x0e, 0xd8, 0xa4, 0xae, + 0xf6, 0x0a, 0x8d, 0x61, 0xab, 0x5f, 0x22, 0x5a } +}; + +static const unsigned char kwp_msg[KW_TESTS][31] = { + { 0xbd, 0x68, 0x43, 0xd4, 0x20, 0x37, 0x8d, 0xc8, + 0x96 }, + { 0x6c, 0xcd, 0xd5, 0x85, 0x18, 0x40, 0x97, 0xeb, + 0xd5, 0xc3, 0xaf, 0x3e, 0x47, 0xd0, 0x2c, 0x19, + 0x14, 0x7b, 0x4d, 0x99, 0x5f, 0x96, 0x43, 0x66, + 0x91, 0x56, 0x75, 0x8c, 0x13, 0x16, 0x8f }, + { 0xd1 } +}; +static const size_t kwp_msg_len[KW_TESTS] = { 9, 31, 1 }; + +static const unsigned char kwp_res[KW_TESTS][48] = { + { 0x41, 0xec, 0xa9, 0x56, 0xd4, 0xaa, 0x04, 0x7e, + 0xb5, 0xcf, 0x4e, 0xfe, 0x65, 0x96, 0x61, 0xe7, + 0x4d, 0xb6, 0xf8, 0xc5, 0x64, 0xe2, 0x35, 0x00 }, + { 0x4e, 0x9b, 0xc2, 0xbc, 0xbc, 0x6c, 0x1e, 0x13, + 0xd3, 0x35, 0xbc, 0xc0, 0xf7, 0x73, 0x6a, 0x88, + 0xfa, 0x87, 0x53, 0x66, 0x15, 0xbb, 0x8e, 0x63, + 0x8b, 0xcc, 0x81, 0x66, 0x84, 0x68, 0x17, 0x90, + 0x67, 0xcf, 0xa9, 0x8a, 0x9d, 0x0e, 0x33, 0x26 }, + { 0x06, 0xba, 0x7a, 0xe6, 0xf3, 0x24, 0x8c, 0xfd, + 0xcf, 0x26, 0x75, 0x07, 0xfa, 0x00, 0x1b, 0xc4 } +}; +static const size_t kwp_out_len[KW_TESTS] = { 24, 40, 16 }; + +int mbedtls_nist_kw_self_test( int verbose ) +{ + mbedtls_nist_kw_context ctx; + unsigned char out[48]; + size_t olen; + int i; + int ret = 0; + mbedtls_nist_kw_init( &ctx ); + + for( i = 0; i < KW_TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " KW-AES-%u ", (unsigned int) key_len[i] * 8 ); + + ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, + kw_key[i], key_len[i] * 8, 1 ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " KW: setup failed " ); + + goto end; + } + + ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KW, kw_msg[i], + kw_msg_len[i], out, &olen, sizeof( out ) ); + if( ret != 0 || kw_out_len[i] != olen || + memcmp( out, kw_res[i], kw_out_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed. "); + + ret = 1; + goto end; + } + + if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, + kw_key[i], key_len[i] * 8, 0 ) ) + != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " KW: setup failed "); + + goto end; + } + + ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KW, + out, olen, out, &olen, sizeof( out ) ); + + if( ret != 0 || olen != kw_msg_len[i] || + memcmp( out, kw_msg[i], kw_msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto end; + } + + if( verbose != 0 ) + mbedtls_printf( " passed\n" ); + } + + for( i = 0; i < KW_TESTS; i++ ) + { + olen = sizeof( out ); + if( verbose != 0 ) + mbedtls_printf( " KWP-AES-%u ", (unsigned int) key_len[i] * 8 ); + + ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, kwp_key[i], + key_len[i] * 8, 1 ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " KWP: setup failed " ); + + goto end; + } + ret = mbedtls_nist_kw_wrap( &ctx, MBEDTLS_KW_MODE_KWP, kwp_msg[i], + kwp_msg_len[i], out, &olen, sizeof( out ) ); + + if( ret != 0 || kwp_out_len[i] != olen || + memcmp( out, kwp_res[i], kwp_out_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed. "); + + ret = 1; + goto end; + } + + if( ( ret = mbedtls_nist_kw_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, + kwp_key[i], key_len[i] * 8, 0 ) ) + != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " KWP: setup failed "); + + goto end; + } + + ret = mbedtls_nist_kw_unwrap( &ctx, MBEDTLS_KW_MODE_KWP, out, + olen, out, &olen, sizeof( out ) ); + + if( ret != 0 || olen != kwp_msg_len[i] || + memcmp( out, kwp_msg[i], kwp_msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed. "); + + ret = 1; + goto end; + } + + if( verbose != 0 ) + mbedtls_printf( " passed\n" ); + } +end: + mbedtls_nist_kw_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_NIST_KW_C */ diff --git a/thirdparty/mbedtls/library/pkcs5.c b/thirdparty/mbedtls/library/pkcs5.c index 440a174b5b..f04f0ab25e 100644 --- a/thirdparty/mbedtls/library/pkcs5.c +++ b/thirdparty/mbedtls/library/pkcs5.c @@ -249,8 +249,10 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p memset( counter, 0, 4 ); counter[3] = 1; +#if UINT_MAX > 0xFFFFFFFF if( iteration_count > 0xFFFFFFFF ) return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); +#endif while( key_length ) { diff --git a/thirdparty/mbedtls/library/pkparse.c b/thirdparty/mbedtls/library/pkparse.c index ccb7f5409d..d6ac987e23 100644 --- a/thirdparty/mbedtls/library/pkparse.c +++ b/thirdparty/mbedtls/library/pkparse.c @@ -1261,7 +1261,6 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, return( ret ); #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ #else - ((void) ret); ((void) pwd); ((void) pwdlen); #endif /* MBEDTLS_PEM_PARSE_C */ diff --git a/thirdparty/mbedtls/library/platform.c b/thirdparty/mbedtls/library/platform.c index 9e992875d9..b24b2fa652 100644 --- a/thirdparty/mbedtls/library/platform.c +++ b/thirdparty/mbedtls/library/platform.c @@ -51,14 +51,24 @@ static void platform_free_uninit( void *ptr ) #define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit #endif /* !MBEDTLS_PLATFORM_STD_FREE */ -void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; -void (*mbedtls_free)( void * ) = MBEDTLS_PLATFORM_STD_FREE; +static void * (*mbedtls_calloc_func)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; +static void (*mbedtls_free_func)( void * ) = MBEDTLS_PLATFORM_STD_FREE; + +void * mbedtls_calloc( size_t nmemb, size_t size ) +{ + return (*mbedtls_calloc_func)( nmemb, size ); +} + +void mbedtls_free( void * ptr ) +{ + (*mbedtls_free_func)( ptr ); +} int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), void (*free_func)( void * ) ) { - mbedtls_calloc = calloc_func; - mbedtls_free = free_func; + mbedtls_calloc_func = calloc_func; + mbedtls_free_func = free_func; return( 0 ); } #endif /* MBEDTLS_PLATFORM_MEMORY */ diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c new file mode 100644 index 0000000000..e22d3afb68 --- /dev/null +++ b/thirdparty/mbedtls/library/poly1305.c @@ -0,0 +1,563 @@ +/** + * \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) + +#include "mbedtls/poly1305.h" +#include "mbedtls/platform_util.h" + +#include <string.h> + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include <stdio.h> +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#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 ) \ + ( (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 ) \ + ) + +/* + * 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. + * + * \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 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++ ) + { + /* 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; + acc3 = (uint32_t) d3; + acc4 += (uint32_t) ( d3 >> 32U ) + needs_padding; + + /* Compute: acc *= r */ + 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) */ + 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 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 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] = (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_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); + } +} + +void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx ) +{ + if( ctx != NULL ) + { + mbedtls_platform_zeroize( ctx, sizeof( mbedtls_poly1305_context ) ); + } +} + +int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx, + const unsigned char key[32] ) +{ + if( ctx == NULL || key == 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; + ctx->acc[4] = 0U; + + /* Queue initially empty */ + mbedtls_platform_zeroize( ctx->queue, sizeof( ctx->queue ) ); + ctx->queue_len = 0U; + + return( 0 ); +} + +int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx, + const unsigned char *input, + size_t ilen ) +{ + size_t offset = 0U; + size_t remaining = ilen; + size_t queue_free_len; + size_t nblocks; + + 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( ( remaining > 0U ) && ( 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; + + 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; + + 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 ); + + poly1305_process( ctx, 1U, /* Process 1 block */ + ctx->queue, 0U ); /* Already padded above */ + } + + poly1305_compute_mac( ctx, mac ); + + return( 0 ); +} + +int mbedtls_poly1305_mac( const unsigned char key[32], + const unsigned char *input, + size_t ilen, + unsigned char mac[16] ) +{ + mbedtls_poly1305_context ctx; + int ret; + + mbedtls_poly1305_init( &ctx ); + + ret = mbedtls_poly1305_starts( &ctx, key ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_poly1305_update( &ctx, input, ilen ); + if( ret != 0 ) + goto cleanup; + + ret = mbedtls_poly1305_finish( &ctx, mac ); + +cleanup: + mbedtls_poly1305_free( &ctx ); + return( ret ); +} + +#endif /* MBEDTLS_POLY1305_ALT */ + +#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 + } +}; + +#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 ret; + + for( i = 0U; i < 2U; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " Poly1305 test %u ", i ); + + 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" ) ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_POLY1305_C */ diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c index 1587de4805..bab6087c4e 100644 --- a/thirdparty/mbedtls/library/sha1.c +++ b/thirdparty/mbedtls/library/sha1.c @@ -342,14 +342,6 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, } #endif -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - /* * SHA-1 final digest */ @@ -357,25 +349,48 @@ int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] ) { int ret; - uint32_t last, padn; + uint32_t used; uint32_t high, low; - unsigned char msglen[8]; + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->total[0] & 0x3F; + + ctx->buffer[used++] = 0x80; + + if( used <= 56 ) + { + /* Enough room for padding + length in current block */ + memset( ctx->buffer + used, 0, 56 - used ); + } + else + { + /* We'll need an extra block */ + memset( ctx->buffer + used, 0, 64 - used ); + + if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + memset( ctx->buffer, 0, 56 ); + } + + /* + * Add message length + */ high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); - PUT_UINT32_BE( high, msglen, 0 ); - PUT_UINT32_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + PUT_UINT32_BE( high, ctx->buffer, 56 ); + PUT_UINT32_BE( low, ctx->buffer, 60 ); - if( ( ret = mbedtls_sha1_update_ret( ctx, sha1_padding, padn ) ) != 0 ) - return( ret ); - if( ( ret = mbedtls_sha1_update_ret( ctx, msglen, 8 ) ) != 0 ) + if( ( ret = mbedtls_internal_sha1_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); + /* + * Output final state + */ PUT_UINT32_BE( ctx->state[0], output, 0 ); PUT_UINT32_BE( ctx->state[1], output, 4 ); PUT_UINT32_BE( ctx->state[2], output, 8 ); diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c index 695485d847..dbb4a89861 100644 --- a/thirdparty/mbedtls/library/sha256.c +++ b/thirdparty/mbedtls/library/sha256.c @@ -311,14 +311,6 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, } #endif -static const unsigned char sha256_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - /* * SHA-256 final digest */ @@ -326,26 +318,48 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] ) { int ret; - uint32_t last, padn; + uint32_t used; uint32_t high, low; - unsigned char msglen[8]; + /* + * Add padding: 0x80 then 0x00 until 8 bytes remain for the length + */ + used = ctx->total[0] & 0x3F; + + ctx->buffer[used++] = 0x80; + + if( used <= 56 ) + { + /* Enough room for padding + length in current block */ + memset( ctx->buffer + used, 0, 56 - used ); + } + else + { + /* We'll need an extra block */ + memset( ctx->buffer + used, 0, 64 - used ); + + if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + memset( ctx->buffer, 0, 56 ); + } + + /* + * Add message length + */ high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); low = ( ctx->total[0] << 3 ); - PUT_UINT32_BE( high, msglen, 0 ); - PUT_UINT32_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - if( ( ret = mbedtls_sha256_update_ret( ctx, sha256_padding, padn ) ) != 0 ) - return( ret ); + PUT_UINT32_BE( high, ctx->buffer, 56 ); + PUT_UINT32_BE( low, ctx->buffer, 60 ); - if( ( ret = mbedtls_sha256_update_ret( ctx, msglen, 8 ) ) != 0 ) + if( ( ret = mbedtls_internal_sha256_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); + /* + * Output final state + */ PUT_UINT32_BE( ctx->state[0], output, 0 ); PUT_UINT32_BE( ctx->state[1], output, 4 ); PUT_UINT32_BE( ctx->state[2], output, 8 ); diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c index 6de94e99b4..a9440e8af5 100644 --- a/thirdparty/mbedtls/library/sha512.c +++ b/thirdparty/mbedtls/library/sha512.c @@ -341,18 +341,6 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, } #endif -static const unsigned char sha512_padding[128] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - /* * SHA-512 final digest */ @@ -360,26 +348,48 @@ int mbedtls_sha512_finish_ret( mbedtls_sha512_context *ctx, unsigned char output[64] ) { int ret; - size_t last, padn; + unsigned used; uint64_t high, low; - unsigned char msglen[16]; - high = ( ctx->total[0] >> 61 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); + /* + * Add padding: 0x80 then 0x00 until 16 bytes remain for the length + */ + used = ctx->total[0] & 0x7F; - PUT_UINT64_BE( high, msglen, 0 ); - PUT_UINT64_BE( low, msglen, 8 ); + ctx->buffer[used++] = 0x80; - last = (size_t)( ctx->total[0] & 0x7F ); - padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); + if( used <= 112 ) + { + /* Enough room for padding + length in current block */ + memset( ctx->buffer + used, 0, 112 - used ); + } + else + { + /* We'll need an extra block */ + memset( ctx->buffer + used, 0, 128 - used ); - if( ( ret = mbedtls_sha512_update_ret( ctx, sha512_padding, padn ) ) != 0 ) + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) return( ret ); - if( ( ret = mbedtls_sha512_update_ret( ctx, msglen, 16 ) ) != 0 ) - return( ret ); + memset( ctx->buffer, 0, 112 ); + } + + /* + * Add message length + */ + high = ( ctx->total[0] >> 61 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT64_BE( high, ctx->buffer, 112 ); + PUT_UINT64_BE( low, ctx->buffer, 120 ); + if( ( ret = mbedtls_internal_sha512_process( ctx, ctx->buffer ) ) != 0 ) + return( ret ); + + /* + * Output final state + */ PUT_UINT64_BE( ctx->state[0], output, 0 ); PUT_UINT64_BE( ctx->state[1], output, 8 ); PUT_UINT64_BE( ctx->state[2], output, 16 ); diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c index 2e9a0fd792..59cdc7a806 100644 --- a/thirdparty/mbedtls/library/ssl_ciphersuites.c +++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c @@ -47,7 +47,7 @@ * 1. By key exchange: * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK * 2. By key length and cipher: - * AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 > 3DES + * ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 > 3DES * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 * 4. By hash function used when relevant * 5. By key exchange/auth again: EC > non-EC @@ -57,6 +57,11 @@ static const int ciphersuite_preference[] = #if defined(MBEDTLS_SSL_CIPHERSUITES) MBEDTLS_SSL_CIPHERSUITES, #else + /* Chacha-Poly ephemeral suites */ + MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + /* All AES-256 ephemeral suites */ MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, @@ -127,6 +132,8 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* The PSK ephemeral suites */ + MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, @@ -227,6 +234,7 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* The RSA PSK suites */ + MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, @@ -246,6 +254,7 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, /* The PSK suites */ + MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_PSK_WITH_AES_256_CCM, MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, @@ -312,6 +321,75 @@ static const int ciphersuite_preference[] = static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = { +#if defined(MBEDTLS_CHACHAPOLY_C) && \ + defined(MBEDTLS_SHA256_C) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + { MBEDTLS_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + { MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS-PSK-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + { MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS-ECDHE-PSK-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + { MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS-DHE-PSK-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + { MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS-RSA-PSK-WITH-CHACHA20-POLY1305-SHA256", + MBEDTLS_CIPHER_CHACHA20_POLY1305, MBEDTLS_MD_SHA256, + MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif +#endif /* MBEDTLS_CHACHAPOLY_C && + MBEDTLS_SHA256_C && + MBEDTLS_SSL_PROTO_TLS1_2 */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) #if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_SHA1_C) diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c index 7455e99d2e..ba59c48989 100644 --- a/thirdparty/mbedtls/library/ssl_cli.c +++ b/thirdparty/mbedtls/library/ssl_cli.c @@ -57,7 +57,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t hostname_len; *olen = 0; @@ -127,7 +127,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -171,7 +171,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t sig_alg_len = 0; const int *md; #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) @@ -256,7 +256,7 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; unsigned char *elliptic_curve_list = p + 6; size_t elliptic_curve_len = 0; const mbedtls_ecp_curve_info *info; @@ -329,7 +329,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -362,7 +362,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, { int ret; unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t kkpp_len; *olen = 0; @@ -439,7 +439,7 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -472,7 +472,7 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -504,7 +504,7 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -538,7 +538,7 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; *olen = 0; @@ -572,7 +572,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t tlen = ssl->session_negotiate->ticket_len; *olen = 0; @@ -616,7 +616,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, unsigned char *buf, size_t *olen ) { unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t alpnlen = 0; const char **cur; @@ -1247,14 +1247,14 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, size_t list_size; const unsigned char *p; - list_size = buf[0]; - if( list_size + 1 != len ) + if( len == 0 || (size_t)( buf[0] + 1 ) != len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } + list_size = buf[0]; p = buf + 1; while( list_size > 0 ) @@ -2117,7 +2117,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; unsigned char *p = ssl->handshake->premaster + pms_offset; - if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); @@ -2160,7 +2160,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk, p, ssl->handshake->pmslen, ssl->out_msg + offset + len_bytes, olen, - MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes, + MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); @@ -2544,10 +2544,9 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) defined(MBEDTLS_SSL_PROTO_TLS1_2) if( md_alg != MBEDTLS_MD_NONE ) { - /* Info from md_alg will be used instead */ - hashlen = 0; - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params, - params_len, md_alg ); + ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, + params, params_len, + md_alg ); if( ret != 0 ) return( ret ); } @@ -2559,8 +2558,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : - (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); if( ssl->session_negotiate->peer_cert == NULL ) { @@ -2711,7 +2709,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) * therefore the buffer length at this point must be greater than that * regardless of the actual code path. */ - if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) + if( ssl->in_hslen <= mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, @@ -2928,7 +2926,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) i = 4; n = ssl->conf->psk_identity_len; - if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " "SSL buffer too short" ) ); @@ -2964,7 +2962,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) */ n = ssl->handshake->dhm_ctx.len; - if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( i + 2 + n > MBEDTLS_SSL_OUT_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" " or SSL buffer too short" ) ); @@ -2993,7 +2991,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) * ClientECDiffieHellmanPublic public; */ ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, - &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i, + &ssl->out_msg[i], MBEDTLS_SSL_OUT_CONTENT_LEN - i, ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { @@ -3034,7 +3032,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) i = 4; ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, - ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n, + ssl->out_msg + i, MBEDTLS_SSL_OUT_CONTENT_LEN - i, &n, ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { diff --git a/thirdparty/mbedtls/library/ssl_srv.c b/thirdparty/mbedtls/library/ssl_srv.c index 09b7a3fed3..52087ae6e1 100644 --- a/thirdparty/mbedtls/library/ssl_srv.c +++ b/thirdparty/mbedtls/library/ssl_srv.c @@ -91,6 +91,13 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); + if( len < 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( servername_list_size + 2 != len ) { @@ -101,7 +108,7 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, } p = buf + 2; - while( servername_list_size > 0 ) + while( servername_list_size > 2 ) { hostname_len = ( ( p[1] << 8 ) | p[2] ); if( hostname_len + 3 > servername_list_size ) @@ -205,6 +212,12 @@ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, mbedtls_md_type_t md_cur; mbedtls_pk_type_t sig_cur; + if ( len < 2 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( sig_alg_list_size + 2 != len || sig_alg_list_size % 2 != 0 ) @@ -273,6 +286,12 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, const unsigned char *p; const mbedtls_ecp_curve_info *curve_info, **curves; + if ( len < 2 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( list_size + 2 != len || list_size % 2 != 0 ) @@ -332,14 +351,14 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, size_t list_size; const unsigned char *p; - list_size = buf[0]; - if( list_size + 1 != len ) + if( len == 0 || (size_t)( buf[0] + 1 ) != len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } + list_size = buf[0]; p = buf + 1; while( list_size > 0 ) @@ -709,7 +728,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", cur->cert ); - if( ! mbedtls_pk_can_do( cur->key, pk_alg ) ) + if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); continue; @@ -733,7 +752,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ECDSA_C) if( pk_alg == MBEDTLS_PK_ECDSA && - ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 ) + ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); continue; @@ -1303,7 +1322,7 @@ read_record_header: else #endif { - if( msg_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( msg_len > MBEDTLS_SSL_IN_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); @@ -1656,10 +1675,16 @@ read_record_header: while( ext_len != 0 ) { - unsigned int ext_id = ( ( ext[0] << 8 ) - | ( ext[1] ) ); - unsigned int ext_size = ( ( ext[2] << 8 ) - | ( ext[3] ) ); + unsigned int ext_id; + unsigned int ext_size; + if ( ext_len < 4 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + ext_id = ( ( ext[0] << 8 ) | ( ext[1] ) ); + ext_size = ( ( ext[2] << 8 ) | ( ext[3] ) ); if( ext_size + 4 > ext_len ) { @@ -2235,7 +2260,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, { int ret; unsigned char *p = buf; - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; size_t kkpp_len; *olen = 0; @@ -2342,7 +2367,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) cookie_len_byte = p++; if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, - &p, ssl->out_buf + MBEDTLS_SSL_BUFFER_LEN, + &p, ssl->out_buf + MBEDTLS_SSL_OUT_BUFFER_LEN, ssl->cli_id, ssl->cli_id_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); @@ -2638,7 +2663,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) size_t dn_size, total_dn_size; /* excluding length bytes */ size_t ct_len, sa_len; /* including length bytes */ unsigned char *buf, *p; - const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; const mbedtls_x509_crt *crt; int authmode; @@ -2828,54 +2853,56 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ -static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ + defined(MBEDTLS_SSL_ASYNC_PRIVATE) +static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl, + size_t *signature_len ) +{ + /* Append the signature to ssl->out_msg, leaving 2 bytes for the + * signature length which will be added in ssl_write_server_key_exchange + * after the call to ssl_prepare_server_key_exchange. + * ssl_write_server_key_exchange also takes care of incrementing + * ssl->out_msglen. */ + unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2; + size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_OUT_CONTENT_LEN + - sig_start ); + int ret = ssl->conf->f_async_resume( ssl, + sig_start, signature_len, sig_max_len ); + if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) + { + ssl->handshake->async_in_progress = 0; + mbedtls_ssl_set_async_operation_data( ssl, NULL ); + } + MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret ); + return( ret ); +} +#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && + defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ + +/* Prepare the ServerKeyExchange message, up to and including + * calculating the signature if any, but excluding formatting the + * signature and sending the message. */ +static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl, + size_t *signature_len ) { - int ret; - size_t n = 0; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; - #if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) - unsigned char *p = ssl->out_msg + 4; - size_t len; #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - unsigned char *dig_signed = p; - size_t dig_signed_len = 0; + unsigned char *dig_signed = NULL; #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ - MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); - - /* - * - * Part 1: Extract static ECDH parameters and abort - * if ServerKeyExchange not needed. - * - */ - - /* For suites involving ECDH, extract DH parameters - * from certificate at this point. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) - if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) - { - ssl_get_ecdh_params_from_cert( ssl ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ + (void) ciphersuite_info; /* unused in some configurations */ +#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) + (void) signature_len; +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - /* Key exchanges not involving ephemeral keys don't use - * ServerKeyExchange, so end here. */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) - if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); - ssl->state++; - return( 0 ); - } -#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */ + ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */ /* * - * Part 2: Provide key exchange parameters for chosen ciphersuite. + * Part 1: Provide key exchange parameters for chosen ciphersuite. * */ @@ -2885,18 +2912,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { - const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + int ret; + size_t len = 0; - ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng ); + ret = mbedtls_ecjpake_write_round_two( + &ssl->handshake->ecjpake_ctx, + ssl->out_msg + ssl->out_msglen, + MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, &len, + ssl->conf->f_rng, ssl->conf->p_rng ); if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); return( ret ); } - p += len; - n += len; + ssl->out_msglen += len; } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ @@ -2910,10 +2940,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { - *(p++) = 0x00; - *(p++) = 0x00; - - n += 2; + ssl->out_msg[ssl->out_msglen++] = 0x00; + ssl->out_msg[ssl->out_msglen++] = 0x00; } #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ @@ -2924,6 +2952,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) { + int ret; + size_t len = 0; + if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); @@ -2947,21 +2978,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) return( ret ); } - if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx, - (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), - p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + if( ( ret = mbedtls_dhm_make_params( + &ssl->handshake->dhm_ctx, + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + ssl->out_msg + ssl->out_msglen, &len, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); return( ret ); } #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = p; - dig_signed_len = len; + dig_signed = ssl->out_msg + ssl->out_msglen; #endif - p += len; - n += len; + ssl->out_msglen += len; MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); @@ -2986,6 +3017,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) */ const mbedtls_ecp_curve_info **curve = NULL; const mbedtls_ecp_group_id *gid; + int ret; + size_t len = 0; /* Match our preference list against the offered curves */ for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) @@ -3009,21 +3042,21 @@ curve_matching_done: return( ret ); } - if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, - p, MBEDTLS_SSL_MAX_CONTENT_LEN - n, - ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + if( ( ret = mbedtls_ecdh_make_params( + &ssl->handshake->ecdh_ctx, &len, + ssl->out_msg + ssl->out_msglen, + MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); return( ret ); } #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) - dig_signed = p; - dig_signed_len = len; + dig_signed = ssl->out_msg + ssl->out_msglen; #endif - p += len; - n += len; + ssl->out_msglen += len; MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q ); } @@ -3031,19 +3064,20 @@ curve_matching_done: /* * - * Part 3: For key exchanges involving the server signing the + * Part 2: For key exchanges involving the server signing the * exchange parameters, compute and add the signature here. * */ #if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) { - size_t signature_len = 0; - unsigned int hashlen = 0; - unsigned char hash[64]; + size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed; + size_t hashlen = 0; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + int ret; /* - * 3.1: Choose hash algorithm: + * 2.1: Choose hash algorithm: * A: For TLS 1.2, obey signature-hash-algorithm extension * to choose appropriate hash. * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 @@ -3090,7 +3124,7 @@ curve_matching_done: MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); /* - * 3.2: Compute the hash to be signed + * 2.2: Compute the hash to be signed */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) @@ -3110,9 +3144,7 @@ curve_matching_done: defined(MBEDTLS_SSL_PROTO_TLS1_2) if( md_alg != MBEDTLS_MD_NONE ) { - /* Info from md_alg will be used instead */ - hashlen = 0; - ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, + ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen, dig_signed, dig_signed_len, md_alg ); @@ -3127,18 +3159,11 @@ curve_matching_done: return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : - (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen ); /* - * 3.3: Compute and add the signature + * 2.3: Compute and add the signature */ - if( mbedtls_ssl_own_key( ssl ) == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); - } - #if defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { @@ -3158,33 +3183,150 @@ curve_matching_done: * */ - *(p++) = mbedtls_ssl_hash_from_md_alg( md_alg ); - *(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg ); - - n += 2; + ssl->out_msg[ssl->out_msglen++] = + mbedtls_ssl_hash_from_md_alg( md_alg ); + ssl->out_msg[ssl->out_msglen++] = + mbedtls_ssl_sig_from_pk_alg( sig_alg ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen, - p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + if( ssl->conf->f_async_sign_start != NULL ) + { + ret = ssl->conf->f_async_sign_start( ssl, + mbedtls_ssl_own_cert( ssl ), + md_alg, hash, hashlen ); + switch( ret ) + { + case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: + /* act as if f_async_sign was null */ + break; + case 0: + ssl->handshake->async_in_progress = 1; + return( ssl_resume_server_key_exchange( ssl, signature_len ) ); + case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: + ssl->handshake->async_in_progress = 1; + return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); + default: + MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + + if( mbedtls_ssl_own_key( ssl ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* Append the signature to ssl->out_msg, leaving 2 bytes for the + * signature length which will be added in ssl_write_server_key_exchange + * after the call to ssl_prepare_server_key_exchange. + * ssl_write_server_key_exchange also takes care of incrementing + * ssl->out_msglen. */ + if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), + md_alg, hash, hashlen, + ssl->out_msg + ssl->out_msglen + 2, + signature_len, + ssl->conf->f_rng, + ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); return( ret ); } + } +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ + + return( 0 ); +} + +/* Prepare the ServerKeyExchange message and send it. For ciphersuites + * that do not include a ServerKeyExchange message, do nothing. Either + * way, if successful, move on to the next step in the SSL state + * machine. */ +static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) +{ + int ret; + size_t signature_len = 0; +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) + /* Extract static ECDH parameters and abort if ServerKeyExchange + * is not needed. */ + if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) ) + { + /* For suites involving ECDH, extract DH parameters + * from certificate at this point. */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) + if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) ) + { + ssl_get_ecdh_params_from_cert( ssl ); + } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ - *(p++) = (unsigned char)( signature_len >> 8 ); - *(p++) = (unsigned char)( signature_len ); - n += 2; + /* Key exchanges not involving ephemeral keys don't use + * ServerKeyExchange, so end here. */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ - MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len ); +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \ + defined(MBEDTLS_SSL_ASYNC_PRIVATE) + /* If we have already prepared the message and there is an ongoing + * signature operation, resume signing. */ + if( ssl->handshake->async_in_progress != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) ); + ret = ssl_resume_server_key_exchange( ssl, &signature_len ); + } + else +#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && + defined(MBEDTLS_SSL_ASYNC_PRIVATE) */ + { + /* ServerKeyExchange is needed. Prepare the message. */ + ret = ssl_prepare_server_key_exchange( ssl, &signature_len ); + } - n += signature_len; + if( ret != 0 ) + { + /* If we're starting to write a new message, set ssl->out_msglen + * to 0. But if we're resuming after an asynchronous message, + * out_msglen is the amount of data written so far and mst be + * preserved. */ + if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) ); + else + ssl->out_msglen = 0; + return( ret ); } -#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ - /* Done with actual work; add header and send. */ + /* If there is a signature, write its length. + * ssl_prepare_server_key_exchange already wrote the signature + * itself at its proper place in the output buffer. */ +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) + if( signature_len != 0 ) + { + ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 ); + ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len ); - ssl->out_msglen = 4 + n; + MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", + ssl->out_msg + ssl->out_msglen, + signature_len ); + + /* Skip over the already-written signature */ + ssl->out_msglen += signature_len; + } +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ + + /* Add header and send. */ ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; @@ -3197,7 +3339,6 @@ curve_matching_done: } MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); - return( 0 ); } @@ -3272,33 +3413,59 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char * #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) -static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, - const unsigned char *p, - const unsigned char *end, - size_t pms_offset ) + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl, + unsigned char *peer_pms, + size_t *peer_pmslen, + size_t peer_pmssize ) +{ + int ret = ssl->conf->f_async_resume( ssl, + peer_pms, peer_pmslen, peer_pmssize ); + if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) + { + ssl->handshake->async_in_progress = 0; + mbedtls_ssl_set_async_operation_data( ssl, NULL ); + } + MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret ); + return( ret ); +} +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + +static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, + const unsigned char *p, + const unsigned char *end, + unsigned char *peer_pms, + size_t *peer_pmslen, + size_t peer_pmssize ) { int ret; - size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) ); - unsigned char *pms = ssl->handshake->premaster + pms_offset; - unsigned char ver[2]; - unsigned char fake_pms[48], peer_pms[48]; - unsigned char mask; - size_t i, peer_pmslen; - unsigned int diff; + mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); + mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; + size_t len = mbedtls_pk_get_len( public_key ); - if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) ) +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + /* If we have already started decoding the message and there is an ongoing + * decryption operation, resume signing. */ + if( ssl->handshake->async_in_progress != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); - return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) ); + return( ssl_resume_decrypt_pms( ssl, + peer_pms, peer_pmslen, peer_pmssize ) ); } +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ /* - * Decrypt the premaster using own private RSA key + * Prepare to decrypt the premaster using own private RSA key */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) { + if ( p + 2 > end ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } if( *p++ != ( ( len >> 8 ) & 0xFF ) || *p++ != ( ( len ) & 0xFF ) ) { @@ -3314,30 +3481,120 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } + /* + * Decrypt the premaster secret + */ +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + if( ssl->conf->f_async_decrypt_start != NULL ) + { + ret = ssl->conf->f_async_decrypt_start( ssl, + mbedtls_ssl_own_cert( ssl ), + p, len ); + switch( ret ) + { + case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH: + /* act as if f_async_decrypt_start was null */ + break; + case 0: + ssl->handshake->async_in_progress = 1; + return( ssl_resume_decrypt_pms( ssl, + peer_pms, + peer_pmslen, + peer_pmssize ) ); + case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS: + ssl->handshake->async_in_progress = 1; + return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ); + default: + MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + + if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + ret = mbedtls_pk_decrypt( private_key, p, len, + peer_pms, peer_pmslen, peer_pmssize, + ssl->conf->f_rng, ssl->conf->p_rng ); + return( ret ); +} + +static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, + const unsigned char *p, + const unsigned char *end, + size_t pms_offset ) +{ + int ret; + unsigned char *pms = ssl->handshake->premaster + pms_offset; + unsigned char ver[2]; + unsigned char fake_pms[48], peer_pms[48]; + unsigned char mask; + size_t i, peer_pmslen; + unsigned int diff; + + /* In case of a failure in decryption, the decryption may write less than + * 2 bytes of output, but we always read the first two bytes. It doesn't + * matter in the end because diff will be nonzero in that case due to + * peer_pmslen being less than 48, and we only care whether diff is 0. + * But do initialize peer_pms for robustness anyway. This also makes + * memory analyzers happy (don't access uninitialized memory, even + * if it's an unsigned char). */ + peer_pms[0] = peer_pms[1] = ~0; + + ret = ssl_decrypt_encrypted_pms( ssl, p, end, + peer_pms, + &peer_pmslen, + sizeof( peer_pms ) ); + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS ) + return( ret ); +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + mbedtls_ssl_write_version( ssl->handshake->max_major_ver, - ssl->handshake->max_minor_ver, - ssl->conf->transport, ver ); + ssl->handshake->max_minor_ver, + ssl->conf->transport, ver ); + + /* Avoid data-dependent branches while checking for invalid + * padding, to protect against timing-based Bleichenbacher-type + * attacks. */ + diff = (unsigned int) ret; + diff |= peer_pmslen ^ 48; + diff |= peer_pms[0] ^ ver[0]; + diff |= peer_pms[1] ^ ver[1]; + + /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ + /* MSVC has a warning about unary minus on unsigned, but this is + * well-defined and precisely what we want to do here */ +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif /* * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding * must not cause the connection to end immediately; instead, send a * bad_record_mac later in the handshake. - * Also, avoid data-dependant branches here to protect against - * timing-based variants. + * To protect against timing-based variants of the attack, we must + * not have any branch that depends on whether the decryption was + * successful. In particular, always generate the fake premaster secret, + * regardless of whether it will ultimately influence the output or not. */ ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); if( ret != 0 ) + { + /* It's ok to abort on an RNG failure, since this does not reveal + * anything about the RSA decryption. */ return( ret ); - - ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len, - peer_pms, &peer_pmslen, - sizeof( peer_pms ), - ssl->conf->f_rng, ssl->conf->p_rng ); - - diff = (unsigned int) ret; - diff |= peer_pmslen ^ 48; - diff |= peer_pms[0] ^ ver[0]; - diff |= peer_pms[1] ^ ver[1]; + } #if defined(MBEDTLS_SSL_DEBUG_ALL) if( diff != 0 ) @@ -3352,18 +3609,8 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, } ssl->handshake->pmslen = 48; - /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ - /* MSVC has a warning about unary minus on unsigned, but this is - * well-defined and precisely what we want to do here */ -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4146 ) -#endif - mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - + /* Set pms to either the true or the fake PMS, without + * data-dependent branches. */ for( i = 0; i < ssl->handshake->pmslen; i++ ) pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); @@ -3445,6 +3692,20 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \ + ( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) ) + if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) && + ( ssl->handshake->async_in_progress != 0 ) ) + { + /* We've already read a record and there is an asynchronous + * operation in progress to decrypt it. So skip reading the + * record. */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) ); + } + else +#endif if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); @@ -3557,6 +3818,19 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) { +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + if ( ssl->handshake->async_in_progress != 0 ) + { + /* There is an asynchronous operation in progress to + * decrypt the encrypted premaster secret, so skip + * directly to resuming this operation. */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) ); + /* Update p to skip the PSK identity. ssl_parse_encrypted_pms + * won't actually use it, but maintain p anyway for robustness. */ + p += ssl->conf->psk_identity_len + 2; + } + else +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); @@ -3926,7 +4200,7 @@ static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, ssl->session_negotiate, ssl->out_msg + 10, - ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN, + ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN, &tlen, &lifetime ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c index e8e0cd854b..91f96c8ab6 100644 --- a/thirdparty/mbedtls/library/ssl_tls.c +++ b/thirdparty/mbedtls/library/ssl_tls.c @@ -141,14 +141,24 @@ static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) * } MaxFragmentLength; * and we add 0 -> extension unused */ -static unsigned int mfl_code_to_length[MBEDTLS_SSL_MAX_FRAG_LEN_INVALID] = +static unsigned int ssl_mfl_code_to_length( int mfl ) { - MBEDTLS_SSL_MAX_CONTENT_LEN, /* MBEDTLS_SSL_MAX_FRAG_LEN_NONE */ - 512, /* MBEDTLS_SSL_MAX_FRAG_LEN_512 */ - 1024, /* MBEDTLS_SSL_MAX_FRAG_LEN_1024 */ - 2048, /* MBEDTLS_SSL_MAX_FRAG_LEN_2048 */ - 4096, /* MBEDTLS_SSL_MAX_FRAG_LEN_4096 */ -}; + switch( mfl ) + { + case MBEDTLS_SSL_MAX_FRAG_LEN_NONE: + return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); + case MBEDTLS_SSL_MAX_FRAG_LEN_512: + return 512; + case MBEDTLS_SSL_MAX_FRAG_LEN_1024: + return 1024; + case MBEDTLS_SSL_MAX_FRAG_LEN_2048: + return 2048; + case MBEDTLS_SSL_MAX_FRAG_LEN_4096: + return 4096; + default: + return ( MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ); + } +} #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #if defined(MBEDTLS_SSL_CLI_C) @@ -688,18 +698,32 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) transform->keylen = cipher_info->key_bitlen / 8; if( cipher_info->mode == MBEDTLS_MODE_GCM || - cipher_info->mode == MBEDTLS_MODE_CCM ) + cipher_info->mode == MBEDTLS_MODE_CCM || + cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) { + size_t taglen, explicit_ivlen; + transform->maclen = 0; mac_key_len = 0; + /* All modes haves 96-bit IVs; + * GCM and CCM has 4 implicit and 8 explicit bytes + * ChachaPoly has all 12 bytes implicit + */ transform->ivlen = 12; - transform->fixed_ivlen = 4; + if( cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY ) + transform->fixed_ivlen = 12; + else + transform->fixed_ivlen = 4; + + /* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */ + taglen = transform->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - /* Minimum length is expicit IV + tag */ - transform->minlen = transform->ivlen - transform->fixed_ivlen - + ( transform->ciphersuite_info->flags & - MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16 ); + + /* Minimum length of encrypted record */ + explicit_ivlen = transform->ivlen - transform->fixed_ivlen; + transform->minlen = explicit_ivlen + taglen; } else { @@ -956,11 +980,11 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) if( ssl->compress_buf == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); - ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_BUFFER_LEN ); + ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); if( ssl->compress_buf == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", - MBEDTLS_SSL_BUFFER_LEN ) ); + MBEDTLS_SSL_COMPRESS_BUFFER_LEN ) ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } } @@ -1151,6 +1175,9 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch * other_secret already set by the ClientKeyExchange message, * and is 48 bytes long */ + if( end - p < 2 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + *p++ = 0; *p++ = 48; p += 48; @@ -1276,6 +1303,27 @@ static void ssl_mac( mbedtls_md_context_t *md_ctx, #define SSL_SOME_MODES_USE_MAC #endif +/* The function below is only used in the Lucky 13 counter-measure in + * ssl_decrypt_buf(). These are the defines that guard the call site. */ +#if defined(SSL_SOME_MODES_USE_MAC) && \ + ( defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) ) +/* This function makes sure every byte in the memory region is accessed + * (in ascending addresses order) */ +static void ssl_read_memory( unsigned char *p, size_t len ) +{ + unsigned char acc = 0; + volatile unsigned char force; + + for( ; len != 0; p++, len-- ) + acc ^= *p; + + force = acc; + (void) force; +} +#endif /* SSL_SOME_MODES_USE_MAC && ( TLS1 || TLS1_1 || TLS1_2 ) */ + /* * Encryption/decryption functions */ @@ -1297,11 +1345,11 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", ssl->out_msg, ssl->out_msglen ); - if( ssl->out_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( ssl->out_msglen > MBEDTLS_SSL_OUT_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d", (unsigned) ssl->out_msglen, - MBEDTLS_SSL_MAX_CONTENT_LEN ) ); + MBEDTLS_SSL_OUT_CONTENT_LEN ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -1394,17 +1442,26 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) } else #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) +#if defined(MBEDTLS_GCM_C) || \ + defined(MBEDTLS_CCM_C) || \ + defined(MBEDTLS_CHACHAPOLY_C) if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM ) + mode == MBEDTLS_MODE_CCM || + mode == MBEDTLS_MODE_CHACHAPOLY ) { int ret; size_t enc_msglen, olen; unsigned char *enc_msg; unsigned char add_data[13]; - unsigned char taglen = ssl->transform_out->ciphersuite_info->flags & + unsigned char iv[12]; + mbedtls_ssl_transform *transform = ssl->transform_out; + unsigned char taglen = transform->ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; + size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen; + /* + * Prepare additional authenticated data + */ memcpy( add_data, ssl->out_ctr, 8 ); add_data[8] = ssl->out_msgtype; mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, @@ -1412,44 +1469,57 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; add_data[12] = ssl->out_msglen & 0xFF; - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", - add_data, 13 ); + MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); /* * Generate IV */ - if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 ) + if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) + { + /* GCM and CCM: fixed || explicit (=seqnum) */ + memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); + memcpy( iv + transform->fixed_ivlen, ssl->out_ctr, 8 ); + memcpy( ssl->out_iv, ssl->out_ctr, 8 ); + + } + else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) + { + /* ChachaPoly: fixed XOR sequence number */ + unsigned char i; + + memcpy( iv, transform->iv_enc, transform->fixed_ivlen ); + + for( i = 0; i < 8; i++ ) + iv[i+4] ^= ssl->out_ctr[i]; + } + else { /* Reminder if we ever add an AEAD mode with a different size */ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, - ssl->out_ctr, 8 ); - memcpy( ssl->out_iv, ssl->out_ctr, 8 ); - - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, - ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", + iv, transform->ivlen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", + ssl->out_iv, explicit_ivlen ); /* - * Fix pointer positions and message length with added IV + * Fix message length with added IV */ enc_msg = ssl->out_msg; enc_msglen = ssl->out_msglen; - ssl->out_msglen += ssl->transform_out->ivlen - - ssl->transform_out->fixed_ivlen; + ssl->out_msglen += explicit_ivlen; MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " - "including %d bytes of padding", - ssl->out_msglen, 0 ) ); + "including 0 bytes of padding", + ssl->out_msglen ) ); /* * Encrypt and authenticate */ - if( ( ret = mbedtls_cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc, - ssl->transform_out->iv_enc, - ssl->transform_out->ivlen, + if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, + iv, transform->ivlen, add_data, 13, enc_msg, enc_msglen, enc_msg, &olen, @@ -1609,7 +1679,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) { - size_t i; mbedtls_cipher_mode_t mode; int auth_done = 0; #if defined(SSL_SOME_MODES_USE_MAC) @@ -1659,20 +1728,27 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) } else #endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ -#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) +#if defined(MBEDTLS_GCM_C) || \ + defined(MBEDTLS_CCM_C) || \ + defined(MBEDTLS_CHACHAPOLY_C) if( mode == MBEDTLS_MODE_GCM || - mode == MBEDTLS_MODE_CCM ) + mode == MBEDTLS_MODE_CCM || + mode == MBEDTLS_MODE_CHACHAPOLY ) { int ret; size_t dec_msglen, olen; unsigned char *dec_msg; unsigned char *dec_msg_result; unsigned char add_data[13]; - unsigned char taglen = ssl->transform_in->ciphersuite_info->flags & + unsigned char iv[12]; + mbedtls_ssl_transform *transform = ssl->transform_in; + unsigned char taglen = transform->ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; - size_t explicit_iv_len = ssl->transform_in->ivlen - - ssl->transform_in->fixed_ivlen; + size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen; + /* + * Compute and update sizes + */ if( ssl->in_msglen < explicit_iv_len + taglen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " @@ -1686,6 +1762,9 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) dec_msg_result = ssl->in_msg; ssl->in_msglen = dec_msglen; + /* + * Prepare additional authenticated data + */ memcpy( add_data, ssl->in_ctr, 8 ); add_data[8] = ssl->in_msgtype; mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, @@ -1693,23 +1772,43 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; add_data[12] = ssl->in_msglen & 0xFF; - MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", - add_data, 13 ); + MBEDTLS_SSL_DEBUG_BUF( 4, "additional data for AEAD", add_data, 13 ); - memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen, - ssl->in_iv, - ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen ); + /* + * Prepare IV + */ + if( transform->ivlen == 12 && transform->fixed_ivlen == 4 ) + { + /* GCM and CCM: fixed || explicit (transmitted) */ + memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); + memcpy( iv + transform->fixed_ivlen, ssl->in_iv, 8 ); - MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec, - ssl->transform_in->ivlen ); + } + else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 ) + { + /* ChachaPoly: fixed XOR sequence number */ + unsigned char i; + + memcpy( iv, transform->iv_dec, transform->fixed_ivlen ); + + for( i = 0; i < 8; i++ ) + iv[i+4] ^= ssl->in_ctr[i]; + } + else + { + /* Reminder if we ever add an AEAD mode with a different size */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen ); MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); /* * Decrypt and authenticate */ if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, - ssl->transform_in->iv_dec, - ssl->transform_in->ivlen, + iv, transform->ivlen, add_data, 13, dec_msg, dec_msglen, dec_msg_result, &olen, @@ -1827,6 +1926,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) */ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) { + unsigned char i; dec_msglen -= ssl->transform_in->ivlen; ssl->in_msglen -= ssl->transform_in->ivlen; @@ -1900,27 +2000,28 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) * and fake check up to 256 bytes of padding */ size_t pad_count = 0, real_count = 1; - size_t padding_idx = ssl->in_msglen - padlen - 1; + size_t padding_idx = ssl->in_msglen - padlen; + size_t i; /* * Padding is guaranteed to be incorrect if: - * 1. padlen >= ssl->in_msglen + * 1. padlen > ssl->in_msglen * - * 2. padding_idx >= MBEDTLS_SSL_MAX_CONTENT_LEN + + * 2. padding_idx > MBEDTLS_SSL_IN_CONTENT_LEN + * ssl->transform_in->maclen * * In both cases we reset padding_idx to a safe value (0) to * prevent out-of-buffer reads. */ - correct &= ( ssl->in_msglen >= padlen + 1 ); - correct &= ( padding_idx < MBEDTLS_SSL_MAX_CONTENT_LEN + + correct &= ( padlen <= ssl->in_msglen ); + correct &= ( padding_idx <= MBEDTLS_SSL_IN_CONTENT_LEN + ssl->transform_in->maclen ); padding_idx *= correct; - for( i = 1; i <= 256; i++ ) + for( i = 0; i < 256; i++ ) { - real_count &= ( i <= padlen ); + real_count &= ( i < padlen ); pad_count += real_count * ( ssl->in_msg[padding_idx + i] == padlen - 1 ); } @@ -1951,8 +2052,10 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } +#if defined(MBEDTLS_SSL_DEBUG_ALL) MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", ssl->in_msg, ssl->in_msglen ); +#endif /* * Authenticate if not done yet. @@ -1985,20 +2088,69 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) { /* * Process MAC and always update for padlen afterwards to make - * total time independent of padlen - * - * extra_run compensates MAC check for padlen + * total time independent of padlen. * * Known timing attacks: * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) * - * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values - * correctly. (We round down instead of up, so -56 is the correct - * value for our calculations instead of -55) + * To compensate for different timings for the MAC calculation + * depending on how much padding was removed (which is determined + * by padlen), process extra_run more blocks through the hash + * function. + * + * The formula in the paper is + * extra_run = ceil( (L1-55) / 64 ) - ceil( (L2-55) / 64 ) + * where L1 is the size of the header plus the decrypted message + * plus CBC padding and L2 is the size of the header plus the + * decrypted message. This is for an underlying hash function + * with 64-byte blocks. + * We use ( (Lx+8) / 64 ) to handle 'negative Lx' values + * correctly. We round down instead of up, so -56 is the correct + * value for our calculations instead of -55. + * + * Repeat the formula rather than defining a block_size variable. + * This avoids requiring division by a variable at runtime + * (which would be marginally less efficient and would require + * linking an extra division function in some builds). */ size_t j, extra_run = 0; - extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - - ( 13 + ssl->in_msglen + 8 ) / 64; + + /* + * The next two sizes are the minimum and maximum values of + * in_msglen over all padlen values. + * + * They're independent of padlen, since we previously did + * in_msglen -= padlen. + * + * Note that max_len + maclen is never more than the buffer + * length, as we previously did in_msglen -= maclen too. + */ + const size_t max_len = ssl->in_msglen + padlen; + const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0; + + switch( ssl->transform_in->ciphersuite_info->mac ) + { +#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \ + defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_MD5: + case MBEDTLS_MD_SHA1: + case MBEDTLS_MD_SHA256: + /* 8 bytes of message size, 64-byte compression blocks */ + extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - + ( 13 + ssl->in_msglen + 8 ) / 64; + break; +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + /* 16 bytes of message size, 128-byte compression blocks */ + extra_run = ( 13 + ssl->in_msglen + padlen + 16 ) / 128 - + ( 13 + ssl->in_msglen + 16 ) / 128; + break; +#endif + default: + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } extra_run &= correct * 0xFF; @@ -2007,12 +2159,25 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, ssl->in_msglen ); + /* Make sure we access everything even when padlen > 0. This + * makes the synchronisation requirements for just-in-time + * Prime+Probe attacks much tighter and hopefully impractical. */ + ssl_read_memory( ssl->in_msg + ssl->in_msglen, padlen ); mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, mac_expect ); - /* Call mbedtls_md_process at least once due to cache attacks */ + + /* Call mbedtls_md_process at least once due to cache attacks + * that observe whether md_process() was called of not */ for( j = 0; j < extra_run + 1; j++ ) mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); + + /* Make sure we access all the memory that could contain the MAC, + * before we check it in the next code block. This makes the + * synchronisation requirements for just-in-time Prime+Probe + * attacks much tighter and hopefully impractical. */ + ssl_read_memory( ssl->in_msg + min_len, + max_len - min_len + ssl->transform_in->maclen ); } else #endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ @@ -2022,9 +2187,11 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } +#if defined(MBEDTLS_SSL_DEBUG_ALL) MBEDTLS_SSL_DEBUG_BUF( 4, "expected mac", mac_expect, ssl->transform_in->maclen ); MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen ); +#endif if( mbedtls_ssl_safer_memcmp( ssl->in_msg + ssl->in_msglen, mac_expect, ssl->transform_in->maclen ) != 0 ) @@ -2053,6 +2220,16 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) if( ssl->in_msglen == 0 ) { +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 + && ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + /* TLS v1.2 explicitly disallows zero-length messages which are not application data */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid zero-length message type: %d", ssl->in_msgtype ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + ssl->nb_zero++; /* @@ -2077,6 +2254,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) else #endif { + unsigned char i; for( i = 8; i > ssl_ep_len( ssl ); i-- ) if( ++ssl->in_ctr[i - 1] != 0 ) break; @@ -2126,7 +2304,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl ) ssl->transform_out->ctx_deflate.next_in = msg_pre; ssl->transform_out->ctx_deflate.avail_in = len_pre; ssl->transform_out->ctx_deflate.next_out = msg_post; - ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN - bytes_written; + ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written; ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); if( ret != Z_OK ) @@ -2135,7 +2313,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); } - ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN - + ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN - ssl->transform_out->ctx_deflate.avail_out - bytes_written; MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", @@ -2173,7 +2351,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) ssl->transform_in->ctx_inflate.next_in = msg_pre; ssl->transform_in->ctx_inflate.avail_in = len_pre; ssl->transform_in->ctx_inflate.next_out = msg_post; - ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_BUFFER_LEN - + ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN - header_bytes; ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); @@ -2183,7 +2361,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); } - ssl->in_msglen = MBEDTLS_SSL_BUFFER_LEN - + ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN - ssl->transform_in->ctx_inflate.avail_out - header_bytes; MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", @@ -2258,7 +2436,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } - if( nb_want > MBEDTLS_SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) + if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -2344,7 +2522,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) } else { - len = MBEDTLS_SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); + len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) timeout = ssl->handshake->retransmit_timeout; @@ -2798,12 +2976,12 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { /* Make room for the additional DTLS fields */ - if( MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen < 8 ) + if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS handshake message too large: " "size %u, maximum %u", (unsigned) ( ssl->in_hslen - 4 ), - (unsigned) ( MBEDTLS_SSL_MAX_CONTENT_LEN - 12 ) ) ); + (unsigned) ( MBEDTLS_SSL_OUT_CONTENT_LEN - 12 ) ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -3016,7 +3194,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", msg_len ) ); - if( ssl->in_hslen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( ssl->in_hslen > MBEDTLS_SSL_IN_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too large" ) ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); @@ -3120,7 +3298,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) ssl->next_record_offset = new_remain - ssl->in_hdr; ssl->in_left = ssl->next_record_offset + remain_len; - if( ssl->in_left > MBEDTLS_SSL_BUFFER_LEN - + if( ssl->in_left > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "reassembled message too large for buffer" ) ); @@ -3496,7 +3674,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) ssl->conf->p_cookie, ssl->cli_id, ssl->cli_id_len, ssl->in_buf, ssl->in_left, - ssl->out_buf, MBEDTLS_SSL_MAX_CONTENT_LEN, &len ); + ssl->out_buf, MBEDTLS_SSL_OUT_CONTENT_LEN, &len ); MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); @@ -3593,7 +3771,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) } /* Check length against the size of our buffer */ - if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN + if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_msg - ssl->in_buf ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); @@ -3687,7 +3865,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) if( ssl->transform_in == NULL ) { if( ssl->in_msglen < 1 || - ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); @@ -3703,7 +3881,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_SSL3) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN ) + ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_IN_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); @@ -3716,7 +3894,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) */ if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 && ssl->in_msglen > ssl->transform_in->minlen + - MBEDTLS_SSL_MAX_CONTENT_LEN + 256 ) + MBEDTLS_SSL_IN_CONTENT_LEN + 256 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); @@ -3764,7 +3942,7 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", ssl->in_msg, ssl->in_msglen ); - if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); @@ -4096,6 +4274,16 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) { + if( ssl->in_msglen != 2 ) + { + /* Note: Standard allows for more than one 2 byte alert + to be packed in a single message, but Mbed TLS doesn't + currently support this. */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid alert message, len: %d", + ssl->in_msglen ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]", ssl->in_msg[0], ssl->in_msg[1] ) ); @@ -4325,10 +4513,10 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) while( crt != NULL ) { n = crt->raw.len; - if( n > MBEDTLS_SSL_MAX_CONTENT_LEN - 3 - i ) + if( n > MBEDTLS_SSL_OUT_CONTENT_LEN - 3 - i ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", - i + 3 + n, MBEDTLS_SSL_MAX_CONTENT_LEN ) ); + i + 3 + n, MBEDTLS_SSL_OUT_CONTENT_LEN ) ); return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE ); } @@ -4528,6 +4716,12 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) while( i < ssl->in_hslen ) { + if ( i + 3 > ssl->in_hslen ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } if( ssl->in_msg[i] != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); @@ -5202,7 +5396,7 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) /* * Free our handshake params */ - mbedtls_ssl_handshake_free( ssl->handshake ); + mbedtls_ssl_handshake_free( ssl ); mbedtls_free( ssl->handshake ); ssl->handshake = NULL; @@ -5557,7 +5751,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) if( ssl->session_negotiate ) mbedtls_ssl_session_free( ssl->session_negotiate ); if( ssl->handshake ) - mbedtls_ssl_handshake_free( ssl->handshake ); + mbedtls_ssl_handshake_free( ssl ); /* * Either the pointers are now NULL or cleared properly and can be freed. @@ -5662,17 +5856,23 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, const mbedtls_ssl_config *conf ) { int ret; - const size_t len = MBEDTLS_SSL_BUFFER_LEN; ssl->conf = conf; /* * Prepare base structures */ - if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL || - ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL ) + ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN ); + if( ssl->in_buf == NULL ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN ); + if( ssl->out_buf == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) ); mbedtls_free( ssl->in_buf ); ssl->in_buf = NULL; return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); @@ -5773,9 +5973,9 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) ssl->transform_in = NULL; ssl->transform_out = NULL; - memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); + memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN ); if( partial == 0 ) - memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); + memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN ); #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_reset != NULL ) @@ -5995,27 +6195,27 @@ static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, mbedtls_x509_crt *cert, mbedtls_pk_context *key ) { - mbedtls_ssl_key_cert *new; + mbedtls_ssl_key_cert *new_cert; - new = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); - if( new == NULL ) + new_cert = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); + if( new_cert == NULL ) return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - new->cert = cert; - new->key = key; - new->next = NULL; + new_cert->cert = cert; + new_cert->key = key; + new_cert->next = NULL; /* Update head is the list was null, else add to the end */ if( *head == NULL ) { - *head = new; + *head = new_cert; } else { mbedtls_ssl_key_cert *cur = *head; while( cur->next != NULL ) cur = cur->next; - cur->next = new; + cur->next = new_cert; } return( 0 ); @@ -6100,7 +6300,7 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, /* Identity len will be encoded on two bytes */ if( ( psk_identity_len >> 16 ) != 0 || - psk_identity_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) + psk_identity_len > MBEDTLS_SSL_OUT_CONTENT_LEN ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -6401,7 +6601,7 @@ void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ) { if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || - mfl_code_to_length[mfl_code] > MBEDTLS_SSL_MAX_CONTENT_LEN ) + ssl_mfl_code_to_length( mfl_code ) > MBEDTLS_TLS_EXT_ADV_CONTENT_LEN ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -6480,6 +6680,43 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, } #endif +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) +void mbedtls_ssl_conf_async_private_cb( + mbedtls_ssl_config *conf, + mbedtls_ssl_async_sign_t *f_async_sign, + mbedtls_ssl_async_decrypt_t *f_async_decrypt, + mbedtls_ssl_async_resume_t *f_async_resume, + mbedtls_ssl_async_cancel_t *f_async_cancel, + void *async_config_data ) +{ + conf->f_async_sign_start = f_async_sign; + conf->f_async_decrypt_start = f_async_decrypt; + conf->f_async_resume = f_async_resume; + conf->f_async_cancel = f_async_cancel; + conf->p_async_config_data = async_config_data; +} + +void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf ) +{ + return( conf->p_async_config_data ); +} + +void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl ) +{ + if( ssl->handshake == NULL ) + return( NULL ); + else + return( ssl->handshake->user_async_ctx ); +} + +void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl, + void *ctx ) +{ + if( ssl->handshake != NULL ) + ssl->handshake->user_async_ctx = ctx; +} +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + /* * SSL get accessors */ @@ -6642,15 +6879,15 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) /* * Assume mfl_code is correct since it was checked when set */ - max_len = mfl_code_to_length[ssl->conf->mfl_code]; + max_len = ssl_mfl_code_to_length( ssl->conf->mfl_code ); /* * Check if a smaller max length was negotiated */ if( ssl->session_out != NULL && - mfl_code_to_length[ssl->session_out->mfl_code] < max_len ) + ssl_mfl_code_to_length( ssl->session_out->mfl_code ) < max_len ) { - max_len = mfl_code_to_length[ssl->session_out->mfl_code]; + max_len = ssl_mfl_code_to_length( ssl->session_out->mfl_code ); } return max_len; @@ -7194,8 +7431,16 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } /* - * Send application data to be encrypted by the SSL layer, - * taking care of max fragment length and buffer size + * Send application data to be encrypted by the SSL layer, taking care of max + * fragment length and buffer size. + * + * According to RFC 5246 Section 6.2.1: + * + * Zero-length fragments of Application data MAY be sent as they are + * potentially useful as a traffic analysis countermeasure. + * + * Therefore, it is possible that the input message length is 0 and the + * corresponding return code is 0 on success. */ static int ssl_write_real( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) @@ -7204,7 +7449,7 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) size_t max_len = mbedtls_ssl_get_max_frag_len( ssl ); #else - size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN; #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ if( len > max_len ) { @@ -7223,6 +7468,12 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, if( ssl->out_left != 0 ) { + /* + * The user has previously tried to send the data and + * MBEDTLS_ERR_SSL_WANT_WRITE or the message was only partially + * written. In this case, we expect the high-level write function + * (e.g. mbedtls_ssl_write()) to be called with the same parameters + */ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); @@ -7231,6 +7482,11 @@ static int ssl_write_real( mbedtls_ssl_context *ssl, } else { + /* + * The user is trying to send a message the first time, so we need to + * copy the data into the internal buffers and setup the data structure + * to keep track of partial writes + */ ssl->out_msglen = len; ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; memcpy( ssl->out_msg, buf, len ); @@ -7387,11 +7643,21 @@ static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) } #endif /* MBEDTLS_X509_CRT_PARSE_C */ -void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ) +void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl ) { + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + if( handshake == NULL ) return; +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 ) + { + ssl->conf->f_async_cancel( ssl ); + handshake->async_in_progress = 0; + } +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) mbedtls_md5_free( &handshake->fin_md5 ); @@ -7496,20 +7762,20 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) if( ssl->out_buf != NULL ) { - mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN ); + mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN ); mbedtls_free( ssl->out_buf ); } if( ssl->in_buf != NULL ) { - mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN ); + mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN ); mbedtls_free( ssl->in_buf ); } #if defined(MBEDTLS_ZLIB_SUPPORT) if( ssl->compress_buf != NULL ) { - mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN ); + mbedtls_platform_zeroize( ssl->compress_buf, MBEDTLS_SSL_COMPRESS_BUFFER_LEN ); mbedtls_free( ssl->compress_buf ); } #endif @@ -7522,7 +7788,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) if( ssl->handshake ) { - mbedtls_ssl_handshake_free( ssl->handshake ); + mbedtls_ssl_handshake_free( ssl ); mbedtls_ssl_transform_free( ssl->transform_negotiate ); mbedtls_ssl_session_free( ssl->session_negotiate ); @@ -8289,13 +8555,14 @@ exit: #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, - unsigned char *output, - unsigned char *data, size_t data_len, - mbedtls_md_type_t md_alg ) + unsigned char *hash, size_t *hashlen, + unsigned char *data, size_t data_len, + mbedtls_md_type_t md_alg ) { int ret = 0; mbedtls_md_context_t ctx; const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + *hashlen = mbedtls_md_get_size( md_info ); mbedtls_md_init( &ctx ); @@ -8326,7 +8593,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret ); goto exit; } - if( ( ret = mbedtls_md_finish( &ctx, output ) ) != 0 ) + if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret ); goto exit; diff --git a/thirdparty/mbedtls/library/threading.c b/thirdparty/mbedtls/library/threading.c index f1c37245c7..7a32e672c7 100644 --- a/thirdparty/mbedtls/library/threading.c +++ b/thirdparty/mbedtls/library/threading.c @@ -114,9 +114,6 @@ void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * #if defined(MBEDTLS_FS_IO) mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); #endif -#if defined(MBEDTLS_HAVE_TIME_DATE) - mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); -#endif } /* @@ -127,9 +124,6 @@ void mbedtls_threading_free_alt( void ) #if defined(MBEDTLS_FS_IO) mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); #endif -#if defined(MBEDTLS_HAVE_TIME_DATE) - mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); -#endif } #endif /* MBEDTLS_THREADING_ALT */ @@ -142,8 +136,5 @@ void mbedtls_threading_free_alt( void ) #if defined(MBEDTLS_FS_IO) mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; #endif -#if defined(MBEDTLS_HAVE_TIME_DATE) -mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; -#endif #endif /* MBEDTLS_THREADING_C */ diff --git a/thirdparty/mbedtls/library/timing.c b/thirdparty/mbedtls/library/timing.c index 6a30e51259..3e8139f1f9 100644 --- a/thirdparty/mbedtls/library/timing.c +++ b/thirdparty/mbedtls/library/timing.c @@ -39,7 +39,8 @@ #if !defined(MBEDTLS_TIMING_ALT) #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) + !defined(__APPLE__) && !defined(_WIN32) && !defined(__QNXNTO__) && \ + !defined(__HAIKU__) #error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" #endif diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c index e8e448f6f8..777b6034c4 100644 --- a/thirdparty/mbedtls/library/version_features.c +++ b/thirdparty/mbedtls/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 */ @@ -102,6 +105,12 @@ 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_CHACHAPOLY_ALT) + "MBEDTLS_CHACHAPOLY_ALT", +#endif /* MBEDTLS_CHACHAPOLY_ALT */ #if defined(MBEDTLS_CMAC_ALT) "MBEDTLS_CMAC_ALT", #endif /* MBEDTLS_CMAC_ALT */ @@ -117,6 +126,9 @@ static const char *features[] = { #if defined(MBEDTLS_GCM_ALT) "MBEDTLS_GCM_ALT", #endif /* MBEDTLS_GCM_ALT */ +#if defined(MBEDTLS_NIST_KW_ALT) + "MBEDTLS_NIST_KW_ALT", +#endif /* MBEDTLS_NIST_KW_ALT */ #if defined(MBEDTLS_MD2_ALT) "MBEDTLS_MD2_ALT", #endif /* MBEDTLS_MD2_ALT */ @@ -126,6 +138,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 */ @@ -255,6 +270,12 @@ static const char *features[] = { #if defined(MBEDTLS_CIPHER_MODE_CTR) "MBEDTLS_CIPHER_MODE_CTR", #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_OFB) + "MBEDTLS_CIPHER_MODE_OFB", +#endif /* MBEDTLS_CIPHER_MODE_OFB */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) + "MBEDTLS_CIPHER_MODE_XTS", +#endif /* MBEDTLS_CIPHER_MODE_XTS */ #if defined(MBEDTLS_CIPHER_NULL_CIPHER) "MBEDTLS_CIPHER_NULL_CIPHER", #endif /* MBEDTLS_CIPHER_NULL_CIPHER */ @@ -405,6 +426,9 @@ static const char *features[] = { #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) "MBEDTLS_SSL_ALL_ALERT_MESSAGES", #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + "MBEDTLS_SSL_ASYNC_PRIVATE", +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ #if defined(MBEDTLS_SSL_DEBUG_ALL) "MBEDTLS_SSL_DEBUG_ALL", #endif /* MBEDTLS_SSL_DEBUG_ALL */ @@ -543,6 +567,12 @@ 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_CHACHAPOLY_C) + "MBEDTLS_CHACHAPOLY_C", +#endif /* MBEDTLS_CHACHAPOLY_C */ #if defined(MBEDTLS_CIPHER_C) "MBEDTLS_CIPHER_C", #endif /* MBEDTLS_CIPHER_C */ @@ -585,9 +615,15 @@ static const char *features[] = { #if defined(MBEDTLS_HAVEGE_C) "MBEDTLS_HAVEGE_C", #endif /* MBEDTLS_HAVEGE_C */ +#if defined(MBEDTLS_HKDF_C) + "MBEDTLS_HKDF_C", +#endif /* MBEDTLS_HKDF_C */ #if defined(MBEDTLS_HMAC_DRBG_C) "MBEDTLS_HMAC_DRBG_C", #endif /* MBEDTLS_HMAC_DRBG_C */ +#if defined(MBEDTLS_NIST_KW_C) + "MBEDTLS_NIST_KW_C", +#endif /* MBEDTLS_NIST_KW_C */ #if defined(MBEDTLS_MD_C) "MBEDTLS_MD_C", #endif /* MBEDTLS_MD_C */ @@ -639,6 +675,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/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c index 371d6da1dc..2e6795f750 100644 --- a/thirdparty/mbedtls/library/x509.c +++ b/thirdparty/mbedtls/library/x509.c @@ -29,6 +29,10 @@ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ +/* Ensure gmtime_r is available even with -std=c99; must be included before + * config.h, which pulls in glibc's features.h. Harmless on other platforms. */ +#define _POSIX_C_SOURCE 200112L + #if !defined(MBEDTLS_CONFIG_FILE) #include "mbedtls/config.h" #else @@ -59,26 +63,13 @@ #define mbedtls_snprintf snprintf #endif - #if defined(MBEDTLS_HAVE_TIME) #include "mbedtls/platform_time.h" #endif - -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#include <windows.h> -#else +#if defined(MBEDTLS_HAVE_TIME_DATE) #include <time.h> #endif -#if defined(MBEDTLS_FS_IO) -#include <stdio.h> -#if !defined(_WIN32) -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#endif -#endif - #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } #define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } @@ -903,36 +894,18 @@ int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) * Set the time structure to the current time. * Return 0 on success, non-zero on failure. */ -#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -static int x509_get_current_time( mbedtls_x509_time *now ) -{ - SYSTEMTIME st; - - GetSystemTime( &st ); - - now->year = st.wYear; - now->mon = st.wMonth; - now->day = st.wDay; - now->hour = st.wHour; - now->min = st.wMinute; - now->sec = st.wSecond; - - return( 0 ); -} -#else static int x509_get_current_time( mbedtls_x509_time *now ) { - struct tm *lt; + struct tm *lt, tm_buf; mbedtls_time_t tt; int ret = 0; -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - tt = mbedtls_time( NULL ); - lt = gmtime( &tt ); +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + lt = gmtime_s( &tm_buf, &tt ) == 0 ? &tm_buf : NULL; +#else + lt = gmtime_r( &tt, &tm_buf ); +#endif if( lt == NULL ) ret = -1; @@ -946,14 +919,8 @@ static int x509_get_current_time( mbedtls_x509_time *now ) now->sec = lt->tm_sec; } -#if defined(MBEDTLS_THREADING_C) - if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) - return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); -#endif - return( ret ); } -#endif /* _WIN32 && !EFIX64 && !EFI32 */ /* * Return 0 if before <= after, 1 otherwise diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c index 038eae0257..3cf1743821 100644 --- a/thirdparty/mbedtls/library/x509_crt.c +++ b/thirdparty/mbedtls/library/x509_crt.c @@ -1139,7 +1139,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) char filename[MAX_PATH]; char *p; size_t len = strlen( path ); - int lengthAsInt = 0; + int length_as_int = 0; WIN32_FIND_DATAW file_data; HANDLE hFind; @@ -1154,7 +1154,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) p = filename + len; filename[len++] = '*'; - if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) ) + if ( FAILED ( SizeTToInt( len, &length_as_int ) ) ) return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); /* @@ -1165,7 +1165,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) * incoming string are less than MAX_PATH to avoid a buffer overrun with * MultiByteToWideChar(). */ - w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir, + w_ret = MultiByteToWideChar( CP_ACP, 0, filename, length_as_int, szDir, MAX_PATH - 3 ); if( w_ret == 0 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); @@ -1182,11 +1182,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; - if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) ) + if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &length_as_int ) ) ) return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, - lengthAsInt, + length_as_int, p, (int) len - 1, NULL, NULL ); if( w_ret == 0 ) diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c index 3e8e8fbc6a..f84425728a 100644 --- a/thirdparty/mbedtls/library/x509_csr.c +++ b/thirdparty/mbedtls/library/x509_csr.c @@ -274,34 +274,25 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); #if defined(MBEDTLS_PEM_PARSE_C) - mbedtls_pem_init( &pem ); - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( buf[buflen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else + if( buf[buflen - 1] == '\0' ) + { + mbedtls_pem_init( &pem ); ret = mbedtls_pem_read_buffer( &pem, "-----BEGIN CERTIFICATE REQUEST-----", "-----END CERTIFICATE REQUEST-----", buf, NULL, 0, &use_len ); - if( ret == 0 ) - { - /* - * Was PEM encoded, parse the result - */ - if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 ) - return( ret ); + if( ret == 0 ) + /* + * Was PEM encoded, parse the result + */ + ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ); mbedtls_pem_free( &pem ); - return( 0 ); - } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) - { - mbedtls_pem_free( &pem ); - return( ret ); + if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); } - else #endif /* MBEDTLS_PEM_PARSE_C */ return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); } |