diff --git a/app/include/mbedtls/aes.h b/app/include/mbedtls/aes.h index a36e825a..1829f724 100644 --- a/app/include/mbedtls/aes.h +++ b/app/include/mbedtls/aes.h @@ -39,6 +39,11 @@ #define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ #define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + #if !defined(MBEDTLS_AES_ALT) // Regular implementation // @@ -253,10 +258,12 @@ int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, * \param ctx AES context * \param input Plaintext block * \param output Output (ciphertext) block + * + * \return 0 if successful */ -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); +int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); /** * \brief Internal AES block decryption function @@ -266,10 +273,49 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, * \param ctx AES context * \param input Ciphertext block * \param output Output (plaintext) block + * + * \return 0 if successful */ -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ); +int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#if defined(MBEDTLS_DEPRECATED_WARNING) +#define MBEDTLS_DEPRECATED __attribute__((deprecated)) +#else +#define MBEDTLS_DEPRECATED +#endif +/** + * \brief Deprecated internal AES block encryption function + * without return value. + * + * \deprecated Superseded by mbedtls_aes_encrypt_ext() in 2.5.0 + * + * \param ctx AES context + * \param input Plaintext block + * \param output Output (ciphertext) block + */ +MBEDTLS_DEPRECATED void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief Deprecated internal AES block decryption function + * without return value. + * + * \deprecated Superseded by mbedtls_aes_decrypt_ext() in 2.5.0 + * + * \param ctx AES context + * \param input Ciphertext block + * \param output Output (plaintext) block + */ +MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ); + +#undef MBEDTLS_DEPRECATED +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ #ifdef __cplusplus } diff --git a/app/include/mbedtls/bignum.h b/app/include/mbedtls/bignum.h index aa51556a..456a8042 100644 --- a/app/include/mbedtls/bignum.h +++ b/app/include/mbedtls/bignum.h @@ -103,36 +103,71 @@ /* * Define the base integer type, architecture-wise. * - * 32-bit integers can be forced on 64-bit arches (eg. for testing purposes) - * by defining MBEDTLS_HAVE_INT32 and undefining MBEDTLS_HAVE_ASM + * 32 or 64-bit integer types can be forced regardless of the underlying + * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 + * respectively and undefining MBEDTLS_HAVE_ASM. + * + * Double-width integers (e.g. 128-bit in 64-bit architectures) can be + * disabled by defining MBEDTLS_NO_UDBL_DIVISION. */ -#if ( ! defined(MBEDTLS_HAVE_INT32) && \ - defined(_MSC_VER) && defined(_M_AMD64) ) - #define MBEDTLS_HAVE_INT64 - typedef int64_t mbedtls_mpi_sint; - typedef uint64_t mbedtls_mpi_uint; -#else - #if ( ! defined(MBEDTLS_HAVE_INT32) && \ - defined(__GNUC__) && ( \ - defined(__amd64__) || defined(__x86_64__) || \ - defined(__ppc64__) || defined(__powerpc64__) || \ - defined(__ia64__) || defined(__alpha__) || \ - (defined(__sparc__) && defined(__arch64__)) || \ - defined(__s390x__) || defined(__mips64) ) ) - #define MBEDTLS_HAVE_INT64 - typedef int64_t mbedtls_mpi_sint; - typedef uint64_t mbedtls_mpi_uint; - /* mbedtls_t_udbl defined as 128-bit unsigned int */ - typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); - #define MBEDTLS_HAVE_UDBL - #else - #define MBEDTLS_HAVE_INT32 - typedef int32_t mbedtls_mpi_sint; - typedef uint32_t mbedtls_mpi_uint; - typedef uint64_t mbedtls_t_udbl; - #define MBEDTLS_HAVE_UDBL - #endif /* !MBEDTLS_HAVE_INT32 && __GNUC__ && 64-bit platform */ -#endif /* !MBEDTLS_HAVE_INT32 && _MSC_VER && _M_AMD64 */ +#if !defined(MBEDTLS_HAVE_INT32) + #if defined(_MSC_VER) && defined(_M_AMD64) + /* Always choose 64-bit when using MSC */ + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* !MBEDTLS_HAVE_INT64 */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #elif defined(__GNUC__) && ( \ + defined(__amd64__) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__powerpc64__) || \ + defined(__ia64__) || defined(__alpha__) || \ + ( defined(__sparc__) && defined(__arch64__) ) || \ + defined(__s390x__) || defined(__mips64) ) + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* MBEDTLS_HAVE_INT64 */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #if !defined(MBEDTLS_NO_UDBL_DIVISION) + /* mbedtls_t_udbl defined as 128-bit unsigned int */ + typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ + #elif defined(__ARMCC_VERSION) && defined(__aarch64__) + /* + * __ARMCC_VERSION is defined for both armcc and armclang and + * __aarch64__ is only defined by armclang when compiling 64-bit code + */ + #if !defined(MBEDTLS_HAVE_INT64) + #define MBEDTLS_HAVE_INT64 + #endif /* !MBEDTLS_HAVE_INT64 */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #if !defined(MBEDTLS_NO_UDBL_DIVISION) + /* mbedtls_t_udbl defined as 128-bit unsigned int */ + typedef __uint128_t mbedtls_t_udbl; + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ + #elif defined(MBEDTLS_HAVE_INT64) + /* Force 64-bit integers with unknown compiler */ + typedef int64_t mbedtls_mpi_sint; + typedef uint64_t mbedtls_mpi_uint; + #endif +#endif /* !MBEDTLS_HAVE_INT32 */ + +#if !defined(MBEDTLS_HAVE_INT64) + /* Default to 32-bit compilation */ + #if !defined(MBEDTLS_HAVE_INT32) + #define MBEDTLS_HAVE_INT32 + #endif /* !MBEDTLS_HAVE_INT32 */ + typedef int32_t mbedtls_mpi_sint; + typedef uint32_t mbedtls_mpi_uint; + #if !defined(MBEDTLS_NO_UDBL_DIVISION) + typedef uint64_t mbedtls_t_udbl; + #define MBEDTLS_HAVE_UDBL + #endif /* !MBEDTLS_NO_UDBL_DIVISION */ +#endif /* !MBEDTLS_HAVE_INT64 */ #ifdef __cplusplus extern "C" { @@ -340,7 +375,7 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, #if defined(MBEDTLS_FS_IO) /** - * \brief Read X from an opened file + * \brief Read MPI from a line in an opened file * * \param X Destination MPI * \param radix Input numeric base @@ -349,6 +384,15 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, * \return 0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if * the file read buffer is too small or a * MBEDTLS_ERR_MPI_XXX error code + * + * \note On success, this function advances the file stream + * to the end of the current line or to EOF. + * + * The function returns 0 on an empty line. + * + * Leading whitespaces are ignored, as is a + * '0x' prefix for radix 16. + * */ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ); @@ -665,8 +709,8 @@ int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B * * \return 0 if successful, * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, - * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or nil - MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N + * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1, + MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N. */ int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ); diff --git a/app/include/mbedtls/bn_mul.h b/app/include/mbedtls/bn_mul.h index 5408d414..cac3f145 100644 --- a/app/include/mbedtls/bn_mul.h +++ b/app/include/mbedtls/bn_mul.h @@ -162,10 +162,6 @@ #define MULADDC_INIT \ asm( \ - "movq %3, %%rsi \n\t" \ - "movq %4, %%rdi \n\t" \ - "movq %5, %%rcx \n\t" \ - "movq %6, %%rbx \n\t" \ "xorq %%r8, %%r8 \n\t" #define MULADDC_CORE \ @@ -181,12 +177,9 @@ "addq $8, %%rdi \n\t" #define MULADDC_STOP \ - "movq %%rcx, %0 \n\t" \ - "movq %%rdi, %1 \n\t" \ - "movq %%rsi, %2 \n\t" \ - : "=m" (c), "=m" (d), "=m" (s) \ - : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \ + : "+c" (c), "+D" (d), "+S" (s) \ + : "b" (b) \ + : "rax", "rdx", "r8" \ ); #endif /* AMD64 */ @@ -563,7 +556,23 @@ #endif /* TriCore */ -#if defined(__arm__) +/* + * gcc -O0 by default uses r7 for the frame pointer, so it complains about our + * use of r7 below, unless -fomit-frame-pointer is passed. Unfortunately, + * passing that option is not easy when building with yotta. + * + * On the other hand, -fomit-frame-pointer is implied by any -Ox options with + * x !=0, which we can detect using __OPTIMIZE__ (which is also defined by + * clang and armcc5 under the same conditions). + * + * So, only use the optimized assembly below for optimized build, which avoids + * the build error and is pretty reasonable anyway. + */ +#if defined(__GNUC__) && !defined(__OPTIMIZE__) +#define MULADDC_CANNOT_USE_R7 +#endif + +#if defined(__arm__) && !defined(MULADDC_CANNOT_USE_R7) #if defined(__thumb__) && !defined(__thumb2__) diff --git a/app/include/mbedtls/certs.h b/app/include/mbedtls/certs.h index 6b7e40bc..ca49086e 100644 --- a/app/include/mbedtls/certs.h +++ b/app/include/mbedtls/certs.h @@ -29,8 +29,6 @@ extern "C" { #endif -#if defined(MBEDTLS_SELF_TEST) - #if defined(MBEDTLS_PEM_PARSE_C) /* Concatenation of all CA certificates in PEM format if available */ extern const char mbedtls_test_cas_pem[]; @@ -94,8 +92,6 @@ extern const char mbedtls_test_cli_key_rsa[]; extern const size_t mbedtls_test_cli_key_rsa_len; #endif -#endif - #ifdef __cplusplus } #endif diff --git a/app/include/mbedtls/check_config.h b/app/include/mbedtls/check_config.h index b6448ece..fa72454e 100644 --- a/app/include/mbedtls/check_config.h +++ b/app/include/mbedtls/check_config.h @@ -3,7 +3,7 @@ * * \brief Consistency checks for configuration options * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -77,6 +77,11 @@ #error "MBEDTLS_DHM_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_CMAC_C) && \ + !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_DES_C) +#error "MBEDTLS_CMAC_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 @@ -130,11 +135,53 @@ #error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" #endif +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( !defined(MBEDTLS_ENTROPY_C) || !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but not all prerequisites" +#endif +#if defined(MBEDTLS_TEST_NULL_ENTROPY) && \ + ( defined(MBEDTLS_ENTROPY_NV_SEED) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT) || \ + defined(MBEDTLS_HAVEGE_C) ) +#error "MBEDTLS_TEST_NULL_ENTROPY defined, but entropy sources too" +#endif + #if defined(MBEDTLS_GCM_C) && ( \ !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) #error "MBEDTLS_GCM_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_ADD_MIXED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_DOUBLE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_JAC_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) && !defined(MBEDTLS_ECP_INTERNAL_ALT) +#error "MBEDTLS_ECP_NORMALIZE_MXZ_ALT defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_HAVEGE_C) && !defined(MBEDTLS_TIMING_C) #error "MBEDTLS_HAVEGE_C defined, but not all prerequisites" #endif @@ -246,6 +293,36 @@ #error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" #endif +#if defined(MBEDTLS_PLATFORM_TIME_ALT) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( !defined(MBEDTLS_PLATFORM_C) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_TIME) ||\ + defined(MBEDTLS_PLATFORM_TIME_ALT) ) +#error "MBEDTLS_PLATFORM_TIME_TYPE_MACRO and MBEDTLS_PLATFORM_STD_TIME/MBEDTLS_PLATFORM_TIME_ALT cannot be defined simultaneously" +#endif + #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C) #error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" #endif @@ -342,6 +419,12 @@ #error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" #endif +#if defined(MBEDTLS_PLATFORM_STD_TIME) &&\ + ( !defined(MBEDTLS_PLATFORM_TIME_ALT) ||\ + !defined(MBEDTLS_HAVE_TIME) ) +#error "MBEDTLS_PLATFORM_STD_TIME defined, but not all prerequisites" +#endif + #if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\ !defined(MBEDTLS_PLATFORM_FPRINTF_ALT) #error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" @@ -357,11 +440,48 @@ #error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) &&\ + ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_ENTROPY_C) ) +#error "MBEDTLS_ENTROPY_NV_SEED defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) &&\ + !defined(MBEDTLS_ENTROPY_NV_SEED) +#error "MBEDTLS_PLATFORM_NV_SEED_ALT defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_READ defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) &&\ + !defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#error "MBEDTLS_PLATFORM_STD_NV_SEED_WRITE defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_READ_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_READ cannot be defined simultaneously" +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) &&\ + ( defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) ||\ + defined(MBEDTLS_PLATFORM_NV_SEED_ALT) ) +#error "MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO and MBEDTLS_PLATFORM_STD_NV_SEED_WRITE cannot be defined simultaneously" +#endif + #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \ !defined(MBEDTLS_OID_C) ) #error "MBEDTLS_RSA_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_PKCS1_V21) && \ + !defined(MBEDTLS_PKCS1_V15) ) +#error "MBEDTLS_RSA_C defined, but none of the PKCS1 versions enabled" +#endif + #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \ ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) #error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" @@ -530,6 +650,15 @@ #error "MBEDTLS_X509_CSR_WRITE_C defined, but not all prerequisites" #endif +#if defined(MBEDTLS_HAVE_INT32) && defined(MBEDTLS_HAVE_INT64) +#error "MBEDTLS_HAVE_INT32 and MBEDTLS_HAVE_INT64 cannot be defined simultaneously" +#endif /* MBEDTLS_HAVE_INT32 && MBEDTLS_HAVE_INT64 */ + +#if ( defined(MBEDTLS_HAVE_INT32) || defined(MBEDTLS_HAVE_INT64) ) && \ + defined(MBEDTLS_HAVE_ASM) +#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously" +#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */ + /* * Avoid warning from -pedantic. This is a convenient place for this * workaround since this is included by every single file before the diff --git a/app/include/mbedtls/cipher.h b/app/include/mbedtls/cipher.h index 70000f5e..b12e3884 100644 --- a/app/include/mbedtls/cipher.h +++ b/app/include/mbedtls/cipher.h @@ -57,6 +57,7 @@ #define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ #define MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ #define MBEDTLS_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ +#define MBEDTLS_ERR_CIPHER_INVALID_CONTEXT -0x6380 /**< The context is invalid, eg because it was free()ed. */ #define MBEDTLS_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ #define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ @@ -175,6 +176,11 @@ enum { */ typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; +/** + * CMAC context (opaque struct). + */ +typedef struct mbedtls_cmac_context_t mbedtls_cmac_context_t; + /** * Cipher information. Allows cipher functions to be called in a generic way. */ @@ -240,6 +246,11 @@ typedef struct { /** Cipher-specific context */ void *cipher_ctx; + +#if defined(MBEDTLS_CMAC_C) + /** CMAC Specific context */ + mbedtls_cmac_context_t *cmac_ctx; +#endif } mbedtls_cipher_context_t; /** diff --git a/app/include/mbedtls/cmac.h b/app/include/mbedtls/cmac.h new file mode 100644 index 00000000..9a2b96bc --- /dev/null +++ b/app/include/mbedtls/cmac.h @@ -0,0 +1,170 @@ +/** + * \file cmac.h + * + * \brief Cipher-based Message Authentication Code (CMAC) Mode for + * Authentication + * + * Copyright (C) 2015-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_CMAC_H +#define MBEDTLS_CMAC_H + +#include "mbedtls/cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MBEDTLS_AES_BLOCK_SIZE 16 +#define MBEDTLS_DES3_BLOCK_SIZE 8 + +#if defined(MBEDTLS_AES_C) +#define MBEDTLS_CIPHER_BLKSIZE_MAX 16 /* longest used by CMAC is AES */ +#else +#define MBEDTLS_CIPHER_BLKSIZE_MAX 8 /* longest used by CMAC is 3DES */ +#endif + +/** + * CMAC context structure - Contains internal state information only + */ +struct mbedtls_cmac_context_t +{ + /** Internal state of the CMAC algorithm */ + unsigned char state[MBEDTLS_CIPHER_BLKSIZE_MAX]; + + /** Unprocessed data - either data that was not block aligned and is still + * pending to be processed, or the final block */ + unsigned char unprocessed_block[MBEDTLS_CIPHER_BLKSIZE_MAX]; + + /** Length of data pending to be processed */ + size_t unprocessed_len; +}; + +/** + * \brief Set the CMAC key and prepare to authenticate the input + * data. + * Should be called with an initialized cipher context. + * + * \param ctx Cipher context. This should be a cipher context, + * initialized to be one of the following types: + * MBEDTLS_CIPHER_AES_128_ECB, MBEDTLS_CIPHER_AES_192_ECB, + * MBEDTLS_CIPHER_AES_256_ECB or + * MBEDTLS_CIPHER_DES_EDE3_ECB. + * \param key CMAC key + * \param keybits length of the CMAC key in bits + * (must be acceptable by the cipher) + * + * \return 0 if successful, or a cipher specific error code + */ +int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, + const unsigned char *key, size_t keybits ); + +/** + * \brief Generic CMAC process buffer. + * Called between mbedtls_cipher_cmac_starts() or + * mbedtls_cipher_cmac_reset() and + * mbedtls_cipher_cmac_finish(). + * May be called repeatedly. + * + * \param ctx CMAC context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief Output CMAC. + * Called after mbedtls_cipher_cmac_update(). + * Usually followed by mbedtls_cipher_cmac_reset(), then + * mbedtls_cipher_cmac_starts(), or mbedtls_cipher_free(). + * + * \param ctx CMAC context + * \param output Generic CMAC checksum result + * + * \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output ); + +/** + * \brief Prepare to authenticate a new message with the same key. + * Called after mbedtls_cipher_cmac_finish() and before + * mbedtls_cipher_cmac_update(). + * + * \param ctx CMAC context to be reset + * + * \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ); + +/** + * \brief Output = Generic_CMAC( cmac key, input buffer ) + * + * \param cipher_info message digest info + * \param key CMAC key + * \param keylen length of the CMAC key in bits + * \param input buffer holding the data + * \param ilen length of the input data + * \param output Generic CMAC-result + * + * \returns 0 on success, MBEDTLS_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, + const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ); + +#if defined(MBEDTLS_AES_C) +/** + * \brief AES-CMAC-128-PRF + * Implementation of (AES-CMAC-PRF-128), as defined in RFC 4615 + * + * \param key PRF key + * \param key_len PRF key length in bytes + * \param input buffer holding the input data + * \param in_len length of the input data in bytes + * \param output buffer holding the generated pseudorandom output (16 bytes) + * + * \return 0 if successful + */ +int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_len, + const unsigned char *input, size_t in_len, + unsigned char output[16] ); +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_SELF_TEST) && ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) ) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_cmac_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST && ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ + +#ifdef __cplusplus +} +#endif + +#endif /* MBEDTLS_CMAC_H */ diff --git a/app/include/mbedtls/compat-1.3.h b/app/include/mbedtls/compat-1.3.h index 27abbd97..bba1d2c2 100644 --- a/app/include/mbedtls/compat-1.3.h +++ b/app/include/mbedtls/compat-1.3.h @@ -207,9 +207,6 @@ #if defined MBEDTLS_ERROR_C #define POLARSSL_ERROR_C MBEDTLS_ERROR_C #endif -#if defined MBEDTLS_ERROR_STRERROR_BC -#define POLARSSL_ERROR_STRERROR_BC MBEDTLS_ERROR_STRERROR_BC -#endif #if defined MBEDTLS_ERROR_STRERROR_DUMMY #define POLARSSL_ERROR_STRERROR_DUMMY MBEDTLS_ERROR_STRERROR_DUMMY #endif @@ -318,9 +315,6 @@ #if defined MBEDTLS_MEMORY_BUFFER_ALLOC_C #define POLARSSL_MEMORY_BUFFER_ALLOC_C MBEDTLS_MEMORY_BUFFER_ALLOC_C #endif -#if defined MBEDTLS_MEMORY_C -#define POLARSSL_MEMORY_C MBEDTLS_MEMORY_C -#endif #if defined MBEDTLS_MEMORY_DEBUG #define POLARSSL_MEMORY_DEBUG MBEDTLS_MEMORY_DEBUG #endif @@ -345,9 +339,6 @@ #if defined MBEDTLS_PADLOCK_C #define POLARSSL_PADLOCK_C MBEDTLS_PADLOCK_C #endif -#if defined MBEDTLS_PBKDF2_C -#define POLARSSL_PBKDF2_C MBEDTLS_PBKDF2_C -#endif #if defined MBEDTLS_PEM_PARSE_C #define POLARSSL_PEM_PARSE_C MBEDTLS_PEM_PARSE_C #endif @@ -429,9 +420,6 @@ #if defined MBEDTLS_PLATFORM_STD_FREE #define POLARSSL_PLATFORM_STD_FREE MBEDTLS_PLATFORM_STD_FREE #endif -#if defined MBEDTLS_PLATFORM_STD_MALLOC -#define POLARSSL_PLATFORM_STD_MALLOC MBEDTLS_PLATFORM_STD_MALLOC -#endif #if defined MBEDTLS_PLATFORM_STD_MEM_HDR #define POLARSSL_PLATFORM_STD_MEM_HDR MBEDTLS_PLATFORM_STD_MEM_HDR #endif @@ -492,12 +480,6 @@ #if defined MBEDTLS_SHA512_PROCESS_ALT #define POLARSSL_SHA512_PROCESS_ALT MBEDTLS_SHA512_PROCESS_ALT #endif -#if defined MBEDTLS_SSL_AEAD_RANDOM_IV -#define POLARSSL_SSL_AEAD_RANDOM_IV MBEDTLS_SSL_AEAD_RANDOM_IV -#endif -#if defined MBEDTLS_SSL_ALERT_MESSAGES -#define POLARSSL_SSL_ALERT_MESSAGES MBEDTLS_SSL_ALERT_MESSAGES -#endif #if defined MBEDTLS_SSL_ALL_ALERT_MESSAGES #define POLARSSL_SSL_ALL_ALERT_MESSAGES MBEDTLS_SSL_ALL_ALERT_MESSAGES #endif @@ -522,9 +504,6 @@ #if defined MBEDTLS_SSL_DEBUG_ALL #define POLARSSL_SSL_DEBUG_ALL MBEDTLS_SSL_DEBUG_ALL #endif -#if defined MBEDTLS_SSL_DISABLE_RENEGOTIATION -#define POLARSSL_SSL_DISABLE_RENEGOTIATION MBEDTLS_SSL_DISABLE_RENEGOTIATION -#endif #if defined MBEDTLS_SSL_DTLS_ANTI_REPLAY #define POLARSSL_SSL_DTLS_ANTI_REPLAY MBEDTLS_SSL_DTLS_ANTI_REPLAY #endif @@ -752,7 +731,6 @@ #define KU_KEY_ENCIPHERMENT MBEDTLS_X509_KU_KEY_ENCIPHERMENT #define KU_NON_REPUDIATION MBEDTLS_X509_KU_NON_REPUDIATION #define LN_2_DIV_LN_10_SCALE100 MBEDTLS_LN_2_DIV_LN_10_SCALE100 -#define MD_CONTEXT_T_INIT MBEDTLS_MD_CONTEXT_T_INIT #define MEMORY_VERIFY_ALLOC MBEDTLS_MEMORY_VERIFY_ALLOC #define MEMORY_VERIFY_ALWAYS MBEDTLS_MEMORY_VERIFY_ALWAYS #define MEMORY_VERIFY_FREE MBEDTLS_MEMORY_VERIFY_FREE @@ -1017,19 +995,13 @@ #define POLARSSL_CONFIG_H MBEDTLS_CONFIG_H #define POLARSSL_CTR_DRBG_H MBEDTLS_CTR_DRBG_H #define POLARSSL_DEBUG_H MBEDTLS_DEBUG_H -#define POLARSSL_DEBUG_LOG_FULL MBEDTLS_DEBUG_LOG_FULL -#define POLARSSL_DEBUG_LOG_RAW MBEDTLS_DEBUG_LOG_RAW #define POLARSSL_DECRYPT MBEDTLS_DECRYPT #define POLARSSL_DES_H MBEDTLS_DES_H #define POLARSSL_DHM_H MBEDTLS_DHM_H -#define POLARSSL_DHM_RFC2409_MODP_1024_G MBEDTLS_DHM_RFC2409_MODP_1024_G -#define POLARSSL_DHM_RFC2409_MODP_1024_P MBEDTLS_DHM_RFC2409_MODP_1024_P #define POLARSSL_DHM_RFC3526_MODP_2048_G MBEDTLS_DHM_RFC3526_MODP_2048_G #define POLARSSL_DHM_RFC3526_MODP_2048_P MBEDTLS_DHM_RFC3526_MODP_2048_P #define POLARSSL_DHM_RFC3526_MODP_3072_G MBEDTLS_DHM_RFC3526_MODP_3072_G #define POLARSSL_DHM_RFC3526_MODP_3072_P MBEDTLS_DHM_RFC3526_MODP_3072_P -#define POLARSSL_DHM_RFC5114_MODP_1024_G MBEDTLS_DHM_RFC5114_MODP_1024_G -#define POLARSSL_DHM_RFC5114_MODP_1024_P MBEDTLS_DHM_RFC5114_MODP_1024_P #define POLARSSL_DHM_RFC5114_MODP_2048_G MBEDTLS_DHM_RFC5114_MODP_2048_G #define POLARSSL_DHM_RFC5114_MODP_2048_P MBEDTLS_DHM_RFC5114_MODP_2048_P #define POLARSSL_ECDH_H MBEDTLS_ECDH_H @@ -1117,9 +1089,6 @@ #define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR #define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG #define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG -#define POLARSSL_ERR_MD2_FILE_IO_ERROR MBEDTLS_ERR_MD2_FILE_IO_ERROR -#define POLARSSL_ERR_MD4_FILE_IO_ERROR MBEDTLS_ERR_MD4_FILE_IO_ERROR -#define POLARSSL_ERR_MD5_FILE_IO_ERROR MBEDTLS_ERR_MD5_FILE_IO_ERROR #define POLARSSL_ERR_MD_ALLOC_FAILED MBEDTLS_ERR_MD_ALLOC_FAILED #define POLARSSL_ERR_MD_BAD_INPUT_DATA MBEDTLS_ERR_MD_BAD_INPUT_DATA #define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE @@ -1147,7 +1116,6 @@ #define POLARSSL_ERR_OID_BUF_TOO_SMALL MBEDTLS_ERR_OID_BUF_TOO_SMALL #define POLARSSL_ERR_OID_NOT_FOUND MBEDTLS_ERR_OID_NOT_FOUND #define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -#define POLARSSL_ERR_PBKDF2_BAD_INPUT_DATA MBEDTLS_ERR_PBKDF2_BAD_INPUT_DATA #define POLARSSL_ERR_PEM_BAD_INPUT_DATA MBEDTLS_ERR_PEM_BAD_INPUT_DATA #define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE #define POLARSSL_ERR_PEM_INVALID_DATA MBEDTLS_ERR_PEM_INVALID_DATA @@ -1179,7 +1147,6 @@ #define POLARSSL_ERR_PK_TYPE_MISMATCH MBEDTLS_ERR_PK_TYPE_MISMATCH #define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE #define POLARSSL_ERR_PK_UNKNOWN_PK_ALG MBEDTLS_ERR_PK_UNKNOWN_PK_ALG -#define POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR MBEDTLS_ERR_RIPEMD160_FILE_IO_ERROR #define POLARSSL_ERR_RSA_BAD_INPUT_DATA MBEDTLS_ERR_RSA_BAD_INPUT_DATA #define POLARSSL_ERR_RSA_INVALID_PADDING MBEDTLS_ERR_RSA_INVALID_PADDING #define POLARSSL_ERR_RSA_KEY_CHECK_FAILED MBEDTLS_ERR_RSA_KEY_CHECK_FAILED @@ -1189,9 +1156,6 @@ #define POLARSSL_ERR_RSA_PUBLIC_FAILED MBEDTLS_ERR_RSA_PUBLIC_FAILED #define POLARSSL_ERR_RSA_RNG_FAILED MBEDTLS_ERR_RSA_RNG_FAILED #define POLARSSL_ERR_RSA_VERIFY_FAILED MBEDTLS_ERR_RSA_VERIFY_FAILED -#define POLARSSL_ERR_SHA1_FILE_IO_ERROR MBEDTLS_ERR_SHA1_FILE_IO_ERROR -#define POLARSSL_ERR_SHA256_FILE_IO_ERROR MBEDTLS_ERR_SHA256_FILE_IO_ERROR -#define POLARSSL_ERR_SHA512_FILE_IO_ERROR MBEDTLS_ERR_SHA512_FILE_IO_ERROR #define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE #define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST #define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY @@ -1305,7 +1269,6 @@ #define POLARSSL_MD_SHA512 MBEDTLS_MD_SHA512 #define POLARSSL_MD_WRAP_H MBEDTLS_MD_WRAP_H #define POLARSSL_MEMORY_BUFFER_ALLOC_H MBEDTLS_MEMORY_BUFFER_ALLOC_H -#define POLARSSL_MEMORY_H MBEDTLS_MEMORY_H #define POLARSSL_MODE_CBC MBEDTLS_MODE_CBC #define POLARSSL_MODE_CCM MBEDTLS_MODE_CCM #define POLARSSL_MODE_CFB MBEDTLS_MODE_CFB @@ -1319,7 +1282,7 @@ #define POLARSSL_MPI_MAX_BITS_SCALE100 MBEDTLS_MPI_MAX_BITS_SCALE100 #define POLARSSL_MPI_MAX_LIMBS MBEDTLS_MPI_MAX_LIMBS #define POLARSSL_MPI_RW_BUFFER_SIZE MBEDTLS_MPI_RW_BUFFER_SIZE -#define POLARSSL_NET_H MBEDTLS_NET_H +#define POLARSSL_NET_H MBEDTLS_NET_SOCKETS_H #define POLARSSL_NET_LISTEN_BACKLOG MBEDTLS_NET_LISTEN_BACKLOG #define POLARSSL_OID_H MBEDTLS_OID_H #define POLARSSL_OPERATION_NONE MBEDTLS_OPERATION_NONE @@ -1329,7 +1292,6 @@ #define POLARSSL_PADDING_ZEROS MBEDTLS_PADDING_ZEROS #define POLARSSL_PADDING_ZEROS_AND_LEN MBEDTLS_PADDING_ZEROS_AND_LEN #define POLARSSL_PADLOCK_H MBEDTLS_PADLOCK_H -#define POLARSSL_PBKDF2_H MBEDTLS_PBKDF2_H #define POLARSSL_PEM_H MBEDTLS_PEM_H #define POLARSSL_PKCS11_H MBEDTLS_PKCS11_H #define POLARSSL_PKCS12_H MBEDTLS_PKCS12_H @@ -1712,7 +1674,6 @@ #define TLS_RSA_WITH_NULL_SHA256 MBEDTLS_TLS_RSA_WITH_NULL_SHA256 #define TLS_RSA_WITH_RC4_128_MD5 MBEDTLS_TLS_RSA_WITH_RC4_128_MD5 #define TLS_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_RSA_WITH_RC4_128_SHA -#define UL64 MBEDTLS_UL64 #define X509_CRT_VERSION_1 MBEDTLS_X509_CRT_VERSION_1 #define X509_CRT_VERSION_2 MBEDTLS_X509_CRT_VERSION_2 #define X509_CRT_VERSION_3 MBEDTLS_X509_CRT_VERSION_3 @@ -1736,7 +1697,6 @@ #define _ssl_key_cert mbedtls_ssl_key_cert #define _ssl_premaster_secret mbedtls_ssl_premaster_secret #define _ssl_session mbedtls_ssl_session -#define _ssl_ticket_keys mbedtls_ssl_ticket_keys #define _ssl_transform mbedtls_ssl_transform #define _x509_crl mbedtls_x509_crl #define _x509_crl_entry mbedtls_x509_crl_entry @@ -1836,7 +1796,6 @@ #define cipher_definitions mbedtls_cipher_definitions #define cipher_finish mbedtls_cipher_finish #define cipher_free mbedtls_cipher_free -#define cipher_free_ctx mbedtls_cipher_free_ctx #define cipher_get_block_size mbedtls_cipher_get_block_size #define cipher_get_cipher_mode mbedtls_cipher_get_cipher_mode #define cipher_get_iv_size mbedtls_cipher_get_iv_size @@ -1855,7 +1814,6 @@ #define cipher_mode_t mbedtls_cipher_mode_t #define cipher_padding_t mbedtls_cipher_padding_t #define cipher_reset mbedtls_cipher_reset -#define cipher_self_test mbedtls_cipher_self_test #define cipher_set_iv mbedtls_cipher_set_iv #define cipher_set_padding_mode mbedtls_cipher_set_padding_mode #define cipher_setkey mbedtls_cipher_setkey @@ -1866,7 +1824,6 @@ #define ctr_drbg_context mbedtls_ctr_drbg_context #define ctr_drbg_free mbedtls_ctr_drbg_free #define ctr_drbg_init mbedtls_ctr_drbg_init -#define ctr_drbg_init_entropy_len mbedtls_ctr_drbg_init_entropy_len #define ctr_drbg_random mbedtls_ctr_drbg_random #define ctr_drbg_random_with_add mbedtls_ctr_drbg_random_with_add #define ctr_drbg_reseed mbedtls_ctr_drbg_reseed @@ -1877,14 +1834,12 @@ #define ctr_drbg_update mbedtls_ctr_drbg_update #define ctr_drbg_update_seed_file mbedtls_ctr_drbg_update_seed_file #define ctr_drbg_write_seed_file mbedtls_ctr_drbg_write_seed_file -#define debug_fmt mbedtls_debug_fmt #define debug_print_buf mbedtls_debug_print_buf #define debug_print_crt mbedtls_debug_print_crt #define debug_print_ecp mbedtls_debug_print_ecp #define debug_print_mpi mbedtls_debug_print_mpi #define debug_print_msg mbedtls_debug_print_msg #define debug_print_ret mbedtls_debug_print_ret -#define debug_set_log_mode mbedtls_debug_set_log_mode #define debug_set_threshold mbedtls_debug_set_threshold #define des3_context mbedtls_des3_context #define des3_crypt_cbc mbedtls_des3_crypt_cbc @@ -1928,7 +1883,6 @@ #define ecdh_make_public mbedtls_ecdh_make_public #define ecdh_read_params mbedtls_ecdh_read_params #define ecdh_read_public mbedtls_ecdh_read_public -#define ecdh_self_test mbedtls_ecdh_self_test #define ecdh_side mbedtls_ecdh_side #define ecdsa_context mbedtls_ecdsa_context #define ecdsa_free mbedtls_ecdsa_free @@ -1937,7 +1891,6 @@ #define ecdsa_info mbedtls_ecdsa_info #define ecdsa_init mbedtls_ecdsa_init #define ecdsa_read_signature mbedtls_ecdsa_read_signature -#define ecdsa_self_test mbedtls_ecdsa_self_test #define ecdsa_sign mbedtls_ecdsa_sign #define ecdsa_sign_det mbedtls_ecdsa_sign_det #define ecdsa_verify mbedtls_ecdsa_verify @@ -1945,7 +1898,6 @@ #define ecdsa_write_signature_det mbedtls_ecdsa_write_signature_det #define eckey_info mbedtls_eckey_info #define eckeydh_info mbedtls_eckeydh_info -#define ecp_add mbedtls_ecp_add #define ecp_check_privkey mbedtls_ecp_check_privkey #define ecp_check_pub_priv mbedtls_ecp_check_pub_priv #define ecp_check_pubkey mbedtls_ecp_check_pubkey @@ -1962,7 +1914,6 @@ #define ecp_group_free mbedtls_ecp_group_free #define ecp_group_id mbedtls_ecp_group_id #define ecp_group_init mbedtls_ecp_group_init -#define ecp_group_read_string mbedtls_ecp_group_read_string #define ecp_grp_id_list mbedtls_ecp_grp_id_list #define ecp_is_zero mbedtls_ecp_is_zero #define ecp_keypair mbedtls_ecp_keypair @@ -1977,7 +1928,6 @@ #define ecp_point_write_binary mbedtls_ecp_point_write_binary #define ecp_self_test mbedtls_ecp_self_test #define ecp_set_zero mbedtls_ecp_set_zero -#define ecp_sub mbedtls_ecp_sub #define ecp_tls_read_group mbedtls_ecp_tls_read_group #define ecp_tls_read_point mbedtls_ecp_tls_read_point #define ecp_tls_write_group mbedtls_ecp_tls_write_group @@ -2015,7 +1965,6 @@ #define hmac_drbg_context mbedtls_hmac_drbg_context #define hmac_drbg_free mbedtls_hmac_drbg_free #define hmac_drbg_init mbedtls_hmac_drbg_init -#define hmac_drbg_init_buf mbedtls_hmac_drbg_init_buf #define hmac_drbg_random mbedtls_hmac_drbg_random #define hmac_drbg_random_with_add mbedtls_hmac_drbg_random_with_add #define hmac_drbg_reseed mbedtls_hmac_drbg_reseed @@ -2031,14 +1980,8 @@ #define md mbedtls_md #define md2 mbedtls_md2 #define md2_context mbedtls_md2_context -#define md2_file mbedtls_md2_file #define md2_finish mbedtls_md2_finish #define md2_free mbedtls_md2_free -#define md2_hmac mbedtls_md2_hmac -#define md2_hmac_finish mbedtls_md2_hmac_finish -#define md2_hmac_reset mbedtls_md2_hmac_reset -#define md2_hmac_starts mbedtls_md2_hmac_starts -#define md2_hmac_update mbedtls_md2_hmac_update #define md2_info mbedtls_md2_info #define md2_init mbedtls_md2_init #define md2_process mbedtls_md2_process @@ -2047,14 +1990,8 @@ #define md2_update mbedtls_md2_update #define md4 mbedtls_md4 #define md4_context mbedtls_md4_context -#define md4_file mbedtls_md4_file #define md4_finish mbedtls_md4_finish #define md4_free mbedtls_md4_free -#define md4_hmac mbedtls_md4_hmac -#define md4_hmac_finish mbedtls_md4_hmac_finish -#define md4_hmac_reset mbedtls_md4_hmac_reset -#define md4_hmac_starts mbedtls_md4_hmac_starts -#define md4_hmac_update mbedtls_md4_hmac_update #define md4_info mbedtls_md4_info #define md4_init mbedtls_md4_init #define md4_process mbedtls_md4_process @@ -2063,14 +2000,8 @@ #define md4_update mbedtls_md4_update #define md5 mbedtls_md5 #define md5_context mbedtls_md5_context -#define md5_file mbedtls_md5_file #define md5_finish mbedtls_md5_finish #define md5_free mbedtls_md5_free -#define md5_hmac mbedtls_md5_hmac -#define md5_hmac_finish mbedtls_md5_hmac_finish -#define md5_hmac_reset mbedtls_md5_hmac_reset -#define md5_hmac_starts mbedtls_md5_hmac_starts -#define md5_hmac_update mbedtls_md5_hmac_update #define md5_info mbedtls_md5_info #define md5_init mbedtls_md5_init #define md5_process mbedtls_md5_process @@ -2081,7 +2012,6 @@ #define md_file mbedtls_md_file #define md_finish mbedtls_md_finish #define md_free mbedtls_md_free -#define md_free_ctx mbedtls_md_free_ctx #define md_get_name mbedtls_md_get_name #define md_get_size mbedtls_md_get_size #define md_get_type mbedtls_md_get_type @@ -2109,7 +2039,6 @@ #define memory_buffer_alloc_status mbedtls_memory_buffer_alloc_status #define memory_buffer_alloc_verify mbedtls_memory_buffer_alloc_verify #define memory_buffer_set_verify mbedtls_memory_buffer_set_verify -#define memory_set_own mbedtls_memory_set_own #define mpi mbedtls_mpi #define mpi_add_abs mbedtls_mpi_add_abs #define mpi_add_int mbedtls_mpi_add_int @@ -2185,8 +2114,6 @@ #define padlock_supports mbedtls_padlock_has_support #define padlock_xcryptcbc mbedtls_padlock_xcryptcbc #define padlock_xcryptecb mbedtls_padlock_xcryptecb -#define pbkdf2_hmac mbedtls_pbkdf2_hmac -#define pbkdf2_self_test mbedtls_pbkdf2_self_test #define pem_context mbedtls_pem_context #define pem_free mbedtls_pem_free #define pem_init mbedtls_pem_init @@ -2246,13 +2173,11 @@ #define platform_entropy_poll mbedtls_platform_entropy_poll #define platform_set_exit mbedtls_platform_set_exit #define platform_set_fprintf mbedtls_platform_set_fprintf -#define platform_set_malloc_free mbedtls_platform_set_malloc_free #define platform_set_printf mbedtls_platform_set_printf #define platform_set_snprintf mbedtls_platform_set_snprintf #define polarssl_exit mbedtls_exit #define polarssl_fprintf mbedtls_fprintf #define polarssl_free mbedtls_free -#define polarssl_malloc mbedtls_malloc #define polarssl_mutex_free mbedtls_mutex_free #define polarssl_mutex_init mbedtls_mutex_init #define polarssl_mutex_lock mbedtls_mutex_lock @@ -2262,14 +2187,8 @@ #define polarssl_strerror mbedtls_strerror #define ripemd160 mbedtls_ripemd160 #define ripemd160_context mbedtls_ripemd160_context -#define ripemd160_file mbedtls_ripemd160_file #define ripemd160_finish mbedtls_ripemd160_finish #define ripemd160_free mbedtls_ripemd160_free -#define ripemd160_hmac mbedtls_ripemd160_hmac -#define ripemd160_hmac_finish mbedtls_ripemd160_hmac_finish -#define ripemd160_hmac_reset mbedtls_ripemd160_hmac_reset -#define ripemd160_hmac_starts mbedtls_ripemd160_hmac_starts -#define ripemd160_hmac_update mbedtls_ripemd160_hmac_update #define ripemd160_info mbedtls_ripemd160_info #define ripemd160_init mbedtls_ripemd160_init #define ripemd160_process mbedtls_ripemd160_process @@ -2283,12 +2202,10 @@ #define rsa_check_pubkey mbedtls_rsa_check_pubkey #define rsa_context mbedtls_rsa_context #define rsa_copy mbedtls_rsa_copy -#define rsa_decrypt_func mbedtls_rsa_decrypt_func #define rsa_free mbedtls_rsa_free #define rsa_gen_key mbedtls_rsa_gen_key #define rsa_info mbedtls_rsa_info #define rsa_init mbedtls_rsa_init -#define rsa_key_len_func mbedtls_rsa_key_len_func #define rsa_pkcs1_decrypt mbedtls_rsa_pkcs1_decrypt #define rsa_pkcs1_encrypt mbedtls_rsa_pkcs1_encrypt #define rsa_pkcs1_sign mbedtls_rsa_pkcs1_sign @@ -2306,19 +2223,12 @@ #define rsa_rsassa_pss_verify_ext mbedtls_rsa_rsassa_pss_verify_ext #define rsa_self_test mbedtls_rsa_self_test #define rsa_set_padding mbedtls_rsa_set_padding -#define rsa_sign_func mbedtls_rsa_sign_func #define safer_memcmp mbedtls_ssl_safer_memcmp #define set_alarm mbedtls_set_alarm #define sha1 mbedtls_sha1 #define sha1_context mbedtls_sha1_context -#define sha1_file mbedtls_sha1_file #define sha1_finish mbedtls_sha1_finish #define sha1_free mbedtls_sha1_free -#define sha1_hmac mbedtls_sha1_hmac -#define sha1_hmac_finish mbedtls_sha1_hmac_finish -#define sha1_hmac_reset mbedtls_sha1_hmac_reset -#define sha1_hmac_starts mbedtls_sha1_hmac_starts -#define sha1_hmac_update mbedtls_sha1_hmac_update #define sha1_info mbedtls_sha1_info #define sha1_init mbedtls_sha1_init #define sha1_process mbedtls_sha1_process @@ -2328,14 +2238,8 @@ #define sha224_info mbedtls_sha224_info #define sha256 mbedtls_sha256 #define sha256_context mbedtls_sha256_context -#define sha256_file mbedtls_sha256_file #define sha256_finish mbedtls_sha256_finish #define sha256_free mbedtls_sha256_free -#define sha256_hmac mbedtls_sha256_hmac -#define sha256_hmac_finish mbedtls_sha256_hmac_finish -#define sha256_hmac_reset mbedtls_sha256_hmac_reset -#define sha256_hmac_starts mbedtls_sha256_hmac_starts -#define sha256_hmac_update mbedtls_sha256_hmac_update #define sha256_info mbedtls_sha256_info #define sha256_init mbedtls_sha256_init #define sha256_process mbedtls_sha256_process @@ -2345,14 +2249,8 @@ #define sha384_info mbedtls_sha384_info #define sha512 mbedtls_sha512 #define sha512_context mbedtls_sha512_context -#define sha512_file mbedtls_sha512_file #define sha512_finish mbedtls_sha512_finish #define sha512_free mbedtls_sha512_free -#define sha512_hmac mbedtls_sha512_hmac -#define sha512_hmac_finish mbedtls_sha512_hmac_finish -#define sha512_hmac_reset mbedtls_sha512_hmac_reset -#define sha512_hmac_starts mbedtls_sha512_hmac_starts -#define sha512_hmac_update mbedtls_sha512_hmac_update #define sha512_info mbedtls_sha512_info #define sha512_init mbedtls_sha512_init #define sha512_process mbedtls_sha512_process @@ -2385,7 +2283,6 @@ #define ssl_cookie_setup mbedtls_ssl_cookie_setup #define ssl_cookie_write mbedtls_ssl_cookie_write #define ssl_cookie_write_t mbedtls_ssl_cookie_write_t -#define ssl_curve_is_acceptable mbedtls_ssl_curve_is_acceptable #define ssl_derive_keys mbedtls_ssl_derive_keys #define ssl_dtls_replay_check mbedtls_ssl_dtls_replay_check #define ssl_dtls_replay_update mbedtls_ssl_dtls_replay_update @@ -2453,7 +2350,6 @@ #define ssl_set_arc4_support mbedtls_ssl_conf_arc4_support #define ssl_set_authmode mbedtls_ssl_conf_authmode #define ssl_set_bio mbedtls_ssl_set_bio -#define ssl_set_bio mbedtls_ssl_set_bio_timeout #define ssl_set_ca_chain mbedtls_ssl_conf_ca_chain #define ssl_set_cbc_record_splitting mbedtls_ssl_conf_cbc_record_splitting #define ssl_set_ciphersuites mbedtls_ssl_conf_ciphersuites @@ -2476,8 +2372,6 @@ #define ssl_set_max_version mbedtls_ssl_conf_max_version #define ssl_set_min_version mbedtls_ssl_conf_min_version #define ssl_set_own_cert mbedtls_ssl_conf_own_cert -#define ssl_set_own_cert_alt mbedtls_ssl_set_own_cert_alt -#define ssl_set_own_cert_rsa mbedtls_ssl_set_own_cert_rsa #define ssl_set_psk mbedtls_ssl_conf_psk #define ssl_set_psk_cb mbedtls_ssl_conf_psk_cb #define ssl_set_renegotiation mbedtls_ssl_conf_renegotiation @@ -2486,7 +2380,6 @@ #define ssl_set_rng mbedtls_ssl_conf_rng #define ssl_set_session mbedtls_ssl_set_session #define ssl_set_session_cache mbedtls_ssl_conf_session_cache -#define ssl_set_session_ticket_lifetime mbedtls_ssl_conf_session_ticket_lifetime #define ssl_set_session_tickets mbedtls_ssl_conf_session_tickets #define ssl_set_sni mbedtls_ssl_conf_sni #define ssl_set_transport mbedtls_ssl_conf_transport @@ -2494,7 +2387,6 @@ #define ssl_set_verify mbedtls_ssl_conf_verify #define ssl_sig_from_pk mbedtls_ssl_sig_from_pk #define ssl_states mbedtls_ssl_states -#define ssl_ticket_keys mbedtls_ssl_ticket_keys #define ssl_transform mbedtls_ssl_transform #define ssl_transform_free mbedtls_ssl_transform_free #define ssl_write mbedtls_ssl_write @@ -2523,7 +2415,6 @@ #define test_cli_key mbedtls_test_cli_key #define test_cli_key_ec mbedtls_test_cli_key_ec #define test_cli_key_rsa mbedtls_test_cli_key_rsa -#define test_dhm_params mbedtls_test_dhm_params #define test_srv_crt mbedtls_test_srv_crt #define test_srv_crt_ec mbedtls_test_srv_crt_ec #define test_srv_crt_rsa mbedtls_test_srv_crt_rsa @@ -2578,8 +2469,6 @@ #define x509_get_time mbedtls_x509_get_time #define x509_key_size_helper mbedtls_x509_key_size_helper #define x509_name mbedtls_x509_name -#define x509_oid_get_description mbedtls_x509_oid_get_description -#define x509_oid_get_numeric_string mbedtls_x509_oid_get_numeric_string #define x509_self_test mbedtls_x509_self_test #define x509_sequence mbedtls_x509_sequence #define x509_serial_gets mbedtls_x509_serial_gets diff --git a/app/include/mbedtls/config.h b/app/include/mbedtls/config.h index d1db0d82..47c71964 100644 --- a/app/include/mbedtls/config.h +++ b/app/include/mbedtls/config.h @@ -55,6 +55,34 @@ */ #define MBEDTLS_HAVE_ASM +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +//#define MBEDTLS_NO_UDBL_DIVISION + /** * \def MBEDTLS_HAVE_SSE2 * @@ -71,6 +99,10 @@ * The time does not need to be correct, only time differences are used, * by contrast with MBEDTLS_HAVE_TIME_DATE * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * * Comment if your system does not support time functions */ #define MBEDTLS_HAVE_TIME @@ -148,13 +180,18 @@ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as * MBEDTLS_PLATFORM_XXX_MACRO! * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * * Uncomment a macro to enable alternate implementation of specific base * platform function */ //#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT //#define MBEDTLS_PLATFORM_FPRINTF_ALT //#define MBEDTLS_PLATFORM_PRINTF_ALT //#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT /** * \def MBEDTLS_DEPRECATED_WARNING @@ -210,16 +247,16 @@ * \def MBEDTLS_AES_ALT * * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto or hash module (e.g. - * platform specific assembly optimized implementations). Keep in mind that - * the function prototypes should remain the same. + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. * * This replaces the whole module. If you only want to replace one of the * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. * * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base function - * declarations and implementations. "aes_alt.h" will be included from + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from * "aes.h" to include the new function definitions. * * Uncomment a macro to enable alternate implementation of the corresponding @@ -238,6 +275,16 @@ //#define MBEDTLS_SHA1_ALT //#define MBEDTLS_SHA256_ALT //#define MBEDTLS_SHA512_ALT +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT /** * \def MBEDTLS_MD2_PROCESS_ALT @@ -255,9 +302,15 @@ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible * with this definition. * - * Note: if you use the AES_xxx_ALT macros, then is is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. + * \note Because of a signature change, the core AES encryption and decryption routines are + * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, + * respectively. When setting up alternative implementations, these functions should + * be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * must stay untouched. + * + * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. * * Uncomment a macro to enable alternate implementation of the corresponding * function. @@ -277,6 +330,76 @@ //#define MBEDTLS_AES_ENCRYPT_ALT //#define MBEDTLS_AES_DECRYPT_ALT +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_deinit( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_deinit are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac + * function, but will use your mbedtls_internal_ecp_double_jac if the group is + * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when + * receives it as an argument). If the group is not supported then the original + * implementation is used. The other functions and the definition of + * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your + * implementation of mbedtls_internal_ecp_double_jac and + * mbedtls_internal_ecp_grp_capable must be compatible with this definition. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT * @@ -798,6 +921,34 @@ */ //#define MBEDTLS_ENTROPY_FORCE_SHA256 +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + /** * \def MBEDTLS_MEMORY_DEBUG * @@ -887,18 +1038,6 @@ */ //#define MBEDTLS_SHA256_SMALLER -/** - * \def MBEDTLS_SSL_AEAD_RANDOM_IV - * - * Generate a random IV rather than using the record sequence number as a - * nonce for ciphersuites using and AEAD algorithm (GCM or CCM). - * - * Using the sequence number is generally recommended. - * - * Uncomment this macro to always use random IVs with AEAD ciphersuites. - */ -//#define MBEDTLS_SSL_AEAD_RANDOM_IV - /** * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES * @@ -1058,7 +1197,7 @@ * * Comment this macro to disable support for SSL 3.0 */ -#define MBEDTLS_SSL_PROTO_SSL3 +//#define MBEDTLS_SSL_PROTO_SSL3 /** * \def MBEDTLS_SSL_PROTO_TLS1 @@ -1484,7 +1623,7 @@ * library/pkwrite.c * library/x509_create.c * library/x509write_crt.c - * library/mbedtls_x509write_csr.c + * library/x509write_csr.c */ #define MBEDTLS_ASN1_WRITE_C @@ -1618,6 +1757,19 @@ */ #define MBEDTLS_CIPHER_C +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +//#define MBEDTLS_CMAC_C + /** * \def MBEDTLS_CTR_DRBG_C * @@ -1832,7 +1984,7 @@ * * Enable the generic message digest layer. * - * Module: library/mbedtls_md.c + * Module: library/md.c * Caller: * * Uncomment to enable generic message digest wrappers. @@ -1844,7 +1996,7 @@ * * Enable the MD2 hash algorithm. * - * Module: library/mbedtls_md2.c + * Module: library/md2.c * Caller: * * Uncomment to enable support for (rare) MD2-signed X.509 certs. @@ -1856,7 +2008,7 @@ * * Enable the MD4 hash algorithm. * - * Module: library/mbedtls_md4.c + * Module: library/md4.c * Caller: * * Uncomment to enable support for (rare) MD4-signed X.509 certs. @@ -1868,8 +2020,8 @@ * * Enable the MD5 hash algorithm. * - * Module: library/mbedtls_md5.c - * Caller: library/mbedtls_md.c + * Module: library/md5.c + * Caller: library/md.c * library/pem.c * library/ssl_tls.c * @@ -1897,11 +2049,19 @@ /** * \def MBEDTLS_NET_C * - * Enable the TCP/IP networking routines. + * Enable the TCP and UDP over IPv6/IPv4 networking routines. * - * Module: library/net.c + * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) + * and Windows. For other platforms, you'll want to disable it, and write your + * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). * - * This module provides TCP/IP networking routines. + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/net_sockets.c + * + * This module provides networking routines. */ #define MBEDTLS_NET_C @@ -1918,11 +2078,11 @@ * library/rsa.c * library/x509.c * library/x509_create.c - * library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c * library/x509write_crt.c - * library/mbedtls_x509write_csr.c + * library/x509write_csr.c * * This modules translates between OIDs and internal values. */ @@ -1950,9 +2110,9 @@ * Module: library/pem.c * Caller: library/dhm.c * library/pkparse.c - * library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c * * Requires: MBEDTLS_BASE64_C * @@ -1968,7 +2128,7 @@ * Module: library/pem.c * Caller: library/pkwrite.c * library/x509write_crt.c - * library/mbedtls_x509write_csr.c + * library/x509write_csr.c * * Requires: MBEDTLS_BASE64_C * @@ -1998,8 +2158,8 @@ * Enable the generic public (asymetric) key parser. * * Module: library/pkparse.c - * Caller: library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c + * Caller: library/x509_crt.c + * library/x509_csr.c * * Requires: MBEDTLS_PK_C * @@ -2090,8 +2250,8 @@ * * Enable the RIPEMD-160 hash algorithm. * - * Module: library/mbedtls_ripemd160.c - * Caller: library/mbedtls_md.c + * Module: library/ripemd160.c + * Caller: library/md.c * */ #define MBEDTLS_RIPEMD160_C @@ -2119,14 +2279,15 @@ * * Enable the SHA1 cryptographic hash algorithm. * - * Module: library/mbedtls_sha1.c - * Caller: library/mbedtls_md.c + * Module: library/sha1.c + * Caller: library/md.c * library/ssl_cli.c * library/ssl_srv.c * library/ssl_tls.c * library/x509write_crt.c * - * This module is required for SSL/TLS and SHA1-signed certificates. + * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 + * depending on the handshake parameters, and for SHA1-signed certificates. */ #define MBEDTLS_SHA1_C @@ -2135,9 +2296,9 @@ * * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. * - * Module: library/mbedtls_sha256.c + * Module: library/sha256.c * Caller: library/entropy.c - * library/mbedtls_md.c + * library/md.c * library/ssl_cli.c * library/ssl_srv.c * library/ssl_tls.c @@ -2152,9 +2313,9 @@ * * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. * - * Module: library/mbedtls_sha512.c + * Module: library/sha512.c * Caller: library/entropy.c - * library/mbedtls_md.c + * library/md.c * library/ssl_cli.c * library/ssl_srv.c * @@ -2247,7 +2408,8 @@ * By default mbed TLS assumes it is used in a non-threaded environment or that * contexts are not shared between threads. If you do intend to use contexts * between threads, you will need to enable this layer to prevent race - * conditions. + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading * * Module: library/threading.c * @@ -2264,7 +2426,18 @@ /** * \def MBEDTLS_TIMING_C * - * Enable the portable timing interface. + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by + * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide + * your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS * * Module: library/timing.c * Caller: library/havege.c @@ -2290,9 +2463,9 @@ * Enable X.509 core for using certificates. * * Module: library/x509.c - * Caller: library/mbedtls_x509_crl.c - * library/mbedtls_x509_crt.c - * library/mbedtls_x509_csr.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c * * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, * MBEDTLS_PK_PARSE_C @@ -2306,7 +2479,7 @@ * * Enable X.509 certificate parsing. * - * Module: library/mbedtls_x509_crt.c + * Module: library/x509_crt.c * Caller: library/ssl_cli.c * library/ssl_srv.c * library/ssl_tls.c @@ -2322,8 +2495,8 @@ * * Enable X.509 CRL parsing. * - * Module: library/mbedtls_x509_crl.c - * Caller: library/mbedtls_x509_crt.c + * Module: library/x509_crl.c + * Caller: library/x509_crt.c * * Requires: MBEDTLS_X509_USE_C * @@ -2336,7 +2509,7 @@ * * Enable X.509 Certificate Signing Request (CSR) parsing. * - * Module: library/mbedtls_x509_csr.c + * Module: library/x509_csr.c * Caller: library/x509_crt_write.c * * Requires: MBEDTLS_X509_USE_C @@ -2436,6 +2609,7 @@ /* Entropy options */ //#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ //#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ /* Memory buffer allocator options */ //#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ @@ -2445,20 +2619,30 @@ //#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ /* Note: your snprintf must correclty zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ /* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ //#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ /* Note: your snprintf must correclty zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ /* SSL Cache options */ //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ @@ -2486,11 +2670,35 @@ /* X509 options */ //#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ -/* \} name SECTION: Module configuration options */ +/** + * Allow SHA-1 in the default TLS configuration for certificate signing. + * Without this build-time option, SHA-1 support must be activated explicitly + * through mbedtls_ssl_conf_cert_profile. Turning on this option is not + * recommended because of it is possible to generte SHA-1 collisions, however + * this may be safe for legacy infrastructure where additional controls apply. + */ +// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES -#if defined(TARGET_LIKE_MBED) -#include "mbedtls/target_config.h" +/** + * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake + * signature and ciphersuite selection. Without this build-time option, SHA-1 + * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes. + * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by + * default. At the time of writing, there is no practical attack on the use + * of SHA-1 in handshake signatures, hence this option is turned on by default + * for compatibility with existing peers. + */ +#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations */ +//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h" + +#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE) +#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE #endif /* diff --git a/app/include/mbedtls/debug.h b/app/include/mbedtls/debug.h index d859dd5f..29579964 100644 --- a/app/include/mbedtls/debug.h +++ b/app/include/mbedtls/debug.h @@ -1,7 +1,7 @@ /** * \file debug.h * - * \brief Debug functions + * \brief Functions for controlling and providing debug output from the library. * * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * SPDX-License-Identifier: Apache-2.0 @@ -80,39 +80,141 @@ extern "C" { #endif /** - * \brief Set the level threshold to handle globally. Messages that have a - * level over the threshold value are ignored. - * (Default value: 0 (No debug)) + * \brief Set the threshold error level to handle globally all debug output. + * Debug messages that have a level over the threshold value are + * discarded. + * (Default value: 0 = No debug ) * - * \param threshold maximum level of messages to pass on + * \param threshold theshold level of messages to filter on. Messages at a + * higher level will be discarded. + * - Debug levels + * - 0 No debug + * - 1 Error + * - 2 State change + * - 3 Informational + * - 4 Verbose */ void mbedtls_debug_set_threshold( int threshold ); +/** + * \brief Print a message to the debug output. This function is always used + * through the MBEDTLS_SSL_DEBUG_MSG() macro, which supplies the ssl + * context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the message has occurred in + * \param line line number the message has occurred at + * \param format format specifier, in printf format + * \param ... variables used by the format specifier + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, const char *file, int line, const char *format, ... ); +/** + * \brief Print the return value of a function to the debug output. This + * function is always used through the MBEDTLS_SSL_DEBUG_RET() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text the name of the function that returned the error + * \param ret the return code value + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, const char *file, int line, const char *text, int ret ); +/** + * \brief Output a buffer of size len bytes to the debug output. This function + * is always used through the MBEDTLS_SSL_DEBUG_BUF() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the buffer being dumped. Normally the + * variable or buffer name + * \param buf the buffer to be outputted + * \param len length of the buffer + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, const char *file, int line, const char *text, const unsigned char *buf, size_t len ); #if defined(MBEDTLS_BIGNUM_C) +/** + * \brief Print a MPI variable to the debug output. This function is always + * used through the MBEDTLS_SSL_DEBUG_MPI() macro, which supplies the + * ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the MPI being output. Normally the + * variable name + * \param X the MPI variable + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, const char *file, int line, const char *text, const mbedtls_mpi *X ); #endif #if defined(MBEDTLS_ECP_C) +/** + * \brief Print an ECP point to the debug output. This function is always + * used through the MBEDTLS_SSL_DEBUG_ECP() macro, which supplies the + * ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the ECP point being output. Normally the + * variable name + * \param X the ECP point + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, const char *file, int line, const char *text, const mbedtls_ecp_point *X ); #endif #if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Print a X.509 certificate structure to the debug output. This + * function is always used through the MBEDTLS_SSL_DEBUG_CRT() macro, + * which supplies the ssl context, file and line number parameters. + * + * \param ssl SSL context + * \param level error level of the debug message + * \param file file the error has occurred in + * \param line line number the error has occurred in + * \param text a name or label for the certificate being output + * \param crt X.509 certificate structure + * + * \attention This function is intended for INTERNAL usage within the + * library only. + */ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, const char *file, int line, const char *text, const mbedtls_x509_crt *crt ); @@ -123,3 +225,4 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, #endif #endif /* debug.h */ + diff --git a/app/include/mbedtls/dhm.h b/app/include/mbedtls/dhm.h index cd056d1b..d7ab1522 100644 --- a/app/include/mbedtls/dhm.h +++ b/app/include/mbedtls/dhm.h @@ -221,7 +221,7 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, * \param ctx DHM context * \param x_size private value size in bytes * \param output destination buffer - * \param olen must be equal to ctx->P.len + * \param olen must be at least equal to the size of P, ctx->len * \param f_rng RNG function * \param p_rng RNG parameter * diff --git a/app/include/mbedtls/ecdsa.h b/app/include/mbedtls/ecdsa.h index 52827d8d..a277715b 100644 --- a/app/include/mbedtls/ecdsa.h +++ b/app/include/mbedtls/ecdsa.h @@ -69,6 +69,10 @@ extern "C" { * \param f_rng RNG function * \param p_rng RNG parameter * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code */ @@ -89,6 +93,10 @@ int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, * \param blen Length of buf * \param md_alg MD algorithm used to hash the message * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code */ @@ -107,6 +115,10 @@ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi * \param r First integer of the signature * \param s Second integer of the signature * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.4 step 3. + * * \return 0 if successful, * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid * or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code @@ -120,7 +132,7 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * serialized as defined in RFC 4492 page 20. * (Not thread-safe to use same context in multiple threads) * - * \note The deterministice version (RFC 6979) is used if + * \note The deterministic version (RFC 6979) is used if * MBEDTLS_ECDSA_DETERMINISTIC is defined. * * \param ctx ECDSA context @@ -136,6 +148,10 @@ int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, * size of the curve used, plus 9 (eg. 73 bytes if a 256-bit * curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe. * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or * MBEDTLS_ERR_ASN1_XXX error code @@ -172,6 +188,10 @@ int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t * size of the curve used, plus 9 (eg. 73 bytes if a 256-bit * curve is used). MBEDTLS_ECDSA_MAX_LEN is always safe. * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.3 step 5. + * * \return 0 if successful, * or a MBEDTLS_ERR_ECP_XXX, MBEDTLS_ERR_MPI_XXX or * MBEDTLS_ERR_ASN1_XXX error code @@ -193,6 +213,10 @@ int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, * \param sig Signature to read and verify * \param slen Size of sig * + * \note If the bitlength of the message hash is larger than the + * bitlength of the group order, then the hash is truncated as + * prescribed by SEC1 4.1.4 step 3. + * * \return 0 if successful, * MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid, * MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH if the signature is diff --git a/app/include/mbedtls/ecjpake.h b/app/include/mbedtls/ecjpake.h index b7b61604..161a5b21 100644 --- a/app/include/mbedtls/ecjpake.h +++ b/app/include/mbedtls/ecjpake.h @@ -116,7 +116,7 @@ int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, const unsigned char *secret, size_t len ); -/* +/** * \brief Check if a context is ready for use * * \param ctx Context to check diff --git a/app/include/mbedtls/ecp.h b/app/include/mbedtls/ecp.h index 5246c789..dad9aef0 100644 --- a/app/include/mbedtls/ecp.h +++ b/app/include/mbedtls/ecp.h @@ -37,6 +37,15 @@ #define MBEDTLS_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ #define MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */ +#if !defined(MBEDTLS_ECP_ALT) +/* + * default mbed TLS elliptic curve arithmetic implementation + * + * (in case MBEDTLS_ECP_ALT is defined then the developer has to provide an + * alternative implementation for the whole module and it will replace this + * one.) + */ + #ifdef __cplusplus extern "C" { #endif @@ -452,7 +461,7 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp * \brief Set a group using well-known domain parameters * * \param grp Destination group - * \param index Index in the list of well-known domain parameters + * \param id Index in the list of well-known domain parameters * * \return 0 if successful, * MBEDTLS_ERR_MPI_XXX if initialization failed @@ -461,7 +470,7 @@ int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp * \note Index should be a value of RFC 4492's enum NamedCurve, * usually in the form of a MBEDTLS_ECP_DP_XXX macro. */ -int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id index ); +int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ); /** * \brief Set a group from a TLS ECParameters record @@ -654,16 +663,22 @@ int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ); #if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * * \return 0 if successful, or 1 if a test failed */ int mbedtls_ecp_self_test( int verbose ); -#endif + +#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } #endif +#else /* MBEDTLS_ECP_ALT */ +#include "ecp_alt.h" +#endif /* MBEDTLS_ECP_ALT */ + #endif /* ecp.h */ diff --git a/app/include/mbedtls/ecp_internal.h b/app/include/mbedtls/ecp_internal.h new file mode 100644 index 00000000..2991e26d --- /dev/null +++ b/app/include/mbedtls/ecp_internal.h @@ -0,0 +1,292 @@ +/** + * \file ecp_internal.h + * + * \brief Function declarations for alternative implementation of elliptic curve + * point arithmetic. + * + * Copyright (C) 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) + */ + +/* + * References: + * + * [1] BERNSTEIN, Daniel J. Curve25519: new Diffie-Hellman speed records. + * + * + * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis + * for elliptic curve cryptosystems. In : Cryptographic Hardware and + * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. + * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * + * + * [4] Certicom Research. SEC 2: Recommended Elliptic Curve Domain Parameters. + * + * + * [5] HANKERSON, Darrel, MENEZES, Alfred J., VANSTONE, Scott. Guide to Elliptic + * Curve Cryptography. + * + * [6] Digital Signature Standard (DSS), FIPS 186-4. + * + * + * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer + * Security (TLS), RFC 4492. + * + * + * [8] + * + * [9] COHEN, Henri. A Course in Computational Algebraic Number Theory. + * Springer Science & Business Media, 1 Aug 2000 + */ + +#ifndef MBEDTLS_ECP_INTERNAL_H +#define MBEDTLS_ECP_INTERNAL_H + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + +/** + * \brief Indicate if the Elliptic Curve Point module extension can + * handle the group. + * + * \param grp The pointer to the elliptic curve group that will be the + * basis of the cryptographic computations. + * + * \return Non-zero if successful. + */ +unsigned char mbedtls_internal_ecp_grp_capable( const mbedtls_ecp_group *grp ); + +/** + * \brief Initialise the Elliptic Curve Point module extension. + * + * If mbedtls_internal_ecp_grp_capable returns true for a + * group, this function has to be able to initialise the + * module for it. + * + * This module can be a driver to a crypto hardware + * accelerator, for which this could be an initialise function. + * + * \param grp The pointer to the group the module needs to be + * initialised for. + * + * \return 0 if successful. + */ +int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ); + +/** + * \brief Frees and deallocates the Elliptic Curve Point module + * extension. + * + * \param grp The pointer to the group the module was initialised for. + */ +void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ); + +#if defined(ECP_SHORTWEIERSTRASS) + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) +/** + * \brief Randomize jacobian coordinates: + * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l. + * + * \param grp Pointer to the group representing the curve. + * + * \param pt The point on the curve to be randomised, given with Jacobian + * coordinates. + * + * \param f_rng A function pointer to the random number generator. + * + * \param p_rng A pointer to the random number generator state. + * + * \return 0 if successful. + */ +int mbedtls_internal_ecp_randomize_jac( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt, int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) +/** + * \brief Addition: R = P + Q, mixed affine-Jacobian coordinates. + * + * The coordinates of Q must be normalized (= affine), + * but those of P don't need to. R is not normalized. + * + * This function is used only as a subrutine of + * ecp_mul_comb(). + * + * Special cases: (1) P or Q is zero, (2) R is zero, + * (3) P == Q. + * None of these cases can happen as intermediate step in + * ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base + * point, the factor being less than its order, so none of + * them is zero; + * - Q is an odd multiple of the base point, P an even + * multiple, due to the choice of precomputed points in the + * modified comb method. + * So branches for these cases do not leak secret information. + * + * We accept Q->Z being unset (saving memory in tables) as + * meaning 1. + * + * Cost in field operations if done by [5] 3.22: + * 1A := 8M + 3S + * + * \param grp Pointer to the group representing the curve. + * + * \param R Pointer to a point structure to hold the result. + * + * \param P Pointer to the first summand, given with Jacobian + * coordinates + * + * \param Q Pointer to the second summand, given with affine + * coordinates. + * + * \return 0 if successful. + */ +int mbedtls_internal_ecp_add_mixed( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q ); +#endif + +/** + * \brief Point doubling R = 2 P, Jacobian coordinates. + * + * Cost: 1D := 3M + 4S (A == 0) + * 4M + 4S (A == -3) + * 3M + 6S + 1a otherwise + * when the implementation is based on the "dbl-1998-cmo-2" + * doubling formulas in [8] and standard optimizations are + * applied when curve parameter A is one of { 0, -3 }. + * + * \param grp Pointer to the group representing the curve. + * + * \param R Pointer to a point structure to hold the result. + * + * \param P Pointer to the point that has to be doubled, given with + * Jacobian coordinates. + * + * \return 0 if successful. + */ +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) +int mbedtls_internal_ecp_double_jac( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, const mbedtls_ecp_point *P ); +#endif + +/** + * \brief Normalize jacobian coordinates of an array of (pointers to) + * points. + * + * Using Montgomery's trick to perform only one inversion mod P + * the cost is: + * 1N(t) := 1I + (6t - 3)M + 1S + * (See for example Algorithm 10.3.4. in [9]) + * + * This function is used only as a subrutine of + * ecp_mul_comb(). + * + * Warning: fails (returning an error) if one of the points is + * zero! + * This should never happen, see choice of w in ecp_mul_comb(). + * + * \param grp Pointer to the group representing the curve. + * + * \param T Array of pointers to the points to normalise. + * + * \param t_len Number of elements in the array. + * + * \return 0 if successful, + * an error if one of the points is zero. + */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) +int mbedtls_internal_ecp_normalize_jac_many( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *T[], size_t t_len ); +#endif + +/** + * \brief Normalize jacobian coordinates so that Z == 0 || Z == 1. + * + * Cost in field operations if done by [5] 3.2.1: + * 1N := 1I + 3M + 1S + * + * \param grp Pointer to the group representing the curve. + * + * \param pt pointer to the point to be normalised. This is an + * input/output parameter. + * + * \return 0 if successful. + */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) +int mbedtls_internal_ecp_normalize_jac( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *pt ); +#endif + +#endif /* ECP_SHORTWEIERSTRASS */ + +#if defined(ECP_MONTGOMERY) + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) +int mbedtls_internal_ecp_double_add_mxz( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, mbedtls_ecp_point *S, const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d ); +#endif + +/** + * \brief Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * + * \param grp pointer to the group representing the curve + * + * \param P the point on the curve to be randomised given with + * projective coordinates. This is an input/output parameter. + * + * \param f_rng a function pointer to the random number generator + * + * \param p_rng a pointer to the random number generator state + * + * \return 0 if successful + */ +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) +int mbedtls_internal_ecp_randomize_mxz( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +#endif + +/** + * \brief Normalize Montgomery x/z coordinates: X = X/Z, Z = 1. + * + * \param grp pointer to the group representing the curve + * + * \param P pointer to the point to be normalised. This is an + * input/output parameter. + * + * \return 0 if successful + */ +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) +int mbedtls_internal_ecp_normalize_mxz( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *P ); +#endif + +#endif /* ECP_MONTGOMERY */ + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + +#endif /* ecp_internal.h */ + diff --git a/app/include/mbedtls/entropy.h b/app/include/mbedtls/entropy.h index 00de9a6e..747aca4d 100644 --- a/app/include/mbedtls/entropy.h +++ b/app/include/mbedtls/entropy.h @@ -3,7 +3,7 @@ * * \brief Entropy accumulator implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -134,6 +134,9 @@ typedef struct #if defined(MBEDTLS_THREADING_C) mbedtls_threading_mutex_t mutex; /*!< mutex */ #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) + int initial_entropy_run; +#endif } mbedtls_entropy_context; @@ -208,6 +211,18 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ); int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, const unsigned char *data, size_t len ); +#if defined(MBEDTLS_ENTROPY_NV_SEED) +/** + * \brief Trigger an update of the seed file in NV by using the + * current entropy pool. + * + * \param ctx Entropy context + * + * \return 0 if successful + */ +int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ); +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + #if defined(MBEDTLS_FS_IO) /** * \brief Write a seed file @@ -240,9 +255,29 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char * /** * \brief Checkup routine * + * This module self-test also calls the entropy self-test, + * mbedtls_entropy_source_self_test(); + * * \return 0 if successful, or 1 if a test failed */ int mbedtls_entropy_self_test( int verbose ); + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) +/** + * \brief Checkup routine + * + * Verifies the integrity of the hardware entropy source + * provided by the function 'mbedtls_hardware_poll()'. + * + * Note this is the only hardware entropy source that is known + * at link time, and other entropy sources configured + * dynamically at runtime by the function + * mbedtls_entropy_add_source() will not be tested. + * + * \return 0 if successful, or 1 if a test failed + */ +int mbedtls_entropy_source_self_test( int verbose ); +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ #endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus diff --git a/app/include/mbedtls/entropy_poll.h b/app/include/mbedtls/entropy_poll.h index dc119113..81258d5f 100644 --- a/app/include/mbedtls/entropy_poll.h +++ b/app/include/mbedtls/entropy_poll.h @@ -3,7 +3,7 @@ * * \brief Platform-specific and custom entropy polling functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -41,7 +41,17 @@ extern "C" { #define MBEDTLS_ENTROPY_MIN_PLATFORM 32 /**< Minimum for platform source */ #define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */ #define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ +#if !defined(MBEDTLS_ENTROPY_MIN_HARDWARE) #define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Minimum for the hardware source */ +#endif + +/** + * \brief Entropy poll callback that provides 0 entropy. + */ +#if defined(MBEDTLS_TEST_NULL_ENTROPY) + int mbedtls_null_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) /** @@ -82,6 +92,16 @@ int mbedtls_hardware_poll( void *data, unsigned char *output, size_t len, size_t *olen ); #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) +/** + * \brief Entropy poll callback for a non-volatile seed file + * + * \note This must accept NULL as its first argument. + */ +int mbedtls_nv_seed_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + #ifdef __cplusplus } #endif diff --git a/app/include/mbedtls/error.h b/app/include/mbedtls/error.h index 5e549f6b..31591e2d 100644 --- a/app/include/mbedtls/error.h +++ b/app/include/mbedtls/error.h @@ -71,7 +71,7 @@ * Name ID Nr of Errors * PEM 1 9 * PKCS#12 1 4 (Started from top) - * X509 2 19 + * X509 2 20 * PKCS5 2 4 (Started from top) * DHM 3 9 * PK 3 14 (Started from top) diff --git a/app/include/mbedtls/gcm.h b/app/include/mbedtls/gcm.h index 6743ac9a..1b77aaed 100644 --- a/app/include/mbedtls/gcm.h +++ b/app/include/mbedtls/gcm.h @@ -190,8 +190,8 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx, * 16 bytes. * * \param ctx GCM context - * \param tag buffer for holding the tag (may be NULL if tag_len is 0) - * \param tag_len length of the tag to generate + * \param tag buffer for holding the tag + * \param tag_len length of the tag to generate (must be at least 4) * * \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT */ diff --git a/app/include/mbedtls/mbedtls_debug.h b/app/include/mbedtls/mbedtls_debug.h deleted file mode 100644 index 30b902ea..00000000 --- a/app/include/mbedtls/mbedtls_debug.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _MBEDTLS_DEBUG_H_ -#define _MBEDTLS_DEBUG_H_ - -#include "osapi.h" - -#define MBEDTLS_SSL_DEBUG_MSG( level, args ) os_printf args; -#define MBEDTLS_SSL_DEBUG_RET( level, ... ) os_printf (__VA_ARGS__); -#define MBEDTLS_SSL_DEBUG_BUF( level, ... ) os_printf (__VA_ARGS__); -#define MBEDTLS_SSL_DEBUG_MPI( level, text, X ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) -#define MBEDTLS_SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) - -#endif diff --git a/app/include/mbedtls/md.h b/app/include/mbedtls/md.h index 703e7811..9b996a95 100644 --- a/app/include/mbedtls/md.h +++ b/app/include/mbedtls/md.h @@ -182,7 +182,7 @@ int mbedtls_md_clone( mbedtls_md_context_t *dst, * * \return size of the message digest output in bytes. */ -int mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); +unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ); /** * \brief Returns the type of the message digest output. @@ -304,8 +304,8 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu /** * \brief Output HMAC. * Called after mbedtls_md_hmac_update(). - * Usually followed my mbedtls_md_hmac_reset(), mbedtls_md_hmac_starts(), - * or mbedtls_md_free(). + * Usually followed by mbedtls_md_hmac_reset(), + * mbedtls_md_hmac_starts(), or mbedtls_md_free(). * * \param ctx HMAC context * \param output Generic HMAC checksum result @@ -317,7 +317,8 @@ int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output); /** * \brief Prepare to authenticate a new message with the same key. - * Called after mbedtls_md_hmac_finish() and before mbedtls_md_hmac_update(). + * Called after mbedtls_md_hmac_finish() and before + * mbedtls_md_hmac_update(). * * \param ctx HMAC context to be reset * diff --git a/app/include/mbedtls/memory_buffer_alloc.h b/app/include/mbedtls/memory_buffer_alloc.h index 661bc08d..d5df316f 100644 --- a/app/include/mbedtls/memory_buffer_alloc.h +++ b/app/include/mbedtls/memory_buffer_alloc.h @@ -98,8 +98,10 @@ void mbedtls_memory_buffer_alloc_status( void ); /** * \brief Get the peak heap usage so far * - * \param max_used Peak number of bytes reauested by the application - * \param max_blocks Peak number of blocks reauested by the application + * \param max_used Peak number of bytes in use or committed. This + * includes bytes in allocated blocks too small to split + * into smaller blocks but larger than the requested size. + * \param max_blocks Peak number of blocks in use, including free and used */ void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ); @@ -111,8 +113,10 @@ void mbedtls_memory_buffer_alloc_max_reset( void ); /** * \brief Get the current heap usage * - * \param cur_used Number of bytes reauested by the application - * \param cur_blocks Number of blocks reauested by the application + * \param cur_used Current number of bytes in use or committed. This + * includes bytes in allocated blocks too small to split + * into smaller blocks but larger than the requested size. + * \param cur_blocks Current number of blocks in use, including free and used */ void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ); #endif /* MBEDTLS_MEMORY_DEBUG */ diff --git a/app/include/mbedtls/net.h b/app/include/mbedtls/net.h index 8c6534cf..774559b3 100644 --- a/app/include/mbedtls/net.h +++ b/app/include/mbedtls/net.h @@ -1,9 +1,9 @@ /** * \file net.h * - * \brief Network communication functions + * \brief Deprecated header file that includes mbedtls/net_sockets.h * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -19,207 +19,13 @@ * limitations under the License. * * This file is part of mbed TLS (https://tls.mbed.org) + * + * \deprecated Superseded by mbedtls/net_sockets.h */ -#ifndef MBEDTLS_NET_H -#define MBEDTLS_NET_H -#if !defined(MBEDTLS_CONFIG_FILE) -#include "config.h" -#else -#include MBEDTLS_CONFIG_FILE -#endif - -#include "ssl.h" - -#include -#include - -#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ -#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ -#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ -#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ -#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ -#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ -#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ -#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ -#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ -#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ -#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ - -#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ - -#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ -#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Wrapper type for sockets. - * - * Currently backed by just a file descriptor, but might be more in the future - * (eg two file descriptors for combined IPv4 + IPv6 support, or additional - * structures for hand-made UDP demultiplexing). - */ -typedef struct -{ - int fd; /**< The underlying file descriptor */ -} -mbedtls_net_context; - -/** - * \brief Initialize a context - * Just makes the context ready to be used or freed safely. - * - * \param ctx Context to initialize - */ -void mbedtls_net_init( mbedtls_net_context *ctx ); - -/** - * \brief Initiate a connection with host:port in the given protocol - * - * \param ctx Socket to use - * \param host Host to connect to - * \param port Port to connect to - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_UNKNOWN_HOST, - * MBEDTLS_ERR_NET_CONNECT_FAILED - * - * \note Sets the socket in connected mode even with UDP. - */ -int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); - -/** - * \brief Create a receiving socket on bind_ip:port in the chosen - * protocol. If bind_ip == NULL, all interfaces are bound. - * - * \param ctx Socket to use - * \param bind_ip IP to bind to, can be NULL - * \param port Port number to use - * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP - * - * \return 0 if successful, or one of: - * MBEDTLS_ERR_NET_SOCKET_FAILED, - * MBEDTLS_ERR_NET_BIND_FAILED, - * MBEDTLS_ERR_NET_LISTEN_FAILED - * - * \note Regardless of the protocol, opens the sockets and binds it. - * In addition, make the socket listening if protocol is TCP. - */ -int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ); - -/** - * \brief Accept a connection from a remote client - * - * \param bind_ctx Relevant socket - * \param client_ctx Will contain the connected client socket - * \param client_ip Will contain the client IP address - * \param buf_size Size of the client_ip buffer - * \param ip_len Will receive the size of the client IP written - * - * \return 0 if successful, or - * MBEDTLS_ERR_NET_ACCEPT_FAILED, or - * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, - * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to - * non-blocking and accept() would block. - */ -int mbedtls_net_accept( mbedtls_net_context *bind_ctx, - mbedtls_net_context *client_ctx, - void *client_ip, size_t buf_size, size_t *ip_len ); - -/** - * \brief Set the socket blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_block( mbedtls_net_context *ctx ); - -/** - * \brief Set the socket non-blocking - * - * \param ctx Socket to set - * - * \return 0 if successful, or a non-zero error code - */ -int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ); - -/** - * \brief Portable usleep helper - * - * \param usec Amount of microseconds to sleep - * - * \note Real amount of time slept will not be less than - * select()'s timeout granularity (typically, 10ms). - */ -void mbedtls_net_usleep( unsigned long usec ); - -/** - * \brief Read at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * - * \return the number of bytes received, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. - */ -int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ); - -/** - * \brief Write at most 'len' characters. If no error occurs, - * the actual amount read is returned. - * - * \param ctx Socket - * \param buf The buffer to read from - * \param len The length of the buffer - * - * \return the number of bytes sent, - * or a non-zero error code; with a non-blocking socket, - * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. - */ -int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); - -/** - * \brief Read at most 'len' characters, blocking for at most - * 'timeout' seconds. If no error occurs, the actual amount - * read is returned. - * - * \param ctx Socket - * \param buf The buffer to write to - * \param len Maximum length of the buffer - * \param timeout Maximum number of milliseconds to wait for data - * 0 means no timeout (wait forever) - * - * \return the number of bytes received, - * or a non-zero error code: - * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, - * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. - * - * \note This function will block (until data becomes available or - * timeout is reached) even if the socket is set to - * non-blocking. Handling timeouts with non-blocking reads - * requires a different strategy. - */ -int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, - uint32_t timeout ); - -/** - * \brief Gracefully shutdown the connection and free associated data - * - * \param ctx The context to free - */ -void mbedtls_net_free( mbedtls_net_context *ctx ); - -#ifdef __cplusplus -} -#endif - -#endif /* net.h */ +#if !defined(MBEDTLS_DEPRECATED_REMOVED) +#include "mbedtls/net_sockets.h" +#if defined(MBEDTLS_DEPRECATED_WARNING) +#warning "Deprecated header file: Superseded by mbedtls/net_sockets.h" +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#endif /* !MBEDTLS_DEPRECATED_REMOVED */ diff --git a/app/include/mbedtls/net_sockets.h b/app/include/mbedtls/net_sockets.h new file mode 100644 index 00000000..de335526 --- /dev/null +++ b/app/include/mbedtls/net_sockets.h @@ -0,0 +1,225 @@ +/** + * \file net_sockets.h + * + * \brief Network communication functions + * + * Copyright (C) 2006-2015, 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_NET_SOCKETS_H +#define MBEDTLS_NET_SOCKETS_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "ssl.h" + +#include +#include + +#define MBEDTLS_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ +#define MBEDTLS_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ +#define MBEDTLS_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ +#define MBEDTLS_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ +#define MBEDTLS_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ +#define MBEDTLS_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ +#define MBEDTLS_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ +#define MBEDTLS_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ +#define MBEDTLS_ERR_NET_UNKNOWN_HOST -0x0052 /**< Failed to get an IP address for the given hostname. */ +#define MBEDTLS_ERR_NET_BUFFER_TOO_SMALL -0x0043 /**< Buffer is too small to hold the data. */ +#define MBEDTLS_ERR_NET_INVALID_CONTEXT -0x0045 /**< The context is invalid, eg because it was free()ed. */ + +#define MBEDTLS_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ + +#define MBEDTLS_NET_PROTO_TCP 0 /**< The TCP transport protocol */ +#define MBEDTLS_NET_PROTO_UDP 1 /**< The UDP transport protocol */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Wrapper type for sockets. + * + * Currently backed by just a file descriptor, but might be more in the future + * (eg two file descriptors for combined IPv4 + IPv6 support, or additional + * structures for hand-made UDP demultiplexing). + */ +typedef struct +{ + int fd; /**< The underlying file descriptor */ +} +mbedtls_net_context; + +/** + * \brief Initialize a context + * Just makes the context ready to be used or freed safely. + * + * \param ctx Context to initialize + */ +void mbedtls_net_init( mbedtls_net_context *ctx ); + +/** + * \brief Initiate a connection with host:port in the given protocol + * + * \param ctx Socket to use + * \param host Host to connect to + * \param port Port to connect to + * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP + * + * \return 0 if successful, or one of: + * MBEDTLS_ERR_NET_SOCKET_FAILED, + * MBEDTLS_ERR_NET_UNKNOWN_HOST, + * MBEDTLS_ERR_NET_CONNECT_FAILED + * + * \note Sets the socket in connected mode even with UDP. + */ +int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto ); + +/** + * \brief Create a receiving socket on bind_ip:port in the chosen + * protocol. If bind_ip == NULL, all interfaces are bound. + * + * \param ctx Socket to use + * \param bind_ip IP to bind to, can be NULL + * \param port Port number to use + * \param proto Protocol: MBEDTLS_NET_PROTO_TCP or MBEDTLS_NET_PROTO_UDP + * + * \return 0 if successful, or one of: + * MBEDTLS_ERR_NET_SOCKET_FAILED, + * MBEDTLS_ERR_NET_BIND_FAILED, + * MBEDTLS_ERR_NET_LISTEN_FAILED + * + * \note Regardless of the protocol, opens the sockets and binds it. + * In addition, make the socket listening if protocol is TCP. + */ +int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ); + +/** + * \brief Accept a connection from a remote client + * + * \param bind_ctx Relevant socket + * \param client_ctx Will contain the connected client socket + * \param client_ip Will contain the client IP address + * \param buf_size Size of the client_ip buffer + * \param ip_len Will receive the size of the client IP written + * + * \return 0 if successful, or + * MBEDTLS_ERR_NET_ACCEPT_FAILED, or + * MBEDTLS_ERR_NET_BUFFER_TOO_SMALL if buf_size is too small, + * MBEDTLS_ERR_SSL_WANT_READ if bind_fd was set to + * non-blocking and accept() would block. + */ +int mbedtls_net_accept( mbedtls_net_context *bind_ctx, + mbedtls_net_context *client_ctx, + void *client_ip, size_t buf_size, size_t *ip_len ); + +/** + * \brief Set the socket blocking + * + * \param ctx Socket to set + * + * \return 0 if successful, or a non-zero error code + */ +int mbedtls_net_set_block( mbedtls_net_context *ctx ); + +/** + * \brief Set the socket non-blocking + * + * \param ctx Socket to set + * + * \return 0 if successful, or a non-zero error code + */ +int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ); + +/** + * \brief Portable usleep helper + * + * \param usec Amount of microseconds to sleep + * + * \note Real amount of time slept will not be less than + * select()'s timeout granularity (typically, 10ms). + */ +void mbedtls_net_usleep( unsigned long usec ); + +/** + * \brief Read at most 'len' characters. If no error occurs, + * the actual amount read is returned. + * + * \param ctx Socket + * \param buf The buffer to write to + * \param len Maximum length of the buffer + * + * \return the number of bytes received, + * or a non-zero error code; with a non-blocking socket, + * MBEDTLS_ERR_SSL_WANT_READ indicates read() would block. + */ +int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ); + +/** + * \brief Write at most 'len' characters. If no error occurs, + * the actual amount read is returned. + * + * \param ctx Socket + * \param buf The buffer to read from + * \param len The length of the buffer + * + * \return the number of bytes sent, + * or a non-zero error code; with a non-blocking socket, + * MBEDTLS_ERR_SSL_WANT_WRITE indicates write() would block. + */ +int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ); + +/** + * \brief Read at most 'len' characters, blocking for at most + * 'timeout' seconds. If no error occurs, the actual amount + * read is returned. + * + * \param ctx Socket + * \param buf The buffer to write to + * \param len Maximum length of the buffer + * \param timeout Maximum number of milliseconds to wait for data + * 0 means no timeout (wait forever) + * + * \return the number of bytes received, + * or a non-zero error code: + * MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, + * MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. + * + * \note This function will block (until data becomes available or + * timeout is reached) even if the socket is set to + * non-blocking. Handling timeouts with non-blocking reads + * requires a different strategy. + */ +int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ); + +/** + * \brief Gracefully shutdown the connection and free associated data + * + * \param ctx The context to free + */ +void mbedtls_net_free( mbedtls_net_context *ctx ); + +#ifdef __cplusplus +} +#endif + +#endif /* net_sockets.h */ diff --git a/app/include/mbedtls/pk.h b/app/include/mbedtls/pk.h index 458bb512..f9f9b9bb 100644 --- a/app/include/mbedtls/pk.h +++ b/app/include/mbedtls/pk.h @@ -496,11 +496,12 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, * \brief Load and parse a public key * * \param ctx key to be initialized - * \param path filename to read the private key from + * \param path filename to read the public key from * * \note On entry, ctx must be empty, either freshly initialised - * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a - * specific key type, check the result with mbedtls_pk_can_do(). + * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If + * you need a specific key type, check the result with + * mbedtls_pk_can_do(). * * \note The key is also checked for correctness. * diff --git a/app/include/mbedtls/platform.h b/app/include/mbedtls/platform.h index fbbefc4d..549b9b4f 100644 --- a/app/include/mbedtls/platform.h +++ b/app/include/mbedtls/platform.h @@ -3,7 +3,7 @@ * * \brief mbed TLS Platform abstraction layer * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -29,6 +29,10 @@ #include MBEDTLS_CONFIG_FILE #endif +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -40,18 +44,16 @@ extern "C" { * Either change them in config.h or define them on the compiler command line. * \{ */ -extern int ets_snprintf(char *buf, unsigned int size, const char *format, ...); -extern void *pvPortCalloc(unsigned int count, unsigned int size); -extern void vPortFree( void *pv ); -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) #include #include +#include #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) #if defined(_WIN32) #define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ #else -#define MBEDTLS_PLATFORM_STD_SNPRINTF ets_snprintf /**< Default snprintf to use */ +#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use */ #endif #endif #if !defined(MBEDTLS_PLATFORM_STD_PRINTF) @@ -61,20 +63,41 @@ extern void vPortFree( void *pv ); #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ #endif #if !defined(MBEDTLS_PLATFORM_STD_CALLOC) -#define MBEDTLS_PLATFORM_STD_CALLOC pvPortCalloc /**< Default allocator to use */ +#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use */ #endif #if !defined(MBEDTLS_PLATFORM_STD_FREE) -#define MBEDTLS_PLATFORM_STD_FREE vPortFree /**< Default free to use */ +#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */ #endif #if !defined(MBEDTLS_PLATFORM_STD_EXIT) -#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default free to use */ +#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use */ #endif +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS EXIT_SUCCESS /**< Default exit value to use */ +#endif +#if !defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE EXIT_FAILURE /**< Default exit value to use */ +#endif +#if defined(MBEDTLS_FS_IO) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write +#endif +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_FILE) +#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" +#endif +#endif /* MBEDTLS_FS_IO */ #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) #include MBEDTLS_PLATFORM_STD_MEM_HDR #endif #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + /* \} name SECTION: Module settings */ /* @@ -103,8 +126,8 @@ int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), void (*free_func)( void * ) ); #endif /* MBEDTLS_PLATFORM_FREE_MACRO && MBEDTLS_PLATFORM_CALLOC_MACRO */ #else /* !MBEDTLS_PLATFORM_MEMORY */ -#define mbedtls_free vPortFree -#define mbedtls_calloc pvPortCalloc +#define mbedtls_free free +#define mbedtls_calloc calloc #endif /* MBEDTLS_PLATFORM_MEMORY && !MBEDTLS_PLATFORM_{FREE,CALLOC}_MACRO */ /* @@ -150,7 +173,7 @@ int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ); #if defined(MBEDTLS_PLATFORM_PRINTF_MACRO) #define mbedtls_printf MBEDTLS_PLATFORM_PRINTF_MACRO #else -#define mbedtls_printf os_printf +#define mbedtls_printf printf #endif /* MBEDTLS_PLATFORM_PRINTF_MACRO */ #endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ @@ -183,8 +206,10 @@ int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, #else /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ #if defined(MBEDTLS_PLATFORM_SNPRINTF_MACRO) #define mbedtls_snprintf MBEDTLS_PLATFORM_SNPRINTF_MACRO +#define mbedtls_vsnprintf MBEDTLS_PLATFORM_VSNPRINTF_MACRO #else -#define mbedtls_snprintf ets_snprintf +#define mbedtls_snprintf snprintf +#define mbedtls_vsnprintf vsnprintf #endif /* MBEDTLS_PLATFORM_SNPRINTF_MACRO */ #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ @@ -210,6 +235,109 @@ int mbedtls_platform_set_exit( void (*exit_func)( int status ) ); #endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ #endif /* MBEDTLS_PLATFORM_EXIT_ALT */ +/* + * The default exit values + */ +#if defined(MBEDTLS_PLATFORM_STD_EXIT_SUCCESS) +#define MBEDTLS_EXIT_SUCCESS MBEDTLS_PLATFORM_STD_EXIT_SUCCESS +#else +#define MBEDTLS_EXIT_SUCCESS 0 +#endif +#if defined(MBEDTLS_PLATFORM_STD_EXIT_FAILURE) +#define MBEDTLS_EXIT_FAILURE MBEDTLS_PLATFORM_STD_EXIT_FAILURE +#else +#define MBEDTLS_EXIT_FAILURE 1 +#endif + +/* + * The function pointers for reading from and writing a seed file to + * Non-Volatile storage (NV) in a platform-independent way + * + * Only enabled when the NV seed entropy source is enabled + */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Internal standard platform definitions */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ); +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ); +#endif + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +extern int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ); +extern int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ); + +/** + * \brief Set your own seed file writing/reading functions + * + * \param nv_seed_read_func the seed reading function implementation + * \param nv_seed_write_func the seed writing function implementation + * + * \return 0 + */ +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) + ); +#else +#if defined(MBEDTLS_PLATFORM_NV_SEED_READ_MACRO) && \ + defined(MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO) +#define mbedtls_nv_seed_read MBEDTLS_PLATFORM_NV_SEED_READ_MACRO +#define mbedtls_nv_seed_write MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO +#else +#define mbedtls_nv_seed_read mbedtls_platform_std_nv_seed_read +#define mbedtls_nv_seed_write mbedtls_platform_std_nv_seed_write +#endif +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) + +/** + * \brief Platform context structure + * + * \note This structure may be used to assist platform-specific + * setup/teardown operations. + */ +typedef struct { + char dummy; /**< Placeholder member as empty structs are not portable */ +} +mbedtls_platform_context; + +#else +#include "platform_alt.h" +#endif /* !MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + +/** + * \brief Perform any platform initialisation operations + * + * \param ctx mbed TLS context + * + * \return 0 if successful + * + * \note This function is intended to allow platform specific initialisation, + * and should be called before any other library functions. Its + * implementation is platform specific, and by default, unless platform + * specific code is provided, it does nothing. + * + * Its use and whether its necessary to be called is dependent on the + * platform. + */ +int mbedtls_platform_setup( mbedtls_platform_context *ctx ); +/** + * \brief Perform any platform teardown operations + * + * \param ctx mbed TLS context + * + * \note This function should be called after every other mbed TLS module has + * been correctly freed using the appropriate free function. + * Its implementation is platform specific, and by default, unless + * platform specific code is provided, it does nothing. + * + * Its use and whether its necessary to be called is dependent on the + * platform. + */ +void mbedtls_platform_teardown( mbedtls_platform_context *ctx ); + #ifdef __cplusplus } #endif diff --git a/app/include/mbedtls/platform_time.h b/app/include/mbedtls/platform_time.h new file mode 100644 index 00000000..abb34314 --- /dev/null +++ b/app/include/mbedtls/platform_time.h @@ -0,0 +1,81 @@ +/** + * \file platform_time.h + * + * \brief mbed TLS Platform time abstraction + * + * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_PLATFORM_TIME_H +#define MBEDTLS_PLATFORM_TIME_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +/* + * The time_t datatype + */ +#if defined(MBEDTLS_PLATFORM_TIME_TYPE_MACRO) +typedef MBEDTLS_PLATFORM_TIME_TYPE_MACRO mbedtls_time_t; +#else +/* For time_t */ +#include +typedef time_t mbedtls_time_t; +#endif /* MBEDTLS_PLATFORM_TIME_TYPE_MACRO */ + +/* + * The function pointers for time + */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +extern mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* time ); + +/** + * \brief Set your own time function pointer + * + * \param time_func the time function implementation + * + * \return 0 + */ +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* time ) ); +#else +#if defined(MBEDTLS_PLATFORM_TIME_MACRO) +#define mbedtls_time MBEDTLS_PLATFORM_TIME_MACRO +#else +#define mbedtls_time time +#endif /* MBEDTLS_PLATFORM_TIME_MACRO */ +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#ifdef __cplusplus +} +#endif + +#endif /* platform_time.h */ diff --git a/app/include/mbedtls/rsa.h b/app/include/mbedtls/rsa.h index 9c8645df..7d7469d5 100644 --- a/app/include/mbedtls/rsa.h +++ b/app/include/mbedtls/rsa.h @@ -99,7 +99,7 @@ typedef struct mbedtls_mpi Vf; /*!< cached un-blinding value */ int padding; /*!< MBEDTLS_RSA_PKCS_V15 for 1.5 padding and - RSA_PKCS_v21 for OAEP/PSS */ + MBEDTLS_RSA_PKCS_v21 for OAEP/PSS */ int hash_id; /*!< Hash identifier of mbedtls_md_type_t as specified in the mbedtls_md.h header file for the EME-OAEP and EMSA-PSS @@ -206,7 +206,7 @@ int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rs * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code * * \note This function does NOT take care of message - * padding. Also, be sure to set input[0] = 0 or assure that + * padding. Also, be sure to set input[0] = 0 or ensure that * input is smaller than N. * * \note The input and output buffers must be large @@ -329,9 +329,15 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, * * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code * - * \note The output buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise - * an error is thrown. + * \note The output buffer length \c output_max_len should be + * as large as the size ctx->len of ctx->N (eg. 128 bytes + * if RSA-1024 is used) to be able to hold an arbitrary + * decrypted message. If it is not large enough to hold + * the decryption of the particular ciphertext provided, + * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \note The input buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -355,9 +361,15 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, * * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code * - * \note The output buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise - * an error is thrown. + * \note The output buffer length \c output_max_len should be + * as large as the size ctx->len of ctx->N (eg. 128 bytes + * if RSA-1024 is used) to be able to hold an arbitrary + * decrypted message. If it is not large enough to hold + * the decryption of the particular ciphertext provided, + * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \note The input buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), @@ -383,9 +395,15 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, * * \return 0 if successful, or an MBEDTLS_ERR_RSA_XXX error code * - * \note The output buffer must be as large as the size - * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise - * an error is thrown. + * \note The output buffer length \c output_max_len should be + * as large as the size ctx->len of ctx->N (eg. 128 bytes + * if RSA-1024 is used) to be able to hold an arbitrary + * decrypted message. If it is not large enough to hold + * the decryption of the particular ciphertext provided, + * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. + * + * \note The input buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, int (*f_rng)(void *, unsigned char *, size_t), diff --git a/app/include/mbedtls/ssl.h b/app/include/mbedtls/ssl.h index ff5f3897..cc000700 100644 --- a/app/include/mbedtls/ssl.h +++ b/app/include/mbedtls/ssl.h @@ -52,7 +52,7 @@ #endif #if defined(MBEDTLS_HAVE_TIME) -#include +#include "mbedtls/platform_time.h" #endif /* @@ -107,6 +107,8 @@ #define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ #define MBEDTLS_ERR_SSL_CLIENT_RECONNECT -0x6780 /**< The client initiated a reconnect from the same port. */ #define MBEDTLS_ERR_SSL_UNEXPECTED_RECORD -0x6700 /**< Record header looks valid but is not expected. */ +#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 */ /* * Various constants @@ -183,6 +185,9 @@ #define MBEDTLS_SSL_PRESET_DEFAULT 0 #define MBEDTLS_SSL_PRESET_SUITEB 2 +#define MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED 1 +#define MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED 0 + /* * Default range for DTLS retransmission timer value, in milliseconds. * RFC 6347 4.2.4.1 says from 1 second to 60 seconds. @@ -232,7 +237,7 @@ * Signaling ciphersuite values (SCSV) */ #define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ -#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< draft-ietf-tls-downgrade-scsv-00 */ +#define MBEDTLS_SSL_FALLBACK_SCSV_VALUE 0x5600 /**< RFC 7507 section 2 */ /* * Supported Signature and Hash algorithms (For TLS 1.2) @@ -411,6 +416,116 @@ typedef enum } mbedtls_ssl_states; +/** + * \brief Callback type: send data on the network. + * + * \note That callback may be either blocking or non-blocking. + * + * \param ctx Context for the send callback (typically a file descriptor) + * \param buf Buffer holding the data to send + * \param len Length of the data to send + * + * \return The callback must return the number of bytes sent if any, + * or a non-zero error code. + * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_WRITE + * must be returned when the operation would block. + * + * \note The callback is allowed to send fewer bytes than requested. + * It must always return the number of bytes actually sent. + */ +typedef int mbedtls_ssl_send_t( void *ctx, + const unsigned char *buf, + size_t len ); + +/** + * \brief Callback type: receive data from the network. + * + * \note That callback may be either blocking or non-blocking. + * + * \param ctx Context for the receive callback (typically a file + * descriptor) + * \param buf Buffer to write the received data to + * \param len Length of the receive buffer + * + * \return The callback must return the number of bytes received, + * or a non-zero error code. + * If performing non-blocking I/O, \c MBEDTLS_ERR_SSL_WANT_READ + * must be returned when the operation would block. + * + * \note The callback may receive fewer bytes than the length of the + * buffer. It must always return the number of bytes actually + * received and written to the buffer. + */ +typedef int mbedtls_ssl_recv_t( void *ctx, + unsigned char *buf, + size_t len ); + +/** + * \brief Callback type: receive data from the network, with timeout + * + * \note That callback must block until data is received, or the + * timeout delay expires, or the operation is interrupted by a + * signal. + * + * \param ctx Context for the receive callback (typically a file descriptor) + * \param buf Buffer to write the received data to + * \param len Length of the receive buffer + * \param timeout Maximum nomber of millisecondes to wait for data + * 0 means no timeout (potentially waiting forever) + * + * \return The callback must return the number of bytes received, + * or a non-zero error code: + * \c MBEDTLS_ERR_SSL_TIMEOUT if the operation timed out, + * \c MBEDTLS_ERR_SSL_WANT_READ if interrupted by a signal. + * + * \note The callback may receive fewer bytes than the length of the + * buffer. It must always return the number of bytes actually + * received and written to the buffer. + */ +typedef int mbedtls_ssl_recv_timeout_t( void *ctx, + unsigned char *buf, + size_t len, + uint32_t timeout ); +/** + * \brief Callback type: set a pair of timers/delays to watch + * + * \param ctx Context pointer + * \param int_ms Intermediate delay in milliseconds + * \param fin_ms Final delay in milliseconds + * 0 cancels the current timer. + * + * \note This callback must at least store the necessary information + * for the associated \c mbedtls_ssl_get_timer_t callback to + * return correct information. + * + * \note If using a event-driven style of programming, an event must + * be generated when the final delay is passed. The event must + * cause a call to \c mbedtls_ssl_handshake() with the proper + * SSL context to be scheduled. Care must be taken to ensure + * that at most one such call happens at a time. + * + * \note Only one timer at a time must be running. Calling this + * function while a timer is running must cancel it. Cancelled + * timers must not generate any event. + */ +typedef void mbedtls_ssl_set_timer_t( void * ctx, + uint32_t int_ms, + uint32_t fin_ms ); + +/** + * \brief Callback type: get status of timers/delays + * + * \param ctx Context pointer + * + * \return This callback must return: + * -1 if cancelled (fin_ms == 0), + * 0 if none of the delays have passed, + * 1 if only the intermediate delay has passed, + * 2 if the final delay has passed. + */ +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; @@ -419,6 +534,7 @@ typedef struct mbedtls_ssl_config mbedtls_ssl_config; /* Defined in ssl_internal.h */ typedef struct mbedtls_ssl_transform mbedtls_ssl_transform; typedef struct mbedtls_ssl_handshake_params mbedtls_ssl_handshake_params; +typedef struct mbedtls_ssl_sig_hash_set_t mbedtls_ssl_sig_hash_set_t; #if defined(MBEDTLS_X509_CRT_PARSE_C) typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert; #endif @@ -432,7 +548,7 @@ typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item; struct mbedtls_ssl_session { #if defined(MBEDTLS_HAVE_TIME) - time_t start; /*!< starting time */ + mbedtls_time_t start; /*!< starting time */ #endif int ciphersuite; /*!< chosen ciphersuite */ int compression; /*!< chosen compression */ @@ -637,6 +753,10 @@ struct mbedtls_ssl_config #if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) unsigned int fallback : 1; /*!< is this a fallback? */ #endif +#if defined(MBEDTLS_SSL_SRV_C) + unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in + Certificate Request messages? */ +#endif }; @@ -662,12 +782,11 @@ struct mbedtls_ssl_context unsigned badmac_seen; /*!< records with a bad MAC received */ #endif - /* - * Callbacks - */ - int (*f_send)(void *, const unsigned char *, size_t); - int (*f_recv)(void *, unsigned char *, size_t); - int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t); + mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ + mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ + mbedtls_ssl_recv_timeout_t *f_recv_timeout; + /*!< Callback for network receive with timeout */ + void *p_bio; /*!< context for I/O operations */ /* @@ -693,8 +812,9 @@ struct mbedtls_ssl_context * Timers */ void *p_timer; /*!< context for the timer callbacks */ - void (*f_set_timer)(void *, uint32_t, uint32_t); /*!< set timer callback */ - int (*f_get_timer)(void *); /*!< get timer callback */ + + mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */ + mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */ /* * Record layer (incoming data) @@ -725,7 +845,9 @@ struct mbedtls_ssl_context size_t in_hslen; /*!< current handshake message length, including the handshake header */ int nb_zero; /*!< # of 0-length encrypted messages */ - int record_read; /*!< record is already present */ + + int keep_current_message; /*!< drop or reuse current message + on next call to record layer? */ /* * Record layer (outgoing data) @@ -848,7 +970,7 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl ); * \note No copy of the configuration context is made, it can be * shared by many mbedtls_ssl_context structures. * - * \warning Modifying the conf structure after is has been used in this + * \warning Modifying the conf structure after it has been used in this * function is unsupported! * * \param ssl SSL context @@ -866,7 +988,7 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, * pointers and data. * * \param ssl SSL context - * \return 0 if successful, or POLASSL_ERR_SSL_MALLOC_FAILED, + * \return 0 if successful, or MBEDTLS_ERR_SSL_ALLOC_FAILED, MBEDTLS_ERR_SSL_HW_ACCEL_FAILED or * MBEDTLS_ERR_SSL_COMPRESSION_FAILED */ @@ -914,6 +1036,7 @@ void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ); * * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, * handshake is aborted if verification failed. + * (default on client) * * \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at @@ -929,7 +1052,7 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); * * If set, the verify callback is called for each * certificate in the chain. For implementation - * information, please see \c x509parse_verify() + * information, please see \c mbedtls_x509_crt_verify() * * \param conf SSL configuration * \param f_vrfy verification function @@ -978,8 +1101,6 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, * \param f_send write callback * \param f_recv read callback * \param f_recv_timeout blocking read callback with timeout. - * The last argument is the timeout in milliseconds, - * 0 means no timeout (block forever until a message comes) * * \note One of f_recv or f_recv_timeout can be NULL, in which case * the other is used. If both are non-NULL, f_recv_timeout is @@ -991,12 +1112,21 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, * * \note For DTLS, you need to provide either a non-NULL * f_recv_timeout callback, or a f_recv that doesn't block. + * + * \note See the documentations of \c mbedtls_ssl_sent_t, + * \c mbedtls_ssl_recv_t and \c mbedtls_ssl_recv_timeout_t for + * the conventions those callbacks must follow. + * + * \note On some platforms, net_sockets.c provides + * \c mbedtls_net_send(), \c mbedtls_net_recv() and + * \c mbedtls_net_recv_timeout() that are suitable to be used + * here. */ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, - void *p_bio, - int (*f_send)(void *, const unsigned char *, size_t), - int (*f_recv)(void *, unsigned char *, size_t), - int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) ); + void *p_bio, + mbedtls_ssl_send_t *f_send, + mbedtls_ssl_recv_t *f_recv, + mbedtls_ssl_recv_timeout_t *f_recv_timeout ); /** * \brief Set the timeout period for mbedtls_ssl_read() @@ -1017,37 +1147,42 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); /** - * \brief Set the timer callbacks - * (Mandatory for DTLS.) + * \brief Set the timer callbacks (Mandatory for DTLS.) * * \param ssl SSL context - * \param p_timer parameter (context) shared by timer callback + * \param p_timer parameter (context) shared by timer callbacks * \param f_set_timer set timer callback - * Accepts an intermediate and a final delay in milliseconcs - * If the final delay is 0, cancels the running timer. * \param f_get_timer get timer callback. Must return: - * -1 if cancelled - * 0 if none of the delays is expired - * 1 if the intermediate delay only is expired - * 2 if the final delay is expired + * + * \note See the documentation of \c mbedtls_ssl_set_timer_t and + * \c mbedtls_ssl_get_timer_t for the conventions this pair of + * callbacks must follow. + * + * \note On some platforms, timing.c provides + * \c mbedtls_timing_set_delay() and + * \c mbedtls_timing_get_delay() that are suitable for using + * here, except if using an event-driven style. + * + * \note See also the "DTLS tutorial" article in our knowledge base. + * https://tls.mbed.org/kb/how-to/dtls-tutorial */ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, - void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms), - int (*f_get_timer)(void *) ); + mbedtls_ssl_set_timer_t *f_set_timer, + mbedtls_ssl_get_timer_t *f_get_timer ); /** * \brief Callback type: generate and write session ticket * * \note This describes what a callback implementation should do. - * This callback should generate and encrypted and + * This callback should generate an encrypted and * authenticated ticket for the session and write it to the * output buffer. Here, ticket means the opaque ticket part * of the NewSessionTicket structure of RFC 5077. * * \param p_ticket Context for the callback - * \param session SSL session to bo written in the ticket - * \param start Start of the outpur buffer + * \param session SSL session to be written in the ticket + * \param start Start of the output buffer * \param end End of the output buffer * \param tlen On exit, holds the length written * \param lifetime On exit, holds the lifetime of the ticket in seconds @@ -1298,7 +1433,7 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi #if defined(MBEDTLS_SSL_PROTO_DTLS) /** - * \brief Set retransmit timeout values for the DTLS handshale. + * \brief Set retransmit timeout values for the DTLS handshake. * (DTLS only, no effect on TLS.) * * \param conf SSL configuration @@ -1309,9 +1444,24 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi * * \note Default values are from RFC 6347 section 4.2.4.1. * - * \note Higher values for initial timeout may increase average - * handshake latency. Lower values may increase the risk of - * network congestion by causing more retransmissions. + * \note The 'min' value should typically be slightly above the + * expected round-trip time to your peer, plus whatever time + * it takes for the peer to process the message. For example, + * if your RTT is about 600ms and you peer needs up to 1s to + * do the cryptographic operations in the handshake, then you + * should set 'min' slightly above 1600. Lower values of 'min' + * might cause spurious resends which waste network resources, + * while larger value of 'min' will increase overall latency + * on unreliable network links. + * + * \note The more unreliable your network connection is, the larger + * your max / min ratio needs to be in order to achieve + * reliable handshakes. + * + * \note Messages are retransmitted up to log2(ceil(max/min)) times. + * For example, if min = 1s and max = 5s, the retransmit plan + * goes: send ... 1s -> resend ... 2s -> resend ... 4s -> + * resend ... 5s -> give up and return a timeout error. */ void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ @@ -1381,7 +1531,7 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session /** * \brief Set the list of allowed ciphersuites and the preference * order. First in the list has the highest preference. - * (Overrides all version specific lists) + * (Overrides all version-specific lists) * * The ciphersuites array is not copied, and must remain * valid for the lifetime of the ssl_config. @@ -1459,7 +1609,12 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, * adequate, preference is given to the one set by the first * call to this function, then second, etc. * - * \note On client, only the first call has any effect. + * \note On client, only the first call has any effect. That is, + * only one client certificate can be provisioned. The + * server's preferences in its CertficateRequest message will + * be ignored and our only cert will be sent regardless of + * whether it matches those preferences - the server can then + * decide what it wants to do with it. * * \param conf SSL configuration * \param own_cert own public certificate chain @@ -1479,6 +1634,12 @@ int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, * \note This is mainly useful for clients. Servers will usually * want to use \c mbedtls_ssl_conf_psk_cb() instead. * + * \note Currently clients can only register one pre-shared key. + * In other words, the servers' identity hint is ignored. + * Support for setting multiple PSKs on clients and selecting + * one based on the identity hint is not a planned feature but + * feedback is welcomed. + * * \param conf SSL configuration * \param psk pointer to the pre-shared key * \param psk_len pre-shared key length @@ -1633,10 +1794,11 @@ void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, #if defined(MBEDTLS_X509_CRT_PARSE_C) /** - * \brief Set hostname for ServerName TLS extension + * \brief Set the hostname to check against the received server + * certificate. It sets the ServerName TLS extension too, + * if the extension is enabled. * (client-side only) * - * * \param ssl SSL context * \param hostname the server hostname * @@ -1747,8 +1909,11 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, * \brief Set the supported Application Layer Protocols. * * \param conf SSL configuration - * \param protos NULL-terminated list of supported protocols, - * in decreasing preference order. + * \param protos Pointer to a NULL-terminated list of supported protocols, + * in decreasing preference order. The pointer to the list is + * recorded by the library for later reference as required, so + * the lifetime of the table must be atleast as long as the + * lifetime of the SSL configuration structure. * * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA. */ @@ -1862,11 +2027,13 @@ void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems * \brief Disable or enable support for RC4 * (Default: MBEDTLS_SSL_ARC4_DISABLED) * - * \warning Use of RC4 in (D)TLS has been prohibited by RFC ???? - * for security reasons. Use at your own risks. + * \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465 + * for security reasons. Use at your own risk. * - * \note This function will likely be removed in future versions as - * RC4 will then be disabled by default at compile time. + * \note This function is deprecated and will likely be removed in + * a future version of the library. + * RC4 is disabled by default at compile time and needs to be + * actively enabled for use with legacy systems. * * \param conf SSL configuration * \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED @@ -1874,6 +2041,20 @@ void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); #endif /* MBEDTLS_ARC4_C */ +#if defined(MBEDTLS_SSL_SRV_C) +/** + * \brief Whether to send a list of acceptable CAs in + * CertificateRequest messages. + * (Default: do send) + * + * \param conf SSL configuration + * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or + * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED + */ +void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, + char cert_req_ca_list ); +#endif /* MBEDTLS_SSL_SRV_C */ + #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) /** * \brief Set the maximum fragment length to emit and/or negotiate @@ -1942,7 +2123,7 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets * * \warning It is recommended to always disable renegotation unless you * know you need it and you know what you're doing. In the - * past, there has been several issues associated with + * past, there have been several issues associated with * renegotiation or a poor understanding of its properties. * * \note Server-side, enabling renegotiation also makes the server @@ -2026,7 +2207,7 @@ void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_ /** * \brief Set record counter threshold for periodic renegotiation. - * (Default: 2^64 - 256.) + * (Default: 2^48 - 1) * * Renegotiation is automatically triggered when a record * counter (outgoing or ingoing) crosses the defined @@ -2037,9 +2218,17 @@ void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_ * Lower values can be used to enforce policies such as "keys * must be refreshed every N packets with cipher X". * + * The renegotiation period can be disabled by setting + * conf->disable_renegotiation to + * MBEDTLS_SSL_RENEGOTIATION_DISABLED. + * + * \note When the configured transport is + * MBEDTLS_SSL_TRANSPORT_DATAGRAM the maximum renegotiation + * period is 2^48 - 1, and for MBEDTLS_SSL_TRANSPORT_STREAM, + * the maximum renegotiation period is 2^64 - 1. + * * \param conf SSL configuration * \param period The threshold value: a big-endian 64-bit number. - * Set to 2^64 - 1 to disable periodic renegotiation */ void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, const unsigned char period[8] ); @@ -2182,8 +2371,8 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ); * \brief Perform a single step of the SSL handshake * * \note The state of the context (ssl->state) will be at - * the following state after execution of this function. - * Do not call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. + * the next state after execution of this function. Do not + * call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. * * \note If this function returns something other than 0 or * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context @@ -2204,11 +2393,13 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ); * \brief Initiate an SSL renegotiation on the running connection. * Client: perform the renegotiation right now. * Server: request renegotiation, which will be performed - * during the next call to mbedtls_ssl_read() if honored by client. + * during the next call to mbedtls_ssl_read() if honored by + * client. * * \param ssl SSL context * - * \return 0 if successful, or any mbedtls_ssl_handshake() return value. + * \return 0 if successful, or any mbedtls_ssl_handshake() return + * value. * * \note If this function returns something other than 0 or * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context @@ -2269,7 +2460,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * \param len how many bytes must be written * * \return the number of bytes actually written (may be less than len), - * or MBEDTLS_ERR_SSL_WANT_WRITE of MBEDTLS_ERR_SSL_WANT_READ, + * 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 @@ -2354,7 +2545,6 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ); * \param transport MBEDTLS_SSL_TRANSPORT_STREAM for TLS, or * MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS * \param preset a MBEDTLS_SSL_PRESET_XXX value - * (currently unused). * * \note See \c mbedtls_ssl_conf_transport() for notes on DTLS. * diff --git a/app/include/mbedtls/ssl_cache.h b/app/include/mbedtls/ssl_cache.h index 1155924a..3734bb72 100644 --- a/app/include/mbedtls/ssl_cache.h +++ b/app/include/mbedtls/ssl_cache.h @@ -60,7 +60,7 @@ typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry; struct mbedtls_ssl_cache_entry { #if defined(MBEDTLS_HAVE_TIME) - time_t timestamp; /*!< entry timestamp */ + mbedtls_time_t timestamp; /*!< entry timestamp */ #endif mbedtls_ssl_session session; /*!< entry session */ #if defined(MBEDTLS_X509_CRT_PARSE_C) diff --git a/app/include/mbedtls/ssl_ciphersuites.h b/app/include/mbedtls/ssl_ciphersuites.h index deaaa375..9101d9cc 100644 --- a/app/include/mbedtls/ssl_ciphersuites.h +++ b/app/include/mbedtls/ssl_ciphersuites.h @@ -260,6 +260,47 @@ typedef enum { #define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED #endif +/* Key exchanges allowing client certificate requests */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED +#endif + +/* Key exchanges involving server signature in ServerKeyExchange */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED +#endif + +/* Key exchanges using ECDH */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED +#endif + +/* Key exchanges that don't involve ephemeral keys */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED +#endif + +/* Key exchanges that involve ephemeral keys */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED +#endif + /* Key exchanges using a PSK */ #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ @@ -268,7 +309,13 @@ typedef enum { #define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED #endif -/* Key exchanges using a ECDHE */ +/* Key exchanges using DHE */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#define MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED +#endif + +/* Key exchanges using ECDHE */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) @@ -309,11 +356,128 @@ const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuit #if defined(MBEDTLS_PK_C) mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ); +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ); #endif int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ); int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ); +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED) +static inline int mbedtls_ssl_ciphersuite_has_pfs( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECJPAKE: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED) +static inline int mbedtls_ssl_ciphersuite_no_pfs( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_PSK: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdh( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */ + +static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_ecdhe( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) */ + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +static inline int mbedtls_ssl_ciphersuite_uses_server_signature( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ + #ifdef __cplusplus } #endif diff --git a/app/include/mbedtls/ssl_internal.h b/app/include/mbedtls/ssl_internal.h index 3af059f8..756360b1 100644 --- a/app/include/mbedtls/ssl_internal.h +++ b/app/include/mbedtls/ssl_internal.h @@ -157,6 +157,24 @@ extern "C" { #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +/* + * Abstraction for a grid of allowed signature-hash-algorithm pairs. + */ +struct mbedtls_ssl_sig_hash_set_t +{ + /* At the moment, we only need to remember a single suitable + * hash algorithm per signature algorithm. As long as that's + * the case - and we don't need a general lookup function - + * we can implement the sig-hash-set as a map from signatures + * to hash algorithms. */ + mbedtls_md_type_t rsa; + mbedtls_md_type_t ecdsa; +}; +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + /* * This structure contains the parameters only needed during handshake. */ @@ -165,9 +183,11 @@ struct mbedtls_ssl_handshake_params /* * Handshake specific crypto variables */ - int sig_alg; /*!< Hash algorithm for signature */ - int cert_type; /*!< Requested cert type */ - int verify_sig_alg; /*!< Signature algorithm for verify */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + mbedtls_ssl_sig_hash_set_t hash_algs; /*!< Set of suitable sig-hash pairs */ +#endif #if defined(MBEDTLS_DHM_C) mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ #endif @@ -180,7 +200,7 @@ struct mbedtls_ssl_handshake_params unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ size_t ecjpake_cache_len; /*!< Length of cached data */ #endif -#endif +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ @@ -196,7 +216,7 @@ struct mbedtls_ssl_handshake_params mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ -#endif +#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 */ @@ -219,7 +239,7 @@ struct mbedtls_ssl_handshake_params resending messages */ unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter for resending messages */ -#endif +#endif /* MBEDTLS_SSL_PROTO_DTLS */ /* * Checksum contexts @@ -330,6 +350,28 @@ struct mbedtls_ssl_flight_item }; #endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + +/* Find an entry in a signature-hash set matching a given hash algorithm. */ +mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, + mbedtls_pk_type_t sig_alg ); +/* Add a signature-hash-pair to a signature-hash set */ +void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, + mbedtls_pk_type_t sig_alg, + mbedtls_md_type_t md_alg ); +/* Allow exactly one hash algorithm for each signature. */ +void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, + mbedtls_md_type_t md_alg ); + +/* Setup an empty signature-hash set */ +static inline void mbedtls_ssl_sig_hash_set_init( mbedtls_ssl_sig_hash_set_t *set ) +{ + mbedtls_ssl_sig_hash_set_const_hash( set, MBEDTLS_MD_NONE ); +} + +#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ /** * \brief Free referenced items in an SSL transform context and clear @@ -356,6 +398,84 @@ int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); + +/** + * \brief Update record layer + * + * This function roughly separates the implementation + * of the logic of (D)TLS from the implementation + * of the secure transport. + * + * \param ssl SSL context to use + * + * \return 0 or non-zero error code. + * + * \note A clarification on what is called 'record layer' here + * is in order, as many sensible definitions are possible: + * + * The record layer takes as input an untrusted underlying + * transport (stream or datagram) and transforms it into + * a serially multiplexed, secure transport, which + * conceptually provides the following: + * + * (1) Three datagram based, content-agnostic transports + * for handshake, alert and CCS messages. + * (2) One stream- or datagram-based transport + * for application data. + * (3) Functionality for changing the underlying transform + * securing the contents. + * + * The interface to this functionality is given as follows: + * + * a Updating + * [Currently implemented by mbedtls_ssl_read_record] + * + * Check if and on which of the four 'ports' data is pending: + * Nothing, a controlling datagram of type (1), or application + * data (2). In any case data is present, internal buffers + * provide access to the data for the user to process it. + * Consumption of type (1) datagrams is done automatically + * on the next update, invalidating that the internal buffers + * for previous datagrams, while consumption of application + * data (2) is user-controlled. + * + * b Reading of application data + * [Currently manual adaption of ssl->in_offt pointer] + * + * As mentioned in the last paragraph, consumption of data + * is different from the automatic consumption of control + * datagrams (1) because application data is treated as a stream. + * + * c Tracking availability of application data + * [Currently manually through decreasing ssl->in_msglen] + * + * For efficiency and to retain datagram semantics for + * application data in case of DTLS, the record layer + * provides functionality for checking how much application + * data is still available in the internal buffer. + * + * d Changing the transformation securing the communication. + * + * Given an opaque implementation of the record layer in the + * above sense, it should be possible to implement the logic + * of (D)TLS on top of it without the need to know anything + * about the record layer's internals. This is done e.g. + * in all the handshake handling functions, and in the + * application data reading function mbedtls_ssl_read. + * + * \note The above tries to give a conceptual picture of the + * record layer, but the current implementation deviates + * from it in some places. For example, our implementation of + * the update functionality through mbedtls_ssl_read_record + * discards datagrams depending on the current state, which + * wouldn't fall under the record layer's responsibility + * following the above definition. + * + */ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ); int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); @@ -380,11 +500,13 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch #if defined(MBEDTLS_PK_C) unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ); +unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ); mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); #endif mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); unsigned char mbedtls_ssl_hash_from_md_alg( int md ); +int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); #if defined(MBEDTLS_ECP_C) int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); diff --git a/app/include/mbedtls/threading.h b/app/include/mbedtls/threading.h index c39cbf24..b0c34ecc 100644 --- a/app/include/mbedtls/threading.h +++ b/app/include/mbedtls/threading.h @@ -81,6 +81,7 @@ void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * void mbedtls_threading_free_alt( void ); #endif /* MBEDTLS_THREADING_ALT */ +#if defined(MBEDTLS_THREADING_C) /* * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock * @@ -96,6 +97,7 @@ extern int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t *mutex ); */ extern mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex; extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; +#endif /* MBEDTLS_THREADING_C */ #ifdef __cplusplus } diff --git a/app/include/mbedtls/version.h b/app/include/mbedtls/version.h index ea2966e8..c5288b94 100644 --- a/app/include/mbedtls/version.h +++ b/app/include/mbedtls/version.h @@ -38,7 +38,7 @@ * Major, Minor, Patchlevel */ #define MBEDTLS_VERSION_MAJOR 2 -#define MBEDTLS_VERSION_MINOR 2 +#define MBEDTLS_VERSION_MINOR 6 #define MBEDTLS_VERSION_PATCH 1 /** @@ -46,9 +46,9 @@ * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02020100 -#define MBEDTLS_VERSION_STRING "2.2.1" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.2.1" +#define MBEDTLS_VERSION_NUMBER 0x02060100 +#define MBEDTLS_VERSION_STRING "2.6.1" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.6.1" #if defined(MBEDTLS_VERSION_C) diff --git a/app/include/mbedtls/x509.h b/app/include/mbedtls/x509.h index 54dac166..d7e318df 100644 --- a/app/include/mbedtls/x509.h +++ b/app/include/mbedtls/x509.h @@ -76,6 +76,7 @@ #define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ +#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */ /* \} name */ /** @@ -157,7 +158,7 @@ #define MBEDTLS_X509_EXT_INIHIBIT_ANYPOLICY (1 << 13) #define MBEDTLS_X509_EXT_FRESHEST_CRL (1 << 14) -#define MBEDTLS_X509_EXT_NS_CERT_TYPE (1 << 16) /* Parsed (and then ?) */ +#define MBEDTLS_X509_EXT_NS_CERT_TYPE (1 << 16) /* * Storage format identifiers @@ -246,12 +247,12 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se * \note Intended usage is "if( is_past( valid_to ) ) ERROR". * Hence the return value of 1 if on internal errors. * - * \param time mbedtls_x509_time to check + * \param to mbedtls_x509_time to check * * \return 1 if the given time is in the past or an error occured, * 0 otherwise. */ -int mbedtls_x509_time_is_past( const mbedtls_x509_time *time ); +int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); /** * \brief Check a given mbedtls_x509_time against the system time @@ -260,12 +261,12 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *time ); * \note Intended usage is "if( is_future( valid_from ) ) ERROR". * Hence the return value of 1 if on internal errors. * - * \param time mbedtls_x509_time to check + * \param from mbedtls_x509_time to check * * \return 1 if the given time is in the future or an error occured, * 0 otherwise. */ -int mbedtls_x509_time_is_future( const mbedtls_x509_time *time ); +int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); /** * \brief Checkup routine @@ -294,7 +295,7 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, void **sig_opts ); int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *time ); + mbedtls_x509_time *t ); int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *serial ); int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, diff --git a/app/include/mbedtls/x509_crt.h b/app/include/mbedtls/x509_crt.h index fe821d1c..06166d8b 100644 --- a/app/include/mbedtls/x509_crt.h +++ b/app/include/mbedtls/x509_crt.h @@ -120,6 +120,10 @@ mbedtls_x509_crt_profile; #define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 #define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 +#if !defined( MBEDTLS_X509_MAX_FILE_PATH_LEN ) +#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 +#endif + /** * Container for writing a certificate (CRT) */ @@ -263,7 +267,13 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, * * All flags left after returning from the callback * are also returned to the application. The function should - * return 0 for anything but a fatal error. + * return 0 for anything (including invalid certificates) + * other than fatal error, as a non-zero return code + * immediately aborts the verification process. For fatal + * errors, a specific error code should be used (different + * from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not + * be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR + * can be used if no better code is available. * * \note In case verification failed, the results can be displayed * using \c mbedtls_x509_crt_verify_info() @@ -271,21 +281,27 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the * default security profile. * - * \param crt a certificate to be verified - * \param trust_ca the trusted CA chain - * \param ca_crl the CRL chain for trusted CA's + * \note It is your responsibility to provide up-to-date CRLs for + * all trusted CAs. If no CRL is provided for the CA that was + * used to sign the certificate, CRL verification is skipped + * silently, that is *without* setting any flag. + * + * \param crt a certificate (chain) to be verified + * \param trust_ca the list of trusted CAs + * \param ca_crl the list of CRLs for trusted CAs (see note above) * \param cn expected Common Name (can be set to * NULL if the CN must not be verified) * \param flags result of the verification * \param f_vrfy verification function * \param p_vrfy verification parameter * - * \return 0 if successful or MBEDTLS_ERR_X509_CERT_VERIFY_FAILED - * in which case *flags will have one or more - * MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX flags - * set, - * or another error in case of a fatal error encountered - * during the verification process. + * \return 0 (and flags set to 0) if the chain was verified and valid, + * MBEDTLS_ERR_X509_CERT_VERIFY_FAILED if the chain was verified + * but found to be invalid, in which case *flags will have one + * or more MBEDTLS_X509_BADCERT_XXX or MBEDTLS_X509_BADCRL_XXX + * flags set, or another error (and flags set to 0xffffffff) + * in case of a fatal error encountered during the + * verification process. */ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, @@ -304,9 +320,9 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, * for ECDSA) apply to all certificates: trusted root, * intermediate CAs if any, and end entity certificate. * - * \param crt a certificate to be verified - * \param trust_ca the trusted CA chain - * \param ca_crl the CRL chain for trusted CA's + * \param crt a certificate (chain) to be verified + * \param trust_ca the list of trusted CAs + * \param ca_crl the list of CRLs for trusted CAs * \param profile security profile for verification * \param cn expected Common Name (can be set to * NULL if the CN must not be verified) diff --git a/app/include/mbedtls/x509_csr.h b/app/include/mbedtls/x509_csr.h index 34998a3a..fe9843cb 100644 --- a/app/include/mbedtls/x509_csr.h +++ b/app/include/mbedtls/x509_csr.h @@ -83,6 +83,8 @@ mbedtls_x509write_csr; /** * \brief Load a Certificate Signing Request (CSR) in DER format * + * \note CSR attributes (if any) are currently silently ignored. + * * \param csr CSR context to fill * \param buf buffer holding the CRL data * \param buflen size of the buffer @@ -95,6 +97,8 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, /** * \brief Load a Certificate Signing Request (CSR), DER or PEM format * + * \note See notes for \c mbedtls_x509_csr_parse_der() + * * \param csr CSR context to fill * \param buf buffer holding the CRL data * \param buflen size of the buffer @@ -108,6 +112,8 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz /** * \brief Load a Certificate Signing Request (CSR) * + * \note See notes for \c mbedtls_x509_csr_parse() + * * \param csr CSR context to fill * \param path filename to read the CSR from * @@ -276,7 +282,7 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s * * \note f_rng may be NULL if RSA is used for signature and the * signature is made offline (otherwise f_rng is desirable - * for couermeasures against timing attacks). + * for countermeasures against timing attacks). * ECDSA signatures always require a non-NULL f_rng. */ int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, diff --git a/app/include/sys/espconn_mbedtls.h b/app/include/sys/espconn_mbedtls.h index c0d7026f..00502093 100644 --- a/app/include/sys/espconn_mbedtls.h +++ b/app/include/sys/espconn_mbedtls.h @@ -31,7 +31,7 @@ #if !defined(ESPCONN_MBEDTLS) -#include "mbedtls/net.h" +#include "mbedtls/net_sockets.h" #include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/entropy.h" diff --git a/app/include/user_mbedtls.h b/app/include/user_mbedtls.h index fa8d0143..9fd773ed 100644 --- a/app/include/user_mbedtls.h +++ b/app/include/user_mbedtls.h @@ -6,7 +6,7 @@ #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE -#undef MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_MEMORY #undef MBEDTLS_PLATFORM_NO_STD_FUNCTIONS #undef MBEDTLS_PLATFORM_EXIT_ALT @@ -126,8 +126,6 @@ #define MBEDTLS_SHA256_SMALLER -#undef MBEDTLS_SSL_AEAD_RANDOM_IV - #define MBEDTLS_SSL_ALL_ALERT_MESSAGES #undef MBEDTLS_SSL_DEBUG_ALL @@ -149,13 +147,13 @@ #define MBEDTLS_SSL_PROTO_TLS1 #define MBEDTLS_SSL_PROTO_TLS1_1 #define MBEDTLS_SSL_PROTO_TLS1_2 -#define MBEDTLS_SSL_PROTO_DTLS +#undef MBEDTLS_SSL_PROTO_DTLS #define MBEDTLS_SSL_ALPN -#define MBEDTLS_SSL_DTLS_ANTI_REPLAY -#define MBEDTLS_SSL_DTLS_HELLO_VERIFY -#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE -#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT +#undef MBEDTLS_SSL_DTLS_ANTI_REPLAY +#undef MBEDTLS_SSL_DTLS_HELLO_VERIFY +#undef MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE +#undef MBEDTLS_SSL_DTLS_BADMAC_LIMIT #define MBEDTLS_SSL_SESSION_TICKETS #define MBEDTLS_SSL_EXPORT_KEYS #define MBEDTLS_SSL_SERVER_NAME_INDICATION @@ -187,6 +185,7 @@ #define MBEDTLS_CCM_C #undef MBEDTLS_CERTS_C #define MBEDTLS_CIPHER_C +#define MBEDTLS_CMAC_C #define MBEDTLS_CTR_DRBG_C #undef MBEDTLS_DEBUG_C #define MBEDTLS_DES_C @@ -260,13 +259,14 @@ //#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ //#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ //#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ //#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +#define MBEDTLS_PLATFORM_STD_CALLOC pvPortCalloc /**< Default allocator to use, can be undefined */ +#define MBEDTLS_PLATFORM_STD_FREE vPortFree /**< Default free to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ @@ -278,11 +278,12 @@ //#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +#define MBEDTLS_PLATFORM_PRINTF_MACRO ets_printf /**< Default printf macro to use, can be undefined */ +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO ets_snprintf /**< Default snprintf macro to use, can be undefined */ +#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO ets_vsnprintf /**< Default vsnprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ @@ -294,3 +295,4 @@ //#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 #define MBEDTLS_X509_MAX_INTERMEDIATE_CA 3 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ diff --git a/app/mbedtls/app/espconn_mbedtls.c b/app/mbedtls/app/espconn_mbedtls.c index 1f3666d1..72e4c51a 100644 --- a/app/mbedtls/app/espconn_mbedtls.c +++ b/app/mbedtls/app/espconn_mbedtls.c @@ -423,22 +423,30 @@ static bool mbedtls_handshake_result(const pmbedtls_msg Threadmsg) static void mbedtls_fail_info(espconn_msg *pinfo, int ret) { pmbedtls_msg TLSmsg = NULL; - lwIP_REQUIRE_ACTION(pinfo,exit,ret = ERR_ARG); + lwIP_REQUIRE_ACTION(pinfo,exit,); TLSmsg = pinfo->pssl; - lwIP_REQUIRE_ACTION(TLSmsg,exit,ret = ERR_ARG); + lwIP_REQUIRE_ACTION(TLSmsg,exit,); - if (TLSmsg->quiet){ - if (pinfo->preverse != NULL) { - os_printf("server's data invalid protocol\n"); - } else { - os_printf("client's data invalid protocol\n"); - } + if (TLSmsg->quiet) { mbedtls_ssl_close_notify(&TLSmsg->ssl); - } else{ - if (pinfo->preverse != NULL) { - os_printf("server handshake failed!\n"); - } else { - os_printf("client handshake failed!\n"); + } + + /* Don't complain to console if we've been told the other end is hanging + * up. That's entirely normal and not worthy of the confusion it sows! + */ + if (ret != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { + if (TLSmsg->quiet){ + if (pinfo->preverse != NULL) { + os_printf("server's data invalid protocol\n"); + } else { + os_printf("client's data invalid protocol\n"); + } + } else{ + if (pinfo->preverse != NULL) { + os_printf("server handshake failed!\n"); + } else { + os_printf("client handshake failed!\n"); + } } } @@ -704,6 +712,12 @@ exit: } } +static void +mbedtls_dbg(void *p, int level, const char *file, int line, const char *str) +{ + os_printf("TLS<%d> (heap=%d): %s:%d %s", level, system_get_free_heap_size(), file, line, str); +} + static bool mbedtls_msg_config(mbedtls_msg *msg) { const char *pers = NULL; @@ -784,7 +798,7 @@ static bool mbedtls_msg_config(mbedtls_msg *msg) mbedtls_ssl_conf_authmode(&msg->conf, MBEDTLS_SSL_VERIFY_NONE); } mbedtls_ssl_conf_rng(&msg->conf, mbedtls_ctr_drbg_random, &msg->ctr_drbg); - mbedtls_ssl_conf_dbg(&msg->conf, NULL, NULL); + mbedtls_ssl_conf_dbg(&msg->conf, mbedtls_dbg, NULL); ret = mbedtls_ssl_setup(&msg->ssl, &msg->conf); lwIP_REQUIRE_NOERROR(ret, exit); diff --git a/app/mbedtls/library/aes.c b/app/mbedtls/library/aes.c index 06300426..58603849 100644 --- a/app/mbedtls/library/aes.c +++ b/app/mbedtls/library/aes.c @@ -33,7 +33,6 @@ #if defined(MBEDTLS_AES_C) -#include "c_types.h" #include #include "mbedtls/aes.h" @@ -57,7 +56,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } /* @@ -92,7 +91,7 @@ static int aes_padlock_ace = -1; /* * Forward S-box */ -static const unsigned char FSb[256] ICACHE_RODATA_ATTR STORE_ATTR = +static const unsigned char FSb[256] = { 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, @@ -199,19 +198,19 @@ static const unsigned char FSb[256] ICACHE_RODATA_ATTR STORE_ATTR = V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) #define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t FT0[256] ICACHE_RODATA_ATTR STORE_ATTR = { FT }; +static const uint32_t FT0[256] = { FT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t FT1[256] ICACHE_RODATA_ATTR STORE_ATTR = { FT }; +static const uint32_t FT1[256] = { FT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t FT2[256] ICACHE_RODATA_ATTR STORE_ATTR = { FT }; +static const uint32_t FT2[256] = { FT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t FT3[256] ICACHE_RODATA_ATTR STORE_ATTR = { FT }; +static const uint32_t FT3[256] = { FT }; #undef V #undef FT @@ -219,7 +218,7 @@ static const uint32_t FT3[256] ICACHE_RODATA_ATTR STORE_ATTR = { FT }; /* * Reverse S-box */ -static const unsigned char RSb[256] ICACHE_RODATA_ATTR STORE_ATTR = +static const unsigned char RSb[256] = { 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, @@ -326,19 +325,19 @@ static const unsigned char RSb[256] ICACHE_RODATA_ATTR STORE_ATTR = V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) #define V(a,b,c,d) 0x##a##b##c##d -static const uint32_t RT0[256] ICACHE_RODATA_ATTR STORE_ATTR = { RT }; +static const uint32_t RT0[256] = { RT }; #undef V #define V(a,b,c,d) 0x##b##c##d##a -static const uint32_t RT1[256] ICACHE_RODATA_ATTR STORE_ATTR = { RT }; +static const uint32_t RT1[256] = { RT }; #undef V #define V(a,b,c,d) 0x##c##d##a##b -static const uint32_t RT2[256] ICACHE_RODATA_ATTR STORE_ATTR = { RT }; +static const uint32_t RT2[256] = { RT }; #undef V #define V(a,b,c,d) 0x##d##a##b##c -static const uint32_t RT3[256] ICACHE_RODATA_ATTR STORE_ATTR = { RT }; +static const uint32_t RT3[256] = { RT }; #undef V #undef RT @@ -346,7 +345,7 @@ static const uint32_t RT3[256] ICACHE_RODATA_ATTR STORE_ATTR = { RT }; /* * Round constants */ -static const uint32_t RCON[10] ICACHE_RODATA_ATTR = +static const uint32_t RCON[10] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, @@ -532,10 +531,10 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, for( i = 0; i < 10; i++, RK += 4 ) { RK[4] = RK[0] ^ RCON[i] ^ - ( (uint32_t) system_get_data_of_array_8(FSb ,( RK[3] >> 8 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb ,( RK[3] >> 16 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb ,( RK[3] >> 24 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb ,( RK[3] ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); RK[5] = RK[1] ^ RK[4]; RK[6] = RK[2] ^ RK[5]; @@ -548,10 +547,10 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, for( i = 0; i < 8; i++, RK += 6 ) { RK[6] = RK[0] ^ RCON[i] ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[5] >> 8 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[5] >> 16 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[5] >> 24 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[5] ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); RK[7] = RK[1] ^ RK[6]; RK[8] = RK[2] ^ RK[7]; @@ -566,20 +565,20 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, for( i = 0; i < 7; i++, RK += 8 ) { RK[8] = RK[0] ^ RCON[i] ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[7] >> 8 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[7] >> 16 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[7] >> 24 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[7] ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); RK[9] = RK[1] ^ RK[8]; RK[10] = RK[2] ^ RK[9]; RK[11] = RK[3] ^ RK[10]; RK[12] = RK[4] ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[11] ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[11] >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[11] >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( RK[11] >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); RK[13] = RK[5] ^ RK[12]; RK[14] = RK[6] ^ RK[13]; @@ -642,10 +641,10 @@ int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, { for( j = 0; j < 4; j++, SK++ ) { - *RK++ = RT0[ system_get_data_of_array_8(FSb, ( *SK ) & 0xFF ) ] ^ - RT1[ system_get_data_of_array_8(FSb, ( *SK >> 8 ) & 0xFF ) ] ^ - RT2[ system_get_data_of_array_8(FSb, ( *SK >> 16 ) & 0xFF ) ] ^ - RT3[ system_get_data_of_array_8(FSb, ( *SK >> 24 ) & 0xFF ) ]; + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; } } @@ -711,9 +710,9 @@ exit: * AES-ECB block encryption */ #if !defined(MBEDTLS_AES_ENCRYPT_ALT) -void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) +int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) { int i; uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; @@ -734,43 +733,52 @@ void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); X0 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y0 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y1 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y2 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y3 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); X1 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y1 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y2 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y3 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y0 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); X2 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y2 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y3 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y0 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y1 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); X3 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y3 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y0 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y1 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(FSb, ( Y2 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); PUT_UINT32_LE( X0, output, 0 ); PUT_UINT32_LE( X1, output, 4 ); PUT_UINT32_LE( X2, output, 8 ); PUT_UINT32_LE( X3, output, 12 ); + + return( 0 ); } #endif /* !MBEDTLS_AES_ENCRYPT_ALT */ +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + mbedtls_internal_aes_encrypt( ctx, input, output ); +} + /* * AES-ECB block decryption */ #if !defined(MBEDTLS_AES_DECRYPT_ALT) -void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, - const unsigned char input[16], - unsigned char output[16] ) +int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) { int i; uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; @@ -791,36 +799,45 @@ void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); X0 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y0 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y3 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y2 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y1 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); X1 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y1 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y0 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y3 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y2 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); X2 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y2 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y1 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y0 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y3 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); X3 = *RK++ ^ \ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y3 ) & 0xFF ) ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y2 >> 8 ) & 0xFF ) << 8 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y1 >> 16 ) & 0xFF ) << 16 ) ^ - ( (uint32_t) system_get_data_of_array_8(RSb, ( Y0 >> 24 ) & 0xFF ) << 24 ); + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); PUT_UINT32_LE( X0, output, 0 ); PUT_UINT32_LE( X1, output, 4 ); PUT_UINT32_LE( X2, output, 8 ); PUT_UINT32_LE( X3, output, 12 ); + + return( 0 ); } #endif /* !MBEDTLS_AES_DECRYPT_ALT */ +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + mbedtls_internal_aes_decrypt( ctx, input, output ); +} + /* * AES-ECB block encryption/decryption */ @@ -847,11 +864,9 @@ int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, #endif if( mode == MBEDTLS_AES_ENCRYPT ) - mbedtls_aes_encrypt( ctx, input, output ); + return( mbedtls_internal_aes_encrypt( ctx, input, output ) ); else - mbedtls_aes_decrypt( ctx, input, output ); - - return( 0 ); + return( mbedtls_internal_aes_decrypt( ctx, input, output ) ); } #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1223,7 +1238,9 @@ int mbedtls_aes_self_test( int verbose ) int ret = 0, i, j, u, v; unsigned char key[32]; unsigned char buf[64]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) unsigned char iv[16]; +#endif #if defined(MBEDTLS_CIPHER_MODE_CBC) unsigned char prv[16]; #endif diff --git a/app/mbedtls/library/aesni.c b/app/mbedtls/library/aesni.c index 83a5868b..1ca3c3ef 100644 --- a/app/mbedtls/library/aesni.c +++ b/app/mbedtls/library/aesni.c @@ -100,7 +100,7 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, asm( "movdqu (%3), %%xmm0 \n\t" // load input "movdqu (%1), %%xmm1 \n\t" // load round key 0 "pxor %%xmm1, %%xmm0 \n\t" // round 0 - "addq $16, %1 \n\t" // point to next round key + "add $16, %1 \n\t" // point to next round key "subl $1, %0 \n\t" // normal rounds = nr - 1 "test %2, %2 \n\t" // mode? "jz 2f \n\t" // 0 = decrypt @@ -108,7 +108,7 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, "1: \n\t" // encryption loop "movdqu (%1), %%xmm1 \n\t" // load round key AESENC xmm1_xmm0 "\n\t" // do round - "addq $16, %1 \n\t" // point to next round key + "add $16, %1 \n\t" // point to next round key "subl $1, %0 \n\t" // loop "jnz 1b \n\t" "movdqu (%1), %%xmm1 \n\t" // load round key @@ -118,7 +118,7 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, "2: \n\t" // decryption loop "movdqu (%1), %%xmm1 \n\t" AESDEC xmm1_xmm0 "\n\t" // do round - "addq $16, %1 \n\t" + "add $16, %1 \n\t" "subl $1, %0 \n\t" "jnz 2b \n\t" "movdqu (%1), %%xmm1 \n\t" // load round key diff --git a/app/mbedtls/library/arc4.c b/app/mbedtls/library/arc4.c index ff0e993e..05b33d3f 100644 --- a/app/mbedtls/library/arc4.c +++ b/app/mbedtls/library/arc4.c @@ -49,7 +49,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) diff --git a/app/mbedtls/library/asn1parse.c b/app/mbedtls/library/asn1parse.c index b37523de..4dd65c03 100644 --- a/app/mbedtls/library/asn1parse.c +++ b/app/mbedtls/library/asn1parse.c @@ -45,7 +45,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } /* @@ -153,7 +153,7 @@ int mbedtls_asn1_get_int( unsigned char **p, if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) return( ret ); - if( len > sizeof( int ) || ( **p & 0x80 ) != 0 ) + if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); *val = 0; @@ -269,7 +269,8 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p, /* Allocate and assign next pointer */ if( *p < end ) { - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); + cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, + sizeof( mbedtls_asn1_sequence ) ); if( cur->next == NULL ) return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); diff --git a/app/mbedtls/library/asn1write.c b/app/mbedtls/library/asn1write.c index 00ed73c1..69b61b20 100644 --- a/app/mbedtls/library/asn1write.c +++ b/app/mbedtls/library/asn1write.c @@ -60,16 +60,43 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 2 ); } - if( *p - start < 3 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + if( len <= 0xFFFF ) + { + if( *p - start < 3 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - // We assume we never have lengths larger than 65535 bytes - // - *--(*p) = len % 256; - *--(*p) = ( len / 256 ) % 256; - *--(*p) = 0x82; + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = 0x82; + return( 3 ); + } - return( 3 ); + if( len <= 0xFFFFFF ) + { + if( *p - start < 4 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = 0x83; + return( 4 ); + } + + if( len <= 0xFFFFFFFF ) + { + if( *p - start < 5 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = ( len >> 24 ) & 0xFF; + *--(*p) = 0x84; + return( 5 ); + } + + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); } int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) @@ -312,7 +339,9 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data { // Add new entry if not present yet based on OID // - if( ( cur = mbedtls_calloc( 1, sizeof(mbedtls_asn1_named_data) ) ) == NULL ) + cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, + sizeof(mbedtls_asn1_named_data) ); + if( cur == NULL ) return( NULL ); cur->oid.len = oid_len; diff --git a/app/mbedtls/library/base64.c b/app/mbedtls/library/base64.c index 36be7aa0..f06b57b3 100644 --- a/app/mbedtls/library/base64.c +++ b/app/mbedtls/library/base64.c @@ -41,7 +41,7 @@ #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ -static const unsigned char base64_enc_map[64] ICACHE_RODATA_ATTR = +static const unsigned char base64_enc_map[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', @@ -52,7 +52,7 @@ static const unsigned char base64_enc_map[64] ICACHE_RODATA_ATTR = '8', '9', '+', '/' }; -static const unsigned char base64_dec_map[128] ICACHE_RODATA_ATTR = +static const unsigned char base64_dec_map[128] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, @@ -97,7 +97,7 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, n *= 4; - if( dlen < n + 1 ) + if( ( dlen < n + 1 ) || ( NULL == dst ) ) { *olen = n + 1; return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); @@ -111,10 +111,10 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, C2 = *src++; C3 = *src++; - *p++ = system_get_data_of_array_8(base64_enc_map, (C1 >> 2) & 0x3F); - *p++ = system_get_data_of_array_8(base64_enc_map, (((C1 & 3) << 4) + (C2 >> 4)) & 0x3F); - *p++ = system_get_data_of_array_8(base64_enc_map, (((C2 & 15) << 2) + (C3 >> 6)) & 0x3F); - *p++ = system_get_data_of_array_8(base64_enc_map, C3 & 0x3F); + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; } if( i < slen ) @@ -122,11 +122,11 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, C1 = *src++; C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; - *p++ = system_get_data_of_array_8(base64_enc_map, (C1 >> 2) & 0x3F); - *p++ = system_get_data_of_array_8(base64_enc_map, (((C1 & 3) << 4) + (C2 >> 4)) & 0x3F); + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; if( ( i + 1 ) < slen ) - *p++ = system_get_data_of_array_8(base64_enc_map, ((C2 & 15) << 2) & 0x3F); + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; else *p++ = '='; *p++ = '='; @@ -177,10 +177,10 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, if( src[i] == '=' && ++j > 2 ) return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - if( src[i] > 127 || system_get_data_of_array_8(base64_dec_map, src[i]) == 127 ) + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); - if( system_get_data_of_array_8(base64_dec_map, src[i]) < 64 && j != 0 ) + if( base64_dec_map[src[i]] < 64 && j != 0 ) return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); n++; @@ -192,7 +192,11 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, return( 0 ); } - n = ( ( n * 6 ) + 7 ) >> 3; + /* The following expression is to calculate the following formula without + * risk of integer overflow in n: + * n = ( ( n * 6 ) + 7 ) >> 3; + */ + n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 ); n -= j; if( dst == NULL || dlen < n ) @@ -206,8 +210,8 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, if( *src == '\r' || *src == '\n' || *src == ' ' ) continue; - j -= ( system_get_data_of_array_8(base64_dec_map, *src) == 64 ); - x = ( x << 6 ) | ( system_get_data_of_array_8(base64_dec_map, *src) & 0x3F ); + j -= ( base64_dec_map[*src] == 64 ); + x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); if( ++n == 4 ) { diff --git a/app/mbedtls/library/bignum.c b/app/mbedtls/library/bignum.c index c55fdb87..d3a150c3 100644 --- a/app/mbedtls/library/bignum.c +++ b/app/mbedtls/library/bignum.c @@ -42,7 +42,7 @@ #endif #if defined(MBEDTLS_BIGNUM_C) -#include "c_types.h" + #include "mbedtls/bignum.h" #include "mbedtls/bn_mul.h" @@ -59,8 +59,8 @@ #endif /* Implementation that should never be optimized out by the compiler */ -static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; +static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) { + volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0; } #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ @@ -99,7 +99,7 @@ void mbedtls_mpi_free( mbedtls_mpi *X ) if( X->p != NULL ) { - mbedtls_zeroize( X->p, X->n * ciL ); + mbedtls_mpi_zeroize( X->p, X->n ); mbedtls_free( X->p ); } @@ -120,13 +120,13 @@ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) if( X->n < nblimbs ) { - if( ( p = mbedtls_calloc( nblimbs, ciL ) ) == NULL ) + if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->p != NULL ) { memcpy( p, X->p, X->n * ciL ); - mbedtls_zeroize( X->p, X->n * ciL ); + mbedtls_mpi_zeroize( X->p, X->n ); mbedtls_free( X->p ); } @@ -158,13 +158,13 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) if( i < nblimbs ) i = nblimbs; - if( ( p = mbedtls_calloc( i, ciL ) ) == NULL ) + if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->p != NULL ) { memcpy( p, X->p, i * ciL ); - mbedtls_zeroize( X->p, X->n * ciL ); + mbedtls_mpi_zeroize( X->p, X->n ); mbedtls_free( X->p ); } @@ -534,7 +534,12 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, n = mbedtls_mpi_bitlen( X ); if( radix >= 4 ) n >>= 1; if( radix >= 16 ) n >>= 1; - n += 3; + /* + * Round up the buffer length to an even value to ensure that there is + * enough room for hexadecimal values that can be represented in an odd + * number of digits. + */ + n += 3 + ( ( n + 1 ) & 1 ); if( buflen < n ) { @@ -611,11 +616,11 @@ int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ) if( slen == sizeof( s ) - 2 ) return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); - if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } - if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } + if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } + if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } p = s + slen; - while( --p >= s ) + while( p-- > s ) if( mpi_get_digit( &d, radix, *p ) != 0 ) break; @@ -883,7 +888,7 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi { int ret; size_t i, j; - mbedtls_mpi_uint *o, *p, c; + mbedtls_mpi_uint *o, *p, c, tmp; if( X == B ) { @@ -906,10 +911,14 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi o = B->p; p = X->p; c = 0; + /* + * tmp is used because it might happen that p == o + */ for( i = 0; i < j; i++, o++, p++ ) { + tmp= *o; *p += c; c = ( *p < c ); - *p += *o; c += ( *p < *o ); + *p += tmp; c += ( *p < tmp ); } while( c != 0 ) @@ -1538,12 +1547,15 @@ static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N ) /* * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) */ -static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, +static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T ) { size_t i, n, m; mbedtls_mpi_uint u0, u1, *d; + if( T->n < N->n + 1 || T->p == NULL ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + memset( T->p, 0, T->n * ciL ); d = T->p; @@ -1571,12 +1583,14 @@ static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi else /* prevent timing attacks */ mpi_sub_hlp( n, A->p, T->p ); + + return( 0 ); } /* * Montgomery reduction: A = A * R^-1 mod N */ -static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T ) +static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T ) { mbedtls_mpi_uint z = 1; mbedtls_mpi U; @@ -1584,7 +1598,7 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint U.n = U.s = (int) z; U.p = &z; - mpi_montmul( A, &U, N, mm, T ); + return( mpi_montmul( A, &U, N, mm, T ) ); } /* @@ -1661,13 +1675,13 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi else MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); - mpi_montmul( &W[1], &RR, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) ); /* * X = R^2 * R^-1 mod N = R mod N */ MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); - mpi_montred( X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); if( wsize > 1 ) { @@ -1680,7 +1694,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) ); for( i = 0; i < wsize - 1; i++ ) - mpi_montmul( &W[j], &W[j], N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) ); /* * W[i] = W[i - 1] * W[1] @@ -1690,7 +1704,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) ); - mpi_montmul( &W[i], &W[1], N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) ); } } @@ -1727,7 +1741,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi /* * out of window, square X */ - mpi_montmul( X, X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); continue; } @@ -1745,12 +1759,12 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi * X = X^wsize R^-1 mod N */ for( i = 0; i < wsize; i++ ) - mpi_montmul( X, X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); /* * X = X * W[wbits] R^-1 mod N */ - mpi_montmul( X, &W[wbits], N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) ); state--; nbits = 0; @@ -1763,20 +1777,20 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi */ for( i = 0; i < nbits; i++ ) { - mpi_montmul( X, X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); wbits <<= 1; if( ( wbits & ( one << wsize ) ) != 0 ) - mpi_montmul( X, &W[1], N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) ); } /* * X = A^E * R * R^-1 mod N = A^E mod N */ - mpi_montred( X, N, mm, &T ); + MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); - if( neg ) + if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 ) { X->s = -1; MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); @@ -1879,7 +1893,7 @@ int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi int ret; mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; - if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 ) + if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 ); @@ -1968,7 +1982,7 @@ cleanup: #if defined(MBEDTLS_GENPRIME) -static const int small_prime[] ICACHE_RODATA_ATTR STORE_ATTR = +static const int small_prime[] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, diff --git a/app/mbedtls/library/blowfish.c b/app/mbedtls/library/blowfish.c index 89be4d12..9003f0df 100644 --- a/app/mbedtls/library/blowfish.c +++ b/app/mbedtls/library/blowfish.c @@ -41,7 +41,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } /* diff --git a/app/mbedtls/library/camellia.c b/app/mbedtls/library/camellia.c index e015ca24..ac6f96a8 100644 --- a/app/mbedtls/library/camellia.c +++ b/app/mbedtls/library/camellia.c @@ -50,7 +50,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } /* @@ -963,38 +963,38 @@ int mbedtls_camellia_self_test( int verbose ) mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); - memcpy( src, camellia_test_cbc_iv, 16 ); - memcpy( dst, camellia_test_cbc_iv, 16 ); - memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); - - if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); - } else { - mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); - } - - for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { + memcpy( src, camellia_test_cbc_iv, 16 ); + memcpy( dst, camellia_test_cbc_iv, 16 ); + memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); if( v == MBEDTLS_CAMELLIA_DECRYPT ) { - memcpy( iv , src, 16 ); - memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); - memcpy( dst, camellia_test_cbc_plain[i], 16 ); - } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ - memcpy( iv , dst, 16 ); - memcpy( src, camellia_test_cbc_plain[i], 16 ); - memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); + mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + } else { + mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); } - mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); + for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { - if( memcmp( buf, dst, 16 ) != 0 ) - { - if( verbose != 0 ) - mbedtls_printf( "failed\n" ); + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + memcpy( iv , src, 16 ); + memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); + memcpy( dst, camellia_test_cbc_plain[i], 16 ); + } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ + memcpy( iv , dst, 16 ); + memcpy( src, camellia_test_cbc_plain[i], 16 ); + memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); + } - return( 1 ); + mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } } - } if( verbose != 0 ) mbedtls_printf( "passed\n" ); diff --git a/app/mbedtls/library/ccm.c b/app/mbedtls/library/ccm.c index 3463a0b3..13a8fd1a 100644 --- a/app/mbedtls/library/ccm.c +++ b/app/mbedtls/library/ccm.c @@ -51,7 +51,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } #define CCM_ENCRYPT 0 diff --git a/app/mbedtls/library/certs.c b/app/mbedtls/library/certs.c index ffa48abf..f1379b8c 100644 --- a/app/mbedtls/library/certs.c +++ b/app/mbedtls/library/certs.c @@ -27,8 +27,6 @@ #include "mbedtls/certs.h" -#if defined(MBEDTLS_SELF_TEST) - #if defined(MBEDTLS_CERTS_C) #if defined(MBEDTLS_ECDSA_C) @@ -49,6 +47,7 @@ "uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ "-----END CERTIFICATE-----\r\n" const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; +const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec ); const char mbedtls_test_ca_key_ec[] = "-----BEGIN EC PRIVATE KEY-----\r\n" @@ -60,8 +59,10 @@ const char mbedtls_test_ca_key_ec[] = "UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" "a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" "-----END EC PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec ); const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest"; +const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; const char mbedtls_test_srv_crt_ec[] = "-----BEGIN CERTIFICATE-----\r\n" @@ -78,6 +79,7 @@ const char mbedtls_test_srv_crt_ec[] = "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" "-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec ); const char mbedtls_test_srv_key_ec[] = "-----BEGIN EC PRIVATE KEY-----\r\n" @@ -85,6 +87,7 @@ const char mbedtls_test_srv_key_ec[] = "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" "-----END EC PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec ); const char mbedtls_test_cli_crt_ec[] = "-----BEGIN CERTIFICATE-----\r\n" @@ -101,6 +104,7 @@ const char mbedtls_test_cli_crt_ec[] = "lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" "LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" "-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec ); const char mbedtls_test_cli_key_ec[] = "-----BEGIN EC PRIVATE KEY-----\r\n" @@ -108,20 +112,45 @@ const char mbedtls_test_cli_key_ec[] = "AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" "wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" "-----END EC PRIVATE KEY-----\r\n"; - -const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec ); -const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec ); -const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; -const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec ); -const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec ); -const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec ); const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec ); -#else -#define TEST_CA_CRT_EC #endif /* MBEDTLS_ECDSA_C */ #if defined(MBEDTLS_RSA_C) -#define TEST_CA_CRT_RSA \ + +#if defined(MBEDTLS_SHA256_C) +#define TEST_CA_CRT_RSA_SHA256 \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ +"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ +"MTcwNTA0MTY1NzAxWhcNMjcwNTA1MTY1NzAxWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ +"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ +"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ +"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ +"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ +"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ +"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ +"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ +"gZUwgZIwHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/MGMGA1UdIwRcMFqA\r\n" \ +"FLRa5KWz3tJS9rnVppUP6z68x/3/oT+kPTA7MQswCQYDVQQGEwJOTDERMA8GA1UE\r\n" \ +"CgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0GCAQAwDAYDVR0T\r\n" \ +"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAHK/HHrTZMnnVMpde1io+voAtql7j\r\n" \ +"4sRhLrjD7o3THtwRbDa2diCvpq0Sq23Ng2LMYoXsOxoL/RQK3iN7UKxV3MKPEr0w\r\n" \ +"XQS+kKQqiT2bsfrjnWMVHZtUOMpm6FNqcdGm/Rss3vKda2lcKl8kUnq/ylc1+QbB\r\n" \ +"G6A6tUvQcr2ZyWfVg+mM5XkhTrOOXus2OLikb4WwEtJTJRNE0f+yPODSUz0/vT57\r\n" \ +"ApH0CnB80bYJshYHPHHymOtleAB8KSYtqm75g/YNobjnjB6cm4HkW3OZRVIl6fYY\r\n" \ +"n20NRVA1Vjs6GAROr4NqW4k/+LofY9y0LLDE+p0oIEKXIsIvhPr39swxSA==\r\n" \ +"-----END CERTIFICATE-----\r\n" + +const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA256; +const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); +#define TEST_CA_CRT_RSA_SOME + +static const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; + +#endif + +#if !defined(TEST_CA_CRT_RSA_SOME) || defined(MBEDTLS_SHA1_C) +#define TEST_CA_CRT_RSA_SHA1 \ "-----BEGIN CERTIFICATE-----\r\n" \ "MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ "MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ @@ -143,7 +172,15 @@ const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec ); "m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \ "7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \ "-----END CERTIFICATE-----\r\n" -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA; + +#if !defined (TEST_CA_CRT_RSA_SOME) +const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA1; +const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); +#endif + +static const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; + +#endif const char mbedtls_test_ca_key_rsa[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" @@ -176,8 +213,10 @@ const char mbedtls_test_ca_key_rsa[] = "wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" "P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" "-----END RSA PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa ); const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest"; +const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; const char mbedtls_test_srv_crt_rsa[] = "-----BEGIN CERTIFICATE-----\r\n" @@ -200,6 +239,7 @@ const char mbedtls_test_srv_crt_rsa[] = "RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n" "zhuYwjVuX6JHG0c=\r\n" "-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); const char mbedtls_test_srv_key_rsa[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" @@ -229,28 +269,31 @@ const char mbedtls_test_srv_key_rsa[] = "4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" "TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" "-----END RSA PRIVATE KEY-----\r\n"; +const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa ); const char mbedtls_test_cli_crt_rsa[] = "-----BEGIN CERTIFICATE-----\r\n" -"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" -"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" -"MTEwMjEyMTQ0NDA3WhcNMjEwMjEyMTQ0NDA3WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" +"MIIDhTCCAm2gAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTcwNTA1MTMwNzU5WhcNMjcwNTA2MTMwNzU5WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" "M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" "1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" "MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" "4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" "/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" -"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" -"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n" -"AQEAAn86isAM8X+mVwJqeItt6E9slhEQbAofyk+diH1Lh8Y9iLlWQSKbw/UXYjx5\r\n" -"LLPZcniovxIcARC/BjyZR9g3UwTHNGNm+rwrqa15viuNOFBchykX/Orsk02EH7NR\r\n" -"Alw5WLPorYjED6cdVQgBl9ot93HdJogRiXCxErM7NC8/eP511mjq+uLDjLKH8ZPQ\r\n" -"8I4ekHJnroLsDkIwXKGIsvIBHQy2ac/NwHLCQOK6mfum1pRx52V4Utu5dLLjD5bM\r\n" -"xOBC7KU4xZKuMXXZM6/93Yb51K/J4ahf1TxJlTWXtnzDr9saEYdNy2SKY/6ZiDNH\r\n" -"D+stpAKiQLAWaAusIWKYEyw9MQ==\r\n" +"o4GSMIGPMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITBjBgNVHSMEXDBa\r\n" +"gBS0WuSls97SUva51aaVD+s+vMf9/6E/pD0wOzELMAkGA1UEBhMCTkwxETAPBgNV\r\n" +"BAoMCFBvbGFyU1NMMRkwFwYDVQQDDBBQb2xhclNTTCBUZXN0IENBggEAMAkGA1Ud\r\n" +"EwQCMAAwDQYJKoZIhvcNAQELBQADggEBAC7yO786NvcHpK8UovKIG9cB32oSQQom\r\n" +"LoR0eHDRzdqEkoq7yGZufHFiRAAzbMqJfogRtxlrWAeB4y/jGaMBV25IbFOIcH2W\r\n" +"iCEaMMbG+VQLKNvuC63kmw/Zewc9ThM6Pa1Hcy0axT0faf1B/U01j0FIcw/6mTfK\r\n" +"D8w48OIwc1yr0JtutCVjig5DC0yznGMt32RyseOLcUe+lfq005v2PAiCozr5X8rE\r\n" +"ofGZpiM2NqRPePgYy+Vc75Zk28xkRQq1ncprgQb3S4vTsZdScpM9hLf+eMlrgqlj\r\n" +"c5PLSkXBeLE5+fedkyfTaLxxQlgCpuoOhKBm04/R1pWNzUHyqagjO9Q=\r\n" "-----END CERTIFICATE-----\r\n"; +const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa ); const char mbedtls_test_cli_key_rsa[] = "-----BEGIN RSA PRIVATE KEY-----\r\n" @@ -280,28 +323,32 @@ const char mbedtls_test_cli_key_rsa[] = "bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" "8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" "-----END RSA PRIVATE KEY-----\r\n"; - -const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); -const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa ); -const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; -const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); -const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa ); -const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa ); const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa ); -#else -#define TEST_CA_CRT_RSA #endif /* MBEDTLS_RSA_C */ #if defined(MBEDTLS_PEM_PARSE_C) /* Concatenation of all available CA certificates */ -const char mbedtls_test_cas_pem[] = TEST_CA_CRT_RSA TEST_CA_CRT_EC; +const char mbedtls_test_cas_pem[] = +#ifdef TEST_CA_CRT_RSA_SHA1 + TEST_CA_CRT_RSA_SHA1 +#endif +#ifdef TEST_CA_CRT_RSA_SHA256 + TEST_CA_CRT_RSA_SHA256 +#endif +#ifdef TEST_CA_CRT_EC + TEST_CA_CRT_EC +#endif + ""; const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); #endif /* List of all available CA certificates */ const char * mbedtls_test_cas[] = { -#if defined(MBEDTLS_RSA_C) - mbedtls_test_ca_crt_rsa, +#if defined(TEST_CA_CRT_RSA_SHA1) + mbedtls_test_ca_crt_rsa_sha1, +#endif +#if defined(TEST_CA_CRT_RSA_SHA256) + mbedtls_test_ca_crt_rsa_sha256, #endif #if defined(MBEDTLS_ECDSA_C) mbedtls_test_ca_crt_ec, @@ -309,8 +356,11 @@ const char * mbedtls_test_cas[] = { NULL }; const size_t mbedtls_test_cas_len[] = { -#if defined(MBEDTLS_RSA_C) - sizeof( mbedtls_test_ca_crt_rsa ), +#if defined(TEST_CA_CRT_RSA_SHA1) + sizeof( mbedtls_test_ca_crt_rsa_sha1 ), +#endif +#if defined(TEST_CA_CRT_RSA_SHA256) + sizeof( mbedtls_test_ca_crt_rsa_sha256 ), #endif #if defined(MBEDTLS_ECDSA_C) sizeof( mbedtls_test_ca_crt_ec ), @@ -319,7 +369,7 @@ const size_t mbedtls_test_cas_len[] = { }; #if defined(MBEDTLS_RSA_C) -const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa; +const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa; /* SHA1 or SHA256 */ const char *mbedtls_test_ca_key = mbedtls_test_ca_key_rsa; const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_rsa; const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa; @@ -351,7 +401,3 @@ const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec ); #endif /* MBEDTLS_RSA_C */ #endif /* MBEDTLS_CERTS_C */ - -#else - -#endif diff --git a/app/mbedtls/library/cipher.c b/app/mbedtls/library/cipher.c index ccc06850..e9e0b223 100644 --- a/app/mbedtls/library/cipher.c +++ b/app/mbedtls/library/cipher.c @@ -45,13 +45,24 @@ #include "mbedtls/ccm.h" #endif +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) #define MBEDTLS_CIPHER_MODE_STREAM #endif /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } static int supported_init = 0; @@ -127,6 +138,14 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) if( ctx == NULL ) return; +#if defined(MBEDTLS_CMAC_C) + if( ctx->cmac_ctx ) + { + mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); + mbedtls_free( ctx->cmac_ctx ); + } +#endif + if( ctx->cipher_ctx ) ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); @@ -252,6 +271,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i size_t ilen, unsigned char *output, size_t *olen ) { int ret; + size_t block_size = 0; if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) { @@ -259,10 +279,11 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } *olen = 0; + block_size = mbedtls_cipher_get_block_size( ctx ); if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) { - if( ilen != mbedtls_cipher_get_block_size( ctx ) ) + if( ilen != block_size ) return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); *olen = ilen; @@ -285,8 +306,13 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif + if ( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + if( input == output && - ( ctx->unprocessed_len != 0 || ilen % mbedtls_cipher_get_block_size( ctx ) ) ) + ( ctx->unprocessed_len != 0 || ilen % block_size ) ) { return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); } @@ -300,9 +326,9 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i * If there is not enough data for a full block, cache it. */ if( ( ctx->operation == MBEDTLS_DECRYPT && - ilen + ctx->unprocessed_len <= mbedtls_cipher_get_block_size( ctx ) ) || + ilen <= block_size - ctx->unprocessed_len ) || ( ctx->operation == MBEDTLS_ENCRYPT && - ilen + ctx->unprocessed_len < mbedtls_cipher_get_block_size( ctx ) ) ) + ilen < block_size - ctx->unprocessed_len ) ) { memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, ilen ); @@ -314,22 +340,22 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i /* * Process cached data first */ - if( ctx->unprocessed_len != 0 ) + if( 0 != ctx->unprocessed_len ) { - copy_len = mbedtls_cipher_get_block_size( ctx ) - ctx->unprocessed_len; + copy_len = block_size - ctx->unprocessed_len; memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, copy_len ); if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, - ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, + ctx->operation, block_size, ctx->iv, ctx->unprocessed_data, output ) ) ) { return( ret ); } - *olen += mbedtls_cipher_get_block_size( ctx ); - output += mbedtls_cipher_get_block_size( ctx ); + *olen += block_size; + output += block_size; ctx->unprocessed_len = 0; input += copy_len; @@ -341,9 +367,14 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i */ if( 0 != ilen ) { - copy_len = ilen % mbedtls_cipher_get_block_size( ctx ); + if( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + copy_len = ilen % block_size; if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) - copy_len = mbedtls_cipher_get_block_size( ctx ); + copy_len = block_size; memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), copy_len ); diff --git a/app/mbedtls/library/cipher_wrap.c b/app/mbedtls/library/cipher_wrap.c index 814376b7..dc76af8f 100644 --- a/app/mbedtls/library/cipher_wrap.c +++ b/app/mbedtls/library/cipher_wrap.c @@ -178,7 +178,7 @@ static void aes_ctx_free( void *ctx ) mbedtls_free( ctx ); } -static const mbedtls_cipher_base_t aes_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t aes_info = { MBEDTLS_CIPHER_ID_AES, aes_crypt_ecb_wrap, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -199,7 +199,7 @@ static const mbedtls_cipher_base_t aes_info ICACHE_RODATA_ATTR = { aes_ctx_free }; -static const mbedtls_cipher_info_t aes_128_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_128_ecb_info = { MBEDTLS_CIPHER_AES_128_ECB, MBEDTLS_MODE_ECB, 128, @@ -210,7 +210,7 @@ static const mbedtls_cipher_info_t aes_128_ecb_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_192_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_192_ecb_info = { MBEDTLS_CIPHER_AES_192_ECB, MBEDTLS_MODE_ECB, 192, @@ -221,7 +221,7 @@ static const mbedtls_cipher_info_t aes_192_ecb_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_256_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_256_ecb_info = { MBEDTLS_CIPHER_AES_256_ECB, MBEDTLS_MODE_ECB, 256, @@ -233,7 +233,7 @@ static const mbedtls_cipher_info_t aes_256_ecb_info ICACHE_RODATA_ATTR = { }; #if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t aes_128_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_128_cbc_info = { MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MODE_CBC, 128, @@ -244,7 +244,7 @@ static const mbedtls_cipher_info_t aes_128_cbc_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_192_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_192_cbc_info = { MBEDTLS_CIPHER_AES_192_CBC, MBEDTLS_MODE_CBC, 192, @@ -255,7 +255,7 @@ static const mbedtls_cipher_info_t aes_192_cbc_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_256_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_256_cbc_info = { MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MODE_CBC, 256, @@ -268,7 +268,7 @@ static const mbedtls_cipher_info_t aes_256_cbc_info ICACHE_RODATA_ATTR = { #endif /* MBEDTLS_CIPHER_MODE_CBC */ #if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t aes_128_cfb128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_128_cfb128_info = { MBEDTLS_CIPHER_AES_128_CFB128, MBEDTLS_MODE_CFB, 128, @@ -279,7 +279,7 @@ static const mbedtls_cipher_info_t aes_128_cfb128_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_192_cfb128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_192_cfb128_info = { MBEDTLS_CIPHER_AES_192_CFB128, MBEDTLS_MODE_CFB, 192, @@ -290,7 +290,7 @@ static const mbedtls_cipher_info_t aes_192_cfb128_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_256_cfb128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_256_cfb128_info = { MBEDTLS_CIPHER_AES_256_CFB128, MBEDTLS_MODE_CFB, 256, @@ -303,7 +303,7 @@ static const mbedtls_cipher_info_t aes_256_cfb128_info ICACHE_RODATA_ATTR = { #endif /* MBEDTLS_CIPHER_MODE_CFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t aes_128_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_128_ctr_info = { MBEDTLS_CIPHER_AES_128_CTR, MBEDTLS_MODE_CTR, 128, @@ -314,7 +314,7 @@ static const mbedtls_cipher_info_t aes_128_ctr_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_192_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_192_ctr_info = { MBEDTLS_CIPHER_AES_192_CTR, MBEDTLS_MODE_CTR, 192, @@ -325,7 +325,7 @@ static const mbedtls_cipher_info_t aes_192_ctr_info ICACHE_RODATA_ATTR = { &aes_info }; -static const mbedtls_cipher_info_t aes_256_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_256_ctr_info = { MBEDTLS_CIPHER_AES_256_CTR, MBEDTLS_MODE_CTR, 256, @@ -345,7 +345,7 @@ static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, key, key_bitlen ); } -static const mbedtls_cipher_base_t gcm_aes_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t gcm_aes_info = { MBEDTLS_CIPHER_ID_AES, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -366,7 +366,7 @@ static const mbedtls_cipher_base_t gcm_aes_info ICACHE_RODATA_ATTR = { gcm_ctx_free, }; -static const mbedtls_cipher_info_t aes_128_gcm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_128_gcm_info = { MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MODE_GCM, 128, @@ -377,7 +377,7 @@ static const mbedtls_cipher_info_t aes_128_gcm_info ICACHE_RODATA_ATTR = { &gcm_aes_info }; -static const mbedtls_cipher_info_t aes_192_gcm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_192_gcm_info = { MBEDTLS_CIPHER_AES_192_GCM, MBEDTLS_MODE_GCM, 192, @@ -388,7 +388,7 @@ static const mbedtls_cipher_info_t aes_192_gcm_info ICACHE_RODATA_ATTR = { &gcm_aes_info }; -static const mbedtls_cipher_info_t aes_256_gcm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_256_gcm_info = { MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MODE_GCM, 256, @@ -408,7 +408,7 @@ static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, key, key_bitlen ); } -static const mbedtls_cipher_base_t ccm_aes_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t ccm_aes_info = { MBEDTLS_CIPHER_ID_AES, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -429,7 +429,7 @@ static const mbedtls_cipher_base_t ccm_aes_info ICACHE_RODATA_ATTR = { ccm_ctx_free, }; -static const mbedtls_cipher_info_t aes_128_ccm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_128_ccm_info = { MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MODE_CCM, 128, @@ -440,7 +440,7 @@ static const mbedtls_cipher_info_t aes_128_ccm_info ICACHE_RODATA_ATTR = { &ccm_aes_info }; -static const mbedtls_cipher_info_t aes_192_ccm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_192_ccm_info = { MBEDTLS_CIPHER_AES_192_CCM, MBEDTLS_MODE_CCM, 192, @@ -451,7 +451,7 @@ static const mbedtls_cipher_info_t aes_192_ccm_info ICACHE_RODATA_ATTR = { &ccm_aes_info }; -static const mbedtls_cipher_info_t aes_256_ccm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t aes_256_ccm_info = { MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MODE_CCM, 256, @@ -535,7 +535,7 @@ static void camellia_ctx_free( void *ctx ) mbedtls_free( ctx ); } -static const mbedtls_cipher_base_t camellia_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t camellia_info = { MBEDTLS_CIPHER_ID_CAMELLIA, camellia_crypt_ecb_wrap, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -556,7 +556,7 @@ static const mbedtls_cipher_base_t camellia_info ICACHE_RODATA_ATTR = { camellia_ctx_free }; -static const mbedtls_cipher_info_t camellia_128_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_128_ecb_info = { MBEDTLS_CIPHER_CAMELLIA_128_ECB, MBEDTLS_MODE_ECB, 128, @@ -567,7 +567,7 @@ static const mbedtls_cipher_info_t camellia_128_ecb_info ICACHE_RODATA_ATTR = { &camellia_info }; -static const mbedtls_cipher_info_t camellia_192_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_192_ecb_info = { MBEDTLS_CIPHER_CAMELLIA_192_ECB, MBEDTLS_MODE_ECB, 192, @@ -578,7 +578,7 @@ static const mbedtls_cipher_info_t camellia_192_ecb_info ICACHE_RODATA_ATTR = { &camellia_info }; -static const mbedtls_cipher_info_t camellia_256_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_256_ecb_info = { MBEDTLS_CIPHER_CAMELLIA_256_ECB, MBEDTLS_MODE_ECB, 256, @@ -590,7 +590,7 @@ static const mbedtls_cipher_info_t camellia_256_ecb_info ICACHE_RODATA_ATTR = { }; #if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t camellia_128_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_128_cbc_info = { MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MODE_CBC, 128, @@ -601,7 +601,7 @@ static const mbedtls_cipher_info_t camellia_128_cbc_info ICACHE_RODATA_ATTR = { &camellia_info }; -static const mbedtls_cipher_info_t camellia_192_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_192_cbc_info = { MBEDTLS_CIPHER_CAMELLIA_192_CBC, MBEDTLS_MODE_CBC, 192, @@ -612,7 +612,7 @@ static const mbedtls_cipher_info_t camellia_192_cbc_info ICACHE_RODATA_ATTR = { &camellia_info }; -static const mbedtls_cipher_info_t camellia_256_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_256_cbc_info = { MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MODE_CBC, 256, @@ -625,7 +625,7 @@ static const mbedtls_cipher_info_t camellia_256_cbc_info ICACHE_RODATA_ATTR = { #endif /* MBEDTLS_CIPHER_MODE_CBC */ #if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t camellia_128_cfb128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, MBEDTLS_MODE_CFB, 128, @@ -636,7 +636,7 @@ static const mbedtls_cipher_info_t camellia_128_cfb128_info ICACHE_RODATA_ATTR = &camellia_info }; -static const mbedtls_cipher_info_t camellia_192_cfb128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, MBEDTLS_MODE_CFB, 192, @@ -647,7 +647,7 @@ static const mbedtls_cipher_info_t camellia_192_cfb128_info ICACHE_RODATA_ATTR = &camellia_info }; -static const mbedtls_cipher_info_t camellia_256_cfb128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, MBEDTLS_MODE_CFB, 256, @@ -660,7 +660,7 @@ static const mbedtls_cipher_info_t camellia_256_cfb128_info ICACHE_RODATA_ATTR = #endif /* MBEDTLS_CIPHER_MODE_CFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t camellia_128_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_128_ctr_info = { MBEDTLS_CIPHER_CAMELLIA_128_CTR, MBEDTLS_MODE_CTR, 128, @@ -671,7 +671,7 @@ static const mbedtls_cipher_info_t camellia_128_ctr_info ICACHE_RODATA_ATTR = { &camellia_info }; -static const mbedtls_cipher_info_t camellia_192_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_192_ctr_info = { MBEDTLS_CIPHER_CAMELLIA_192_CTR, MBEDTLS_MODE_CTR, 192, @@ -682,7 +682,7 @@ static const mbedtls_cipher_info_t camellia_192_ctr_info ICACHE_RODATA_ATTR = { &camellia_info }; -static const mbedtls_cipher_info_t camellia_256_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_256_ctr_info = { MBEDTLS_CIPHER_CAMELLIA_256_CTR, MBEDTLS_MODE_CTR, 256, @@ -702,7 +702,7 @@ static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, key, key_bitlen ); } -static const mbedtls_cipher_base_t gcm_camellia_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t gcm_camellia_info = { MBEDTLS_CIPHER_ID_CAMELLIA, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -723,7 +723,7 @@ static const mbedtls_cipher_base_t gcm_camellia_info ICACHE_RODATA_ATTR = { gcm_ctx_free, }; -static const mbedtls_cipher_info_t camellia_128_gcm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_128_gcm_info = { MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MODE_GCM, 128, @@ -734,7 +734,7 @@ static const mbedtls_cipher_info_t camellia_128_gcm_info ICACHE_RODATA_ATTR = { &gcm_camellia_info }; -static const mbedtls_cipher_info_t camellia_192_gcm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_192_gcm_info = { MBEDTLS_CIPHER_CAMELLIA_192_GCM, MBEDTLS_MODE_GCM, 192, @@ -745,7 +745,7 @@ static const mbedtls_cipher_info_t camellia_192_gcm_info ICACHE_RODATA_ATTR = { &gcm_camellia_info }; -static const mbedtls_cipher_info_t camellia_256_gcm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_256_gcm_info = { MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MODE_GCM, 256, @@ -765,7 +765,7 @@ static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, key, key_bitlen ); } -static const mbedtls_cipher_base_t ccm_camellia_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t ccm_camellia_info = { MBEDTLS_CIPHER_ID_CAMELLIA, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -786,7 +786,7 @@ static const mbedtls_cipher_base_t ccm_camellia_info ICACHE_RODATA_ATTR = { ccm_ctx_free, }; -static const mbedtls_cipher_info_t camellia_128_ccm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_128_ccm_info = { MBEDTLS_CIPHER_CAMELLIA_128_CCM, MBEDTLS_MODE_CCM, 128, @@ -797,7 +797,7 @@ static const mbedtls_cipher_info_t camellia_128_ccm_info ICACHE_RODATA_ATTR = { &ccm_camellia_info }; -static const mbedtls_cipher_info_t camellia_192_ccm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_192_ccm_info = { MBEDTLS_CIPHER_CAMELLIA_192_CCM, MBEDTLS_MODE_CCM, 192, @@ -808,7 +808,7 @@ static const mbedtls_cipher_info_t camellia_192_ccm_info ICACHE_RODATA_ATTR = { &ccm_camellia_info }; -static const mbedtls_cipher_info_t camellia_256_ccm_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t camellia_256_ccm_info = { MBEDTLS_CIPHER_CAMELLIA_256_CCM, MBEDTLS_MODE_CCM, 256, @@ -941,7 +941,7 @@ static void des3_ctx_free( void *ctx ) mbedtls_free( ctx ); } -static const mbedtls_cipher_base_t des_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t des_info = { MBEDTLS_CIPHER_ID_DES, des_crypt_ecb_wrap, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -962,7 +962,7 @@ static const mbedtls_cipher_base_t des_info ICACHE_RODATA_ATTR = { des_ctx_free }; -static const mbedtls_cipher_info_t des_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t des_ecb_info = { MBEDTLS_CIPHER_DES_ECB, MBEDTLS_MODE_ECB, MBEDTLS_KEY_LENGTH_DES, @@ -974,7 +974,7 @@ static const mbedtls_cipher_info_t des_ecb_info ICACHE_RODATA_ATTR = { }; #if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t des_cbc_info = { MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MODE_CBC, MBEDTLS_KEY_LENGTH_DES, @@ -986,7 +986,7 @@ static const mbedtls_cipher_info_t des_cbc_info ICACHE_RODATA_ATTR = { }; #endif /* MBEDTLS_CIPHER_MODE_CBC */ -static const mbedtls_cipher_base_t des_ede_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t des_ede_info = { MBEDTLS_CIPHER_ID_DES, des3_crypt_ecb_wrap, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1007,7 +1007,7 @@ static const mbedtls_cipher_base_t des_ede_info ICACHE_RODATA_ATTR = { des3_ctx_free }; -static const mbedtls_cipher_info_t des_ede_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t des_ede_ecb_info = { MBEDTLS_CIPHER_DES_EDE_ECB, MBEDTLS_MODE_ECB, MBEDTLS_KEY_LENGTH_DES_EDE, @@ -1019,7 +1019,7 @@ static const mbedtls_cipher_info_t des_ede_ecb_info ICACHE_RODATA_ATTR = { }; #if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t des_ede_cbc_info = { MBEDTLS_CIPHER_DES_EDE_CBC, MBEDTLS_MODE_CBC, MBEDTLS_KEY_LENGTH_DES_EDE, @@ -1031,7 +1031,7 @@ static const mbedtls_cipher_info_t des_ede_cbc_info ICACHE_RODATA_ATTR = { }; #endif /* MBEDTLS_CIPHER_MODE_CBC */ -static const mbedtls_cipher_base_t des_ede3_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t des_ede3_info = { MBEDTLS_CIPHER_ID_3DES, des3_crypt_ecb_wrap, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1052,7 +1052,7 @@ static const mbedtls_cipher_base_t des_ede3_info ICACHE_RODATA_ATTR = { des3_ctx_free }; -static const mbedtls_cipher_info_t des_ede3_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t des_ede3_ecb_info = { MBEDTLS_CIPHER_DES_EDE3_ECB, MBEDTLS_MODE_ECB, MBEDTLS_KEY_LENGTH_DES_EDE3, @@ -1063,7 +1063,7 @@ static const mbedtls_cipher_info_t des_ede3_ecb_info ICACHE_RODATA_ATTR = { &des_ede3_info }; #if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t des_ede3_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t des_ede3_cbc_info = { MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MODE_CBC, MBEDTLS_KEY_LENGTH_DES_EDE3, @@ -1140,7 +1140,7 @@ static void blowfish_ctx_free( void *ctx ) mbedtls_free( ctx ); } -static const mbedtls_cipher_base_t blowfish_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t blowfish_info = { MBEDTLS_CIPHER_ID_BLOWFISH, blowfish_crypt_ecb_wrap, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1161,7 +1161,7 @@ static const mbedtls_cipher_base_t blowfish_info ICACHE_RODATA_ATTR = { blowfish_ctx_free }; -static const mbedtls_cipher_info_t blowfish_ecb_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t blowfish_ecb_info = { MBEDTLS_CIPHER_BLOWFISH_ECB, MBEDTLS_MODE_ECB, 128, @@ -1173,7 +1173,7 @@ static const mbedtls_cipher_info_t blowfish_ecb_info ICACHE_RODATA_ATTR = { }; #if defined(MBEDTLS_CIPHER_MODE_CBC) -static const mbedtls_cipher_info_t blowfish_cbc_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t blowfish_cbc_info = { MBEDTLS_CIPHER_BLOWFISH_CBC, MBEDTLS_MODE_CBC, 128, @@ -1186,7 +1186,7 @@ static const mbedtls_cipher_info_t blowfish_cbc_info ICACHE_RODATA_ATTR = { #endif /* MBEDTLS_CIPHER_MODE_CBC */ #if defined(MBEDTLS_CIPHER_MODE_CFB) -static const mbedtls_cipher_info_t blowfish_cfb64_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t blowfish_cfb64_info = { MBEDTLS_CIPHER_BLOWFISH_CFB64, MBEDTLS_MODE_CFB, 128, @@ -1199,7 +1199,7 @@ static const mbedtls_cipher_info_t blowfish_cfb64_info ICACHE_RODATA_ATTR = { #endif /* MBEDTLS_CIPHER_MODE_CFB */ #if defined(MBEDTLS_CIPHER_MODE_CTR) -static const mbedtls_cipher_info_t blowfish_ctr_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t blowfish_ctr_info = { MBEDTLS_CIPHER_BLOWFISH_CTR, MBEDTLS_MODE_CTR, 128, @@ -1250,7 +1250,7 @@ static void arc4_ctx_free( void *ctx ) mbedtls_free( ctx ); } -static const mbedtls_cipher_base_t arc4_base_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t arc4_base_info = { MBEDTLS_CIPHER_ID_ARC4, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1271,7 +1271,7 @@ static const mbedtls_cipher_base_t arc4_base_info ICACHE_RODATA_ATTR = { arc4_ctx_free }; -static const mbedtls_cipher_info_t arc4_128_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t arc4_128_info = { MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MODE_STREAM, 128, @@ -1313,7 +1313,7 @@ static void null_ctx_free( void *ctx ) ((void) ctx); } -static const mbedtls_cipher_base_t null_base_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_base_t null_base_info = { MBEDTLS_CIPHER_ID_NULL, NULL, #if defined(MBEDTLS_CIPHER_MODE_CBC) @@ -1334,7 +1334,7 @@ static const mbedtls_cipher_base_t null_base_info ICACHE_RODATA_ATTR = { null_ctx_free }; -static const mbedtls_cipher_info_t null_cipher_info ICACHE_RODATA_ATTR = { +static const mbedtls_cipher_info_t null_cipher_info = { MBEDTLS_CIPHER_NULL, MBEDTLS_MODE_STREAM, 0, @@ -1346,7 +1346,7 @@ static const mbedtls_cipher_info_t null_cipher_info ICACHE_RODATA_ATTR = { }; #endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ -const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] ICACHE_RODATA_ATTR = +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = { #if defined(MBEDTLS_AES_C) { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, diff --git a/app/mbedtls/library/cmac.c b/app/mbedtls/library/cmac.c new file mode 100644 index 00000000..6df56aa9 --- /dev/null +++ b/app/mbedtls/library/cmac.c @@ -0,0 +1,1074 @@ +/** + * \file cmac.c + * + * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES + * + * 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) + */ + +/* + * References: + * + * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The + * CMAC Mode for Authentication + * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf + * + * - RFC 4493 - The AES-CMAC Algorithm + * https://tools.ietf.org/html/rfc4493 + * + * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message + * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) + * Algorithm for the Internet Key Exchange Protocol (IKE) + * https://tools.ietf.org/html/rfc4615 + * + * Additional test vectors: ISO/IEC 9797-1 + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CMAC_C) + +#include "mbedtls/cmac.h" + +#include + + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#if defined(MBEDTLS_SELF_TEST) +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_SELF_TEST */ +#endif /* MBEDTLS_PLATFORM_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * Multiplication by u in the Galois field of GF(2^n) + * + * As explained in NIST SP 800-38B, this can be computed: + * + * If MSB(p) = 0, then p = (p << 1) + * If MSB(p) = 1, then p = (p << 1) ^ R_n + * with R_64 = 0x1B and R_128 = 0x87 + * + * Input and output MUST NOT point to the same buffer + * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. + */ +static int cmac_multiply_by_u( unsigned char *output, + const unsigned char *input, + size_t blocksize ) +{ + const unsigned char R_128 = 0x87; + const unsigned char R_64 = 0x1B; + unsigned char R_n, mask; + unsigned char overflow = 0x00; + int i; + + if( blocksize == MBEDTLS_AES_BLOCK_SIZE ) + { + R_n = R_128; + } + else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE ) + { + R_n = R_64; + } + else + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + for( i = (int)blocksize - 1; i >= 0; i-- ) + { + output[i] = input[i] << 1 | overflow; + overflow = input[i] >> 7; + } + + /* mask = ( input[0] >> 7 ) ? 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 = - ( input[0] >> 7 ); +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + + output[ blocksize - 1 ] ^= R_n & mask; + + return( 0 ); +} + +/* + * Generate subkeys + * + * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm + */ +static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, + unsigned char* K1, unsigned char* K2 ) +{ + int ret; + unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; + size_t olen, block_size; + + mbedtls_zeroize( L, sizeof( L ) ); + + block_size = ctx->cipher_info->block_size; + + /* Calculate Ek(0) */ + if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 ) + goto exit; + + /* + * Generate K1 and K2 + */ + if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 ) + goto exit; + + if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 ) + goto exit; + +exit: + mbedtls_zeroize( L, sizeof( L ) ); + + return( ret ); +} + +static void cmac_xor_block( unsigned char *output, const unsigned char *input1, + const unsigned char *input2, + const size_t block_size ) +{ + size_t idx; + + for( idx = 0; idx < block_size; idx++ ) + output[ idx ] = input1[ idx ] ^ input2[ idx ]; +} + +/* + * Create padded last block from (partial) last block. + * + * We can't use the padding option from the cipher layer, as it only works for + * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. + */ +static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX], + size_t padded_block_len, + const unsigned char *last_block, + size_t last_block_len ) +{ + size_t j; + + for( j = 0; j < padded_block_len; j++ ) + { + if( j < last_block_len ) + padded_block[j] = last_block[j]; + else if( j == last_block_len ) + padded_block[j] = 0x80; + else + padded_block[j] = 0x00; + } +} + +int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, + const unsigned char *key, size_t keybits ) +{ + mbedtls_cipher_type_t type; + mbedtls_cmac_context_t *cmac_ctx; + int retval; + + if( ctx == NULL || ctx->cipher_info == NULL || key == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + return( retval ); + + type = ctx->cipher_info->type; + + switch( type ) + { + case MBEDTLS_CIPHER_AES_128_ECB: + case MBEDTLS_CIPHER_AES_192_ECB: + case MBEDTLS_CIPHER_AES_256_ECB: + case MBEDTLS_CIPHER_DES_EDE3_ECB: + break; + default: + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + /* Allocated and initialise in the cipher context memory for the CMAC + * context */ + cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) ); + if( cmac_ctx == NULL ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cmac_ctx = cmac_ctx; + + mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); + + return 0; +} + +int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, + const unsigned char *input, size_t ilen ) +{ + mbedtls_cmac_context_t* cmac_ctx; + unsigned char *state; + int ret = 0; + size_t n, j, olen, block_size; + + if( ctx == NULL || ctx->cipher_info == NULL || input == NULL || + ctx->cmac_ctx == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cmac_ctx = ctx->cmac_ctx; + block_size = ctx->cipher_info->block_size; + state = ctx->cmac_ctx->state; + + /* Is there data still to process from the last call, that's greater in + * size than a block? */ + if( cmac_ctx->unprocessed_len > 0 && + ilen > block_size - cmac_ctx->unprocessed_len ) + { + memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], + input, + block_size - cmac_ctx->unprocessed_len ); + + cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); + + if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, + &olen ) ) != 0 ) + { + goto exit; + } + + input += block_size - cmac_ctx->unprocessed_len; + ilen -= block_size - cmac_ctx->unprocessed_len; + cmac_ctx->unprocessed_len = 0; + } + + /* n is the number of blocks including any final partial block */ + n = ( ilen + block_size - 1 ) / block_size; + + /* Iterate across the input data in block sized chunks, excluding any + * final partial or complete block */ + for( j = 1; j < n; j++ ) + { + cmac_xor_block( state, input, state, block_size ); + + if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, + &olen ) ) != 0 ) + goto exit; + + ilen -= block_size; + input += block_size; + } + + /* If there is data left over that wasn't aligned to a block */ + if( ilen > 0 ) + { + memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], + input, + ilen ); + cmac_ctx->unprocessed_len += ilen; + } + +exit: + return( ret ); +} + +int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output ) +{ + mbedtls_cmac_context_t* cmac_ctx; + unsigned char *state, *last_block; + unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; + unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; + unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX]; + int ret; + size_t olen, block_size; + + if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || + output == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cmac_ctx = ctx->cmac_ctx; + block_size = ctx->cipher_info->block_size; + state = cmac_ctx->state; + + mbedtls_zeroize( K1, sizeof( K1 ) ); + mbedtls_zeroize( K2, sizeof( K2 ) ); + cmac_generate_subkeys( ctx, K1, K2 ); + + last_block = cmac_ctx->unprocessed_block; + + /* Calculate last block */ + if( cmac_ctx->unprocessed_len < block_size ) + { + cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); + cmac_xor_block( M_last, M_last, K2, block_size ); + } + else + { + /* Last block is complete block */ + cmac_xor_block( M_last, last_block, K1, block_size ); + } + + + cmac_xor_block( state, M_last, state, block_size ); + if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, + &olen ) ) != 0 ) + { + goto exit; + } + + memcpy( output, state, block_size ); + +exit: + /* Wipe the generated keys on the stack, and any other transients to avoid + * side channel leakage */ + mbedtls_zeroize( K1, sizeof( K1 ) ); + mbedtls_zeroize( K2, sizeof( K2 ) ); + + cmac_ctx->unprocessed_len = 0; + mbedtls_zeroize( cmac_ctx->unprocessed_block, + sizeof( cmac_ctx->unprocessed_block ) ); + + mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); + return( ret ); +} + +int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) +{ + mbedtls_cmac_context_t* cmac_ctx; + + if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cmac_ctx = ctx->cmac_ctx; + + /* Reset the internal state */ + cmac_ctx->unprocessed_len = 0; + mbedtls_zeroize( cmac_ctx->unprocessed_block, + sizeof( cmac_ctx->unprocessed_block ) ); + mbedtls_zeroize( cmac_ctx->state, + sizeof( cmac_ctx->state ) ); + + return( 0 ); +} + +int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, + const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_cipher_context_t ctx; + int ret; + + if( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_cipher_init( &ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_update( &ctx, input, ilen ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_finish( &ctx, output ); + +exit: + mbedtls_cipher_free( &ctx ); + + return( ret ); +} + +#if defined(MBEDTLS_AES_C) +/* + * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 + */ +int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, + const unsigned char *input, size_t in_len, + unsigned char *output ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; + unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; + + if( key == NULL || input == NULL || output == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB ); + if( cipher_info == NULL ) + { + /* Failing at this point must be due to a build issue */ + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto exit; + } + + if( key_length == MBEDTLS_AES_BLOCK_SIZE ) + { + /* Use key as is */ + memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); + } + else + { + memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); + + ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, + key_length, int_key ); + if( ret != 0 ) + goto exit; + } + + ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len, + output ); + +exit: + mbedtls_zeroize( int_key, sizeof( int_key ) ); + + return( ret ); +} +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * CMAC test data for SP800-38B + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf + * + * AES-CMAC-PRF-128 test data from RFC 4615 + * https://tools.ietf.org/html/rfc4615#page-4 + */ + +#define NB_CMAC_TESTS_PER_KEY 4 +#define NB_PRF_TESTS 3 + +#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) +/* All CMAC test inputs are truncated from the same 64 byte buffer. */ +static const unsigned char test_message[] = { + /* PT */ + 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 +}; +#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) +/* Truncation point of message for AES CMAC tests */ +static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { + /* Mlen */ + 0, + 16, + 20, + 64 +}; + +/* CMAC-AES128 Test Data */ +static const unsigned char aes_128_key[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +}; +static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* K1 */ + 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, + 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde + }, + { + /* K2 */ + 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, + 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b + } +}; +static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* Example #1 */ + 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, + 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 + }, + { + /* Example #2 */ + 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c + }, + { + /* Example #3 */ + 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, + 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde + }, + { + /* Example #4 */ + 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, + 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe + } +}; + +/* CMAC-AES192 Test Data */ +static const unsigned char aes_192_key[24] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b +}; +static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* K1 */ + 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, + 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 + }, + { + /* K2 */ + 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, + 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c + } +}; +static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* Example #1 */ + 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, + 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 + }, + { + /* Example #2 */ + 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, + 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 + }, + { + /* Example #3 */ + 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, + 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 + }, + { + /* Example #4 */ + 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, + 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 + } +}; + +/* CMAC-AES256 Test Data */ +static const unsigned char aes_256_key[32] = { + 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_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* K1 */ + 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, + 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f + }, + { + /* K2 */ + 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, + 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 + } +}; +static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* Example #1 */ + 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, + 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 + }, + { + /* Example #2 */ + 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, + 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c + }, + { + /* Example #3 */ + 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, + 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 + }, + { + /* Example #4 */ + 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, + 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 + } +}; +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_DES_C) +/* Truncation point of message for 3DES CMAC tests */ +static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { + 0, + 16, + 20, + 32 +}; + +/* CMAC-TDES (Generation) - 2 Key Test Data */ +static const unsigned char des3_2key_key[24] = { + /* Key1 */ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + /* Key2 */ + 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, + /* Key3 */ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef +}; +static const unsigned char des3_2key_subkeys[2][8] = { + { + /* K1 */ + 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 + }, + { + /* K2 */ + 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 + } +}; +static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { + { + /* Sample #1 */ + 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 + }, + { + /* Sample #2 */ + 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b + }, + { + /* Sample #3 */ + 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 + }, + { + /* Sample #4 */ + 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb + } +}; + +/* CMAC-TDES (Generation) - 3 Key Test Data */ +static const unsigned char des3_3key_key[24] = { + /* Key1 */ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, + /* Key2 */ + 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, + /* Key3 */ + 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 +}; +static const unsigned char des3_3key_subkeys[2][8] = { + { + /* K1 */ + 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 + }, + { + /* K2 */ + 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b + } +}; +static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { + { + /* Sample #1 */ + 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 + }, + { + /* Sample #2 */ + 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 + }, + { + /* Sample #3 */ + 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 + }, + { + /* Sample #4 */ + 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 + } +}; + +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) +/* AES AES-CMAC-PRF-128 Test Data */ +static const unsigned char PRFK[] = { + /* Key */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xed, 0xcb +}; + +/* Sizes in bytes */ +static const size_t PRFKlen[NB_PRF_TESTS] = { + 18, + 16, + 10 +}; + +/* Message */ +static const unsigned char PRFM[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char PRFT[NB_PRF_TESTS][16] = { + { + 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, + 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a + }, + { + 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, + 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d + }, + { + 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, + 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d + } +}; +#endif /* MBEDTLS_AES_C */ + +static int cmac_test_subkeys( int verbose, + const char* testname, + const unsigned char* key, + int keybits, + const unsigned char* subkeys, + mbedtls_cipher_type_t cipher_type, + int block_size, + int num_tests ) +{ + int i, ret; + mbedtls_cipher_context_t ctx; + const mbedtls_cipher_info_t *cipher_info; + unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; + unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; + + cipher_info = mbedtls_cipher_info_from_type( cipher_type ); + if( cipher_info == NULL ) + { + /* Failing at this point must be due to a build issue */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + for( i = 0; i < num_tests; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 ); + + mbedtls_cipher_init( &ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "test execution failed\n" ); + + goto cleanup; + } + + if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "test execution failed\n" ); + + goto cleanup; + } + + ret = cmac_generate_subkeys( &ctx, K1, K2 ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + goto cleanup; + } + + if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 || + ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + goto cleanup; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_cipher_free( &ctx ); + } + + goto exit; + +cleanup: + mbedtls_cipher_free( &ctx ); + +exit: + return( ret ); +} + +static int cmac_test_wth_cipher( int verbose, + const char* testname, + const unsigned char* key, + int keybits, + const unsigned char* messages, + const unsigned int message_lengths[4], + const unsigned char* expected_result, + mbedtls_cipher_type_t cipher_type, + int block_size, + int num_tests ) +{ + const mbedtls_cipher_info_t *cipher_info; + int i, ret; + unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; + + cipher_info = mbedtls_cipher_info_from_type( cipher_type ); + if( cipher_info == NULL ) + { + /* Failing at this point must be due to a build issue */ + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto exit; + } + + for( i = 0; i < num_tests; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 ); + + if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages, + message_lengths[i], output ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + goto exit; + } + + if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + +exit: + return( ret ); +} + +#if defined(MBEDTLS_AES_C) +static int test_aes128_cmac_prf( int verbose ) +{ + int i; + int ret; + unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; + + for( i = 0; i < NB_PRF_TESTS; i++ ) + { + mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); + ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); + if( ret != 0 || + memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) + { + + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); + } + else if( verbose != 0 ) + { + mbedtls_printf( "passed\n" ); + } + } + return( ret ); +} +#endif /* MBEDTLS_AES_C */ + +int mbedtls_cmac_self_test( int verbose ) +{ + int ret; + +#if defined(MBEDTLS_AES_C) + /* AES-128 */ + if( ( ret = cmac_test_subkeys( verbose, + "AES 128", + aes_128_key, + 128, + (const unsigned char*)aes_128_subkeys, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "AES 128", + aes_128_key, + 128, + test_message, + aes_message_lengths, + (const unsigned char*)aes_128_expected_result, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + /* AES-192 */ + if( ( ret = cmac_test_subkeys( verbose, + "AES 192", + aes_192_key, + 192, + (const unsigned char*)aes_192_subkeys, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "AES 192", + aes_192_key, + 192, + test_message, + aes_message_lengths, + (const unsigned char*)aes_192_expected_result, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + /* AES-256 */ + if( ( ret = cmac_test_subkeys( verbose, + "AES 256", + aes_256_key, + 256, + (const unsigned char*)aes_256_subkeys, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher ( verbose, + "AES 256", + aes_256_key, + 256, + test_message, + aes_message_lengths, + (const unsigned char*)aes_256_expected_result, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_DES_C) + /* 3DES 2 key */ + if( ( ret = cmac_test_subkeys( verbose, + "3DES 2 key", + des3_2key_key, + 192, + (const unsigned char*)des3_2key_subkeys, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "3DES 2 key", + des3_2key_key, + 192, + test_message, + des3_message_lengths, + (const unsigned char*)des3_2key_expected_result, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + /* 3DES 3 key */ + if( ( ret = cmac_test_subkeys( verbose, + "3DES 3 key", + des3_3key_key, + 192, + (const unsigned char*)des3_3key_subkeys, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "3DES 3 key", + des3_3key_key, + 192, + test_message, + des3_message_lengths, + (const unsigned char*)des3_3key_expected_result, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) + if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 ) + return( ret ); +#endif /* MBEDTLS_AES_C */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_CMAC_C */ diff --git a/app/mbedtls/library/ctr_drbg.c b/app/mbedtls/library/ctr_drbg.c index aefddfa1..55612c7f 100644 --- a/app/mbedtls/library/ctr_drbg.c +++ b/app/mbedtls/library/ctr_drbg.c @@ -67,8 +67,8 @@ void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) } /* - * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST - * tests to succeed (which require known length fixed entropy) + * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow + * NIST tests to succeed (which require known length fixed entropy) */ int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *ctx, @@ -290,7 +290,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; size_t seedlen = 0; - if( ctx->entropy_len + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) + if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); diff --git a/app/mbedtls/library/debug.c b/app/mbedtls/library/debug.c index 4752ab1a..7b47c852 100644 --- a/app/mbedtls/library/debug.c +++ b/app/mbedtls/library/debug.c @@ -27,21 +27,22 @@ #if defined(MBEDTLS_DEBUG_C) -#include "mbedtls/debug.h" - -#include -#include -#include - #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else #include #define mbedtls_calloc calloc #define mbedtls_free free +#define mbedtls_time_t time_t #define mbedtls_snprintf snprintf #endif +#include "mbedtls/debug.h" + +#include +#include +#include + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -70,7 +71,7 @@ static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level, */ #if defined(MBEDTLS_THREADING_C) char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ - mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", ssl, str ); + mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str ); ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr ); #else ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str ); @@ -85,7 +86,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, char str[DEBUG_BUF_SIZE]; int ret; - if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold ) return; va_start( argp, format ); @@ -101,7 +102,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, } #endif #else - ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); + ret = mbedtls_vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); #endif va_end( argp ); diff --git a/app/mbedtls/library/des.c b/app/mbedtls/library/des.c index 61f214af..09f95cfc 100644 --- a/app/mbedtls/library/des.c +++ b/app/mbedtls/library/des.c @@ -50,7 +50,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } /* diff --git a/app/mbedtls/library/dhm.c b/app/mbedtls/library/dhm.c index 0f4d3164..bec52a11 100644 --- a/app/mbedtls/library/dhm.c +++ b/app/mbedtls/library/dhm.c @@ -19,9 +19,12 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ /* - * Reference: + * The following sources were referenced in the design of this implementation + * of the Diffie-Hellman-Merkle algorithm: + * + * [1] Handbook of Applied Cryptography - 1997, Chapter 12 + * Menezes, van Oorschot and Vanstone * - * http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12) */ #if !defined(MBEDTLS_CONFIG_FILE) @@ -162,7 +165,7 @@ int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, */ do { - mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); @@ -248,7 +251,7 @@ int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, */ do { - mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) ); while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); @@ -321,7 +324,7 @@ static int dhm_update_blinding( mbedtls_dhm_context *ctx, count = 0; do { - mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ); + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) ); while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) ); diff --git a/app/mbedtls/library/ecp.c b/app/mbedtls/library/ecp.c index 19bb4882..5ad68639 100644 --- a/app/mbedtls/library/ecp.c +++ b/app/mbedtls/library/ecp.c @@ -49,9 +49,12 @@ #if defined(MBEDTLS_ECP_C) #include "mbedtls/ecp.h" +#include "mbedtls/threading.h" #include +#if !defined(MBEDTLS_ECP_ALT) + #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else @@ -62,6 +65,8 @@ #define mbedtls_free free #endif +#include "mbedtls/ecp_internal.h" + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -748,6 +753,12 @@ static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ) return( 0 ); +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_jac( grp, pt ); + } +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); /* @@ -796,6 +807,13 @@ static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, if( t_len < 2 ) return( ecp_normalize_jac( grp, *T ) ); +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_jac_many(grp, T, t_len); + } +#endif + if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL ) return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); @@ -912,6 +930,13 @@ static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, dbl_count++; #endif +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_double_jac( grp, R, P ); + } +#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ + mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); /* Special case for A = -3 */ @@ -1003,6 +1028,13 @@ static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, add_count++; #endif +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_add_mixed( grp, R, P, Q ); + } +#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ + /* * Trivial cases: P == 0 or Q == 0 (case 1) */ @@ -1080,15 +1112,23 @@ static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *p { int ret; mbedtls_mpi l, ll; - size_t p_size = ( grp->pbits + 7 ) / 8; + size_t p_size; int count = 0; +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ); + } +#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ + + p_size = ( grp->pbits + 7 ) / 8; mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll ); /* Generate l such that 1 < l < p */ do { - mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ); + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); @@ -1234,6 +1274,7 @@ static int ecp_precompute_comb( const mbedtls_ecp_group *grp, MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); cleanup: + return( ret ); } @@ -1297,6 +1338,7 @@ static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R } cleanup: + mbedtls_ecp_point_free( &Txi ); return( ret ); @@ -1441,6 +1483,13 @@ static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P { int ret; +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_mxz( grp, P ); + } +#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); @@ -1462,15 +1511,23 @@ static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P { int ret; mbedtls_mpi l; - size_t p_size = ( grp->pbits + 7 ) / 8; + size_t p_size; int count = 0; +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ); + } +#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ + + p_size = ( grp->pbits + 7 ) / 8; mbedtls_mpi_init( &l ); /* Generate l such that 1 < l < p */ do { - mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ); + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ) ); while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); @@ -1512,6 +1569,13 @@ static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, int ret; mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ); + } +#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ + mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C ); mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB ); @@ -1612,7 +1676,10 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { - int ret; + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif /* Common sanity checks */ if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 ) @@ -1622,15 +1689,33 @@ int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, ( ret = mbedtls_ecp_check_pubkey( grp, P ) ) != 0 ) return( ret ); +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ #if defined(ECP_MONTGOMERY) if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) - return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); + ret = ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ); + #endif #if defined(ECP_SHORTWEIERSTRASS) if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) - return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) ); + ret = ecp_mul_comb( grp, R, m, P, f_rng, p_rng ); + #endif - return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +cleanup: + + if ( is_grp_capable ) + { + mbedtls_internal_ecp_free( grp ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + return( ret ); } #if defined(ECP_SHORTWEIERSTRASS) @@ -1723,6 +1808,9 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, { int ret; mbedtls_ecp_point mP; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); @@ -1732,10 +1820,25 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) ); +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); cleanup: + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable ) + { + mbedtls_internal_ecp_free( grp ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ mbedtls_ecp_point_free( &mP ); return( ret ); @@ -1827,7 +1930,9 @@ int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, /* [M225] page 5 */ size_t b; - MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); + do { + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); + } while( mbedtls_mpi_bitlen( d ) == 0); /* Make sure the most significant bit is nbits */ b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */ @@ -2087,4 +2192,6 @@ cleanup: #endif /* MBEDTLS_SELF_TEST */ +#endif /* !MBEDTLS_ECP_ALT */ + #endif /* MBEDTLS_ECP_C */ diff --git a/app/mbedtls/library/ecp_curves.c b/app/mbedtls/library/ecp_curves.c index 9a6e8eb1..df5ac3ee 100644 --- a/app/mbedtls/library/ecp_curves.c +++ b/app/mbedtls/library/ecp_curves.c @@ -31,6 +31,8 @@ #include +#if !defined(MBEDTLS_ECP_ALT) + #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ !defined(inline) && !defined(__cplusplus) #define inline __inline @@ -1213,7 +1215,7 @@ static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t int ret; size_t i; mbedtls_mpi M, R; - mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R]; + mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; if( N->n < p_limbs ) return( 0 ); @@ -1235,7 +1237,7 @@ static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); if( shift != 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); - M.n += R.n - adjust; /* Make room for multiplication by R */ + M.n += R.n; /* Make room for multiplication by R */ /* N = A0 */ if( mask != 0 ) @@ -1257,7 +1259,7 @@ static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); if( shift != 0 ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); - M.n += R.n - adjust; /* Make room for multiplication by R */ + M.n += R.n; /* Make room for multiplication by R */ /* N = A0 */ if( mask != 0 ) @@ -1322,4 +1324,6 @@ static int ecp_mod_p256k1( mbedtls_mpi *N ) } #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#endif /* !MBEDTLS_ECP_ALT */ + #endif /* MBEDTLS_ECP_C */ diff --git a/app/mbedtls/library/entropy.c b/app/mbedtls/library/entropy.c index cdbd35c3..23de4062 100644 --- a/app/mbedtls/library/entropy.c +++ b/app/mbedtls/library/entropy.c @@ -1,7 +1,7 @@ /* * Entropy accumulator implementation * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -27,6 +27,12 @@ #if defined(MBEDTLS_ENTROPY_C) +#if defined(MBEDTLS_TEST_NULL_ENTROPY) +#warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! " +#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES " +#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE " +#endif + #include "mbedtls/entropy.h" #include "mbedtls/entropy_poll.h" @@ -36,6 +42,10 @@ #include #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#include "mbedtls/platform.h" +#endif + #if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" @@ -73,6 +83,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) mbedtls_havege_init( &ctx->havege_data ); #endif +#if defined(MBEDTLS_TEST_NULL_ENTROPY) + mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, + 1, MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif + #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, @@ -94,6 +109,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) MBEDTLS_ENTROPY_MIN_HARDWARE, MBEDTLS_ENTROPY_SOURCE_STRONG ); #endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) + mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, + MBEDTLS_ENTROPY_BLOCK_SIZE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ } @@ -112,24 +132,24 @@ int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, mbedtls_entropy_f_source_ptr f_source, void *p_source, size_t threshold, int strong ) { - int index, ret = 0; + int idx, ret = 0; #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); #endif - index = ctx->source_count; - if( index >= MBEDTLS_ENTROPY_MAX_SOURCES ) + idx = ctx->source_count; + if( idx >= MBEDTLS_ENTROPY_MAX_SOURCES ) { ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; goto exit; } - ctx->source[index].f_source = f_source; - ctx->source[index].p_source = p_source; - ctx->source[index].threshold = threshold; - ctx->source[index].strong = strong; + ctx->source[idx].f_source = f_source; + ctx->source[idx].p_source = p_source; + ctx->source[idx].threshold = threshold; + ctx->source[idx].strong = strong; ctx->source_count++; @@ -272,6 +292,18 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); +#if defined(MBEDTLS_ENTROPY_NV_SEED) + /* Update the NV entropy seed before generating any entropy for outside + * use. + */ + if( ctx->initial_entropy_run == 0 ) + { + ctx->initial_entropy_run = 1; + if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) + return( ret ); + } +#endif + #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) return( ret ); @@ -346,6 +378,27 @@ exit: return( ret ); } +#if defined(MBEDTLS_ENTROPY_NV_SEED) +int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) +{ + int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; + unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; + + /* Read new seed and write it to NV */ + if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) + return( ret ); + + if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); + + /* Manually update the remaining stream with a separator value to diverge */ + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + return( 0 ); +} +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + #if defined(MBEDTLS_FS_IO) int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) { @@ -403,6 +456,7 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char * #endif /* MBEDTLS_FS_IO */ #if defined(MBEDTLS_SELF_TEST) +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) /* * Dummy source function */ @@ -416,6 +470,105 @@ static int entropy_dummy_source( void *data, unsigned char *output, return( 0 ); } +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + +static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) +{ + int ret = 0; + size_t entropy_len = 0; + size_t olen = 0; + size_t attempts = buf_len; + + while( attempts > 0 && entropy_len < buf_len ) + { + if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, + buf_len - entropy_len, &olen ) ) != 0 ) + return( ret ); + + entropy_len += olen; + attempts--; + } + + if( entropy_len < buf_len ) + { + ret = 1; + } + + return( ret ); +} + + +static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, + size_t buf_len ) +{ + unsigned char set= 0xFF; + unsigned char unset = 0x00; + size_t i; + + for( i = 0; i < buf_len; i++ ) + { + set &= buf[i]; + unset |= buf[i]; + } + + return( set == 0xFF || unset == 0x00 ); +} + +/* + * A test to ensure hat the entropy sources are functioning correctly + * and there is no obvious failure. The test performs the following checks: + * - The entropy source is not providing only 0s (all bits unset) or 1s (all + * bits set). + * - The entropy source is not providing values in a pattern. Because the + * hardware could be providing data in an arbitrary length, this check polls + * the hardware entropy source twice and compares the result to ensure they + * are not equal. + * - The error code returned by the entropy source is not an error. + */ +int mbedtls_entropy_source_self_test( int verbose ) +{ + int ret = 0; + unsigned char buf0[2 * sizeof( unsigned long long int )]; + unsigned char buf1[2 * sizeof( unsigned long long int )]; + + if( verbose != 0 ) + mbedtls_printf( " ENTROPY_BIAS test: " ); + + memset( buf0, 0x00, sizeof( buf0 ) ); + memset( buf1, 0x00, sizeof( buf1 ) ); + + if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) + goto cleanup; + if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) + goto cleanup; + + /* Make sure that the returned values are not all 0 or 1 */ + if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) + goto cleanup; + if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) + goto cleanup; + + /* Make sure that the entropy source is not returning values in a + * pattern */ + ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; + +cleanup: + if( verbose != 0 ) + { + if( ret != 0 ) + mbedtls_printf( "failed\n" ); + else + mbedtls_printf( "passed\n" ); + + mbedtls_printf( "\n" ); + } + + return( ret != 0 ); +} + +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ /* * The actual entropy quality is hard to test, but we can at least @@ -424,15 +577,18 @@ static int entropy_dummy_source( void *data, unsigned char *output, */ int mbedtls_entropy_self_test( int verbose ) { - int ret = 0; + int ret = 1; +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) mbedtls_entropy_context ctx; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; size_t i, j; +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ if( verbose != 0 ) mbedtls_printf( " ENTROPY test: " ); +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) mbedtls_entropy_init( &ctx ); /* First do a gather to make sure we have default sources */ @@ -473,8 +629,14 @@ int mbedtls_entropy_self_test( int verbose ) } } +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) + goto cleanup; +#endif + cleanup: mbedtls_entropy_free( &ctx ); +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ if( verbose != 0 ) { diff --git a/app/mbedtls/library/entropy_poll.c b/app/mbedtls/library/entropy_poll.c index 25a27bef..a116e605 100644 --- a/app/mbedtls/library/entropy_poll.c +++ b/app/mbedtls/library/entropy_poll.c @@ -1,7 +1,7 @@ /* * Platform-specific and custom entropy polling functions * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -37,8 +37,17 @@ #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) +#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) @@ -61,7 +70,10 @@ int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len } if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) + { + CryptReleaseContext( provider, 0 ); return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } CryptReleaseContext( provider, 0 ); *olen = len; @@ -179,6 +191,23 @@ int mbedtls_platform_entropy_poll( void *data, #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 ) @@ -213,4 +242,27 @@ int mbedtls_havege_poll( void *data, } #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/app/mbedtls/library/error.c b/app/mbedtls/library/error.c index debda1d7..db42381c 100644 --- a/app/mbedtls/library/error.c +++ b/app/mbedtls/library/error.c @@ -34,6 +34,7 @@ #include "mbedtls/platform.h" #else #define mbedtls_snprintf snprintf +#define mbedtls_time_t time_t #endif #if defined(MBEDTLS_ERROR_C) @@ -101,7 +102,7 @@ #endif #if defined(MBEDTLS_NET_C) -#include "mbedtls/net.h" +#include "mbedtls/net_sockets.h" #endif #if defined(MBEDTLS_OID_C) @@ -182,6 +183,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" ); if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) ) + mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid, eg because it was free()ed" ); #endif /* MBEDTLS_CIPHER_C */ #if defined(MBEDTLS_DHM_C) @@ -432,6 +435,10 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) ) mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) ) + mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) ) + mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); #endif /* MBEDTLS_SSL_TLS_C */ #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) @@ -473,6 +480,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); + if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) ) + mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" ); #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ // END generated code diff --git a/app/mbedtls/library/gcm.c b/app/mbedtls/library/gcm.c index aaacf97d..fccb092b 100644 --- a/app/mbedtls/library/gcm.c +++ b/app/mbedtls/library/gcm.c @@ -277,8 +277,10 @@ int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, size_t use_len, olen = 0; /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ - if( ( (uint64_t) iv_len ) >> 61 != 0 || - ( (uint64_t) add_len ) >> 61 != 0 ) + /* IV is not allowed to be zero length */ + if( iv_len == 0 || + ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) { return( MBEDTLS_ERR_GCM_BAD_INPUT ); } @@ -415,8 +417,7 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, if( tag_len > 16 || tag_len < 4 ) return( MBEDTLS_ERR_GCM_BAD_INPUT ); - if( tag_len != 0 ) - memcpy( tag, ctx->base_ectr, tag_len ); + memcpy( tag, ctx->base_ectr, tag_len ); if( orig_len || orig_add_len ) { diff --git a/app/mbedtls/library/havege.c b/app/mbedtls/library/havege.c index 7623bc06..2b75ef7b 100644 --- a/app/mbedtls/library/havege.c +++ b/app/mbedtls/library/havege.c @@ -174,6 +174,8 @@ static void havege_fill( mbedtls_havege_state *hs ) PTX = U1 = 0; PTY = U2 = 0; + (void)PTX; + memset( RES, 0, sizeof( RES ) ); while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) diff --git a/app/mbedtls/library/md.c b/app/mbedtls/library/md.c index 9c2ab6fc..eda98f63 100644 --- a/app/mbedtls/library/md.c +++ b/app/mbedtls/library/md.c @@ -56,7 +56,7 @@ static void mbedtls_zeroize( void *v, size_t n ) { /* * Reminder: update profiles in x509_crt.c when adding a new hash! */ -static const int supported_digests[] ICACHE_RODATA_ATTR = { +static const int supported_digests[] = { #if defined(MBEDTLS_SHA512_C) MBEDTLS_MD_SHA512, @@ -444,7 +444,7 @@ int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) return( 0 ); } -int mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) +unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) { if( md_info == NULL ) return( 0 ); diff --git a/app/mbedtls/library/md2.c b/app/mbedtls/library/md2.c index 89767013..95cbcce6 100644 --- a/app/mbedtls/library/md2.c +++ b/app/mbedtls/library/md2.c @@ -158,7 +158,7 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, s while( ilen > 0 ) { - if( ctx->left + ilen > 16 ) + if( ilen > 16 - ctx->left ) fill = 16 - ctx->left; else fill = ilen; diff --git a/app/mbedtls/library/md5.c b/app/mbedtls/library/md5.c index c36192f3..5d972dc9 100644 --- a/app/mbedtls/library/md5.c +++ b/app/mbedtls/library/md5.c @@ -275,7 +275,7 @@ void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, s } } -static const unsigned char md5_padding[64] ICACHE_RODATA_ATTR = +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, @@ -291,9 +291,6 @@ void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; - unsigned char md5_padding_local[64]; - - memcpy(md5_padding_local, md5_padding, 64); high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); @@ -305,7 +302,7 @@ void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - mbedtls_md5_update( ctx, md5_padding_local, padn ); + mbedtls_md5_update( ctx, md5_padding, padn ); mbedtls_md5_update( ctx, msglen, 8 ); PUT_UINT32_LE( ctx->state[0], output, 0 ); diff --git a/app/mbedtls/library/md_wrap.c b/app/mbedtls/library/md_wrap.c index 3d211598..2cfcae20 100644 --- a/app/mbedtls/library/md_wrap.c +++ b/app/mbedtls/library/md_wrap.c @@ -240,7 +240,7 @@ static void md5_process_wrap( void *ctx, const unsigned char *data ) mbedtls_md5_process( (mbedtls_md5_context *) ctx, data ); } -const mbedtls_md_info_t mbedtls_md5_info ICACHE_RODATA_ATTR = { +const mbedtls_md_info_t mbedtls_md5_info = { MBEDTLS_MD_MD5, "MD5", 16, @@ -364,7 +364,7 @@ static void sha1_process_wrap( void *ctx, const unsigned char *data ) mbedtls_sha1_process( (mbedtls_sha1_context *) ctx, data ); } -const mbedtls_md_info_t mbedtls_sha1_info ICACHE_RODATA_ATTR = { +const mbedtls_md_info_t mbedtls_sha1_info = { MBEDTLS_MD_SHA1, "SHA1", 20, @@ -435,7 +435,7 @@ static void sha224_process_wrap( void *ctx, const unsigned char *data ) mbedtls_sha256_process( (mbedtls_sha256_context *) ctx, data ); } -const mbedtls_md_info_t mbedtls_sha224_info ICACHE_RODATA_ATTR = { +const mbedtls_md_info_t mbedtls_sha224_info = { MBEDTLS_MD_SHA224, "SHA224", 28, @@ -461,7 +461,7 @@ static void sha256_wrap( const unsigned char *input, size_t ilen, mbedtls_sha256( input, ilen, output, 0 ); } -const mbedtls_md_info_t mbedtls_sha256_info ICACHE_RODATA_ATTR = { +const mbedtls_md_info_t mbedtls_sha256_info = { MBEDTLS_MD_SHA256, "SHA256", 32, @@ -529,7 +529,7 @@ static void sha384_process_wrap( void *ctx, const unsigned char *data ) mbedtls_sha512_process( (mbedtls_sha512_context *) ctx, data ); } -const mbedtls_md_info_t mbedtls_sha384_info ICACHE_RODATA_ATTR = { +const mbedtls_md_info_t mbedtls_sha384_info = { MBEDTLS_MD_SHA384, "SHA384", 48, @@ -555,7 +555,7 @@ static void sha512_wrap( const unsigned char *input, size_t ilen, mbedtls_sha512( input, ilen, output, 0 ); } -const mbedtls_md_info_t mbedtls_sha512_info ICACHE_RODATA_ATTR = { +const mbedtls_md_info_t mbedtls_sha512_info = { MBEDTLS_MD_SHA512, "SHA512", 64, diff --git a/app/mbedtls/library/memory_buffer_alloc.c b/app/mbedtls/library/memory_buffer_alloc.c index b2c775a3..545d5a2c 100644 --- a/app/mbedtls/library/memory_buffer_alloc.c +++ b/app/mbedtls/library/memory_buffer_alloc.c @@ -417,6 +417,12 @@ static void buffer_alloc_free( void *ptr ) heap.total_used -= hdr->size; #endif +#if defined(MBEDTLS_MEMORY_BACKTRACE) + free( hdr->trace ); + hdr->trace = NULL; + hdr->trace_count = 0; +#endif + // Regroup with block before // if( hdr->prev != NULL && hdr->prev->alloc == 0 ) @@ -432,9 +438,6 @@ static void buffer_alloc_free( void *ptr ) if( hdr->next != NULL ) hdr->next->prev = hdr; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - free( old->trace ); -#endif memset( old, 0, sizeof(memory_header) ); } @@ -474,9 +477,6 @@ static void buffer_alloc_free( void *ptr ) if( hdr->next != NULL ) hdr->next->prev = hdr; -#if defined(MBEDTLS_MEMORY_BACKTRACE) - free( old->trace ); -#endif memset( old, 0, sizeof(memory_header) ); } @@ -491,11 +491,6 @@ static void buffer_alloc_free( void *ptr ) heap.first_free = hdr; } -#if defined(MBEDTLS_MEMORY_BACKTRACE) - hdr->trace = NULL; - hdr->trace_count = 0; -#endif - if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) mbedtls_exit( 1 ); } diff --git a/app/mbedtls/library/oid.c b/app/mbedtls/library/oid.c index 0d606c69..f13826ed 100644 --- a/app/mbedtls/library/oid.c +++ b/app/mbedtls/library/oid.c @@ -152,6 +152,7 @@ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ return( MBEDTLS_ERR_OID_NOT_FOUND ); \ } +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) /* * For X520 attribute types */ @@ -160,7 +161,7 @@ typedef struct { const char *short_name; } oid_x520_attr_t; -static const oid_x520_attr_t oid_x520_attr_type[] ICACHE_RODATA_ATTR = +static const oid_x520_attr_t oid_x520_attr_type[] = { { { ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" }, @@ -247,7 +248,6 @@ static const oid_x520_attr_t oid_x520_attr_type[] ICACHE_RODATA_ATTR = FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name) -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) /* * For X509 extensions */ @@ -256,7 +256,7 @@ typedef struct { int ext_type; } oid_x509_ext_t; -static const oid_x509_ext_t oid_x509_ext[] ICACHE_RODATA_ATTR = +static const oid_x509_ext_t oid_x509_ext[] = { { { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, @@ -287,7 +287,7 @@ static const oid_x509_ext_t oid_x509_ext[] ICACHE_RODATA_ATTR = FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) -static const mbedtls_oid_descriptor_t oid_ext_key_usage[] ICACHE_RODATA_ATTR = +static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = { { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, @@ -312,24 +312,34 @@ typedef struct { mbedtls_pk_type_t pk_alg; } oid_sig_alg_t; -static const oid_sig_alg_t oid_sig_alg[] ICACHE_RODATA_ATTR = +static const oid_sig_alg_t oid_sig_alg[] = { +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_MD2_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, @@ -338,6 +348,8 @@ static const oid_sig_alg_t oid_sig_alg[] ICACHE_RODATA_ATTR = { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) { { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, @@ -346,34 +358,48 @@ static const oid_sig_alg_t oid_sig_alg[] ICACHE_RODATA_ATTR = { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, }, +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, }, -// { -// { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, -// MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, -// }, -// { -// { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, -// MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, -// }, -// { -// { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, -// MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, -// }, -// { -// { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, -// MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, -// }, -// { -// { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, -// MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, -// }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_SHA1_C) + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, + MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, + }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, + MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, + }, + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, + MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, + }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, + MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, + }, + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, + MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, + }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_RSA_C) { { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, }, +#endif /* MBEDTLS_RSA_C */ { { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, @@ -394,7 +420,7 @@ typedef struct { mbedtls_pk_type_t pk_alg; } oid_pk_alg_t; -static const oid_pk_alg_t oid_pk_alg[] ICACHE_RODATA_ATTR = +static const oid_pk_alg_t oid_pk_alg[] = { { { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, @@ -427,52 +453,74 @@ typedef struct { mbedtls_ecp_group_id grp_id; } oid_ecp_grp_t; -static const oid_ecp_grp_t oid_ecp_grp[] ICACHE_RODATA_ATTR = +static const oid_ecp_grp_t oid_ecp_grp[] = { +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, MBEDTLS_ECP_DP_SECP192R1, }, +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, MBEDTLS_ECP_DP_SECP224R1, }, +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, MBEDTLS_ECP_DP_SECP256R1, }, +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, MBEDTLS_ECP_DP_SECP384R1, }, +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, MBEDTLS_ECP_DP_SECP521R1, }, +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, MBEDTLS_ECP_DP_SECP192K1, }, +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, MBEDTLS_ECP_DP_SECP224K1, }, +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, MBEDTLS_ECP_DP_SECP256K1, }, +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, MBEDTLS_ECP_DP_BP256R1, }, +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, MBEDTLS_ECP_DP_BP384R1, }, +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) { { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, MBEDTLS_ECP_DP_BP512R1, }, +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ { { NULL, 0, NULL, NULL }, MBEDTLS_ECP_DP_NONE, @@ -493,7 +541,7 @@ typedef struct { mbedtls_cipher_type_t cipher_alg; } oid_cipher_alg_t; -static const oid_cipher_alg_t oid_cipher_alg[] ICACHE_RODATA_ATTR = +static const oid_cipher_alg_t oid_cipher_alg[] = { { { ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" }, @@ -522,24 +570,33 @@ typedef struct { mbedtls_md_type_t md_alg; } oid_md_alg_t; -static const oid_md_alg_t oid_md_alg[] ICACHE_RODATA_ATTR = +static const oid_md_alg_t oid_md_alg[] = { +#if defined(MBEDTLS_MD2_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, MBEDTLS_MD_MD2, }, +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, MBEDTLS_MD_MD4, }, +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, MBEDTLS_MD_MD5, }, +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, MBEDTLS_MD_SHA1, }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, MBEDTLS_MD_SHA224, @@ -548,6 +605,8 @@ static const oid_md_alg_t oid_md_alg[] ICACHE_RODATA_ATTR = { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, MBEDTLS_MD_SHA256, }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) { { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, MBEDTLS_MD_SHA384, @@ -556,6 +615,7 @@ static const oid_md_alg_t oid_md_alg[] ICACHE_RODATA_ATTR = { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, MBEDTLS_MD_SHA512, }, +#endif /* MBEDTLS_SHA512_C */ { { NULL, 0, NULL, NULL }, MBEDTLS_MD_NONE, @@ -577,7 +637,7 @@ typedef struct { mbedtls_cipher_type_t cipher_alg; } oid_pkcs12_pbe_alg_t; -static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] ICACHE_RODATA_ATTR = +static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = { { { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, diff --git a/app/mbedtls/library/pem.c b/app/mbedtls/library/pem.c index 1ee3966e..8dd86a4a 100644 --- a/app/mbedtls/library/pem.c +++ b/app/mbedtls/library/pem.c @@ -44,12 +44,12 @@ #define mbedtls_free free #endif +#if defined(MBEDTLS_PEM_PARSE_C) /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; } -#if defined(MBEDTLS_PEM_PARSE_C) void mbedtls_pem_init( mbedtls_pem_context *ctx ) { memset( ctx, 0, sizeof( mbedtls_pem_context ) ); @@ -249,7 +249,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const enc = 0; - if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) + if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) { #if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) @@ -262,22 +262,22 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const #if defined(MBEDTLS_DES_C) - if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) + if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) { enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; s1 += 23; - if( pem_get_iv( s1, pem_iv, 8 ) != 0 ) + if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 ) return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); s1 += 16; } - else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) + else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) { enc_alg = MBEDTLS_CIPHER_DES_CBC; s1 += 18; - if( pem_get_iv( s1, pem_iv, 8) != 0 ) + if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 ) return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); s1 += 16; @@ -285,9 +285,11 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const #endif /* MBEDTLS_DES_C */ #if defined(MBEDTLS_AES_C) - if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) + if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) { - if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) + if( s2 - s1 < 22 ) + return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); + else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) enc_alg = MBEDTLS_CIPHER_AES_128_CBC; else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) enc_alg = MBEDTLS_CIPHER_AES_192_CBC; @@ -297,7 +299,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); s1 += 22; - if( pem_get_iv( s1, pem_iv, 16 ) != 0 ) + if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 ) return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); s1 += 32; @@ -316,7 +318,7 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ } - if( s1 == s2 ) + if( s1 >= s2 ) return( MBEDTLS_ERR_PEM_INVALID_DATA ); ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); diff --git a/app/mbedtls/library/pk.c b/app/mbedtls/library/pk.c index 10bd0a58..8d13bc5c 100644 --- a/app/mbedtls/library/pk.c +++ b/app/mbedtls/library/pk.c @@ -29,6 +29,8 @@ #include "mbedtls/pk.h" #include "mbedtls/pk_internal.h" +#include "mbedtls/bignum.h" + #if defined(MBEDTLS_RSA_C) #include "mbedtls/rsa.h" #endif @@ -39,6 +41,8 @@ #include "mbedtls/ecdsa.h" #endif +#include + /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; @@ -209,6 +213,11 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, int ret; const mbedtls_pk_rsassa_pss_options *pss_opts; +#if defined(MBEDTLS_HAVE_INT64) + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + if( options == NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); @@ -232,7 +241,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, return( 0 ); #else return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); -#endif +#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ } /* General case: no options */ diff --git a/app/mbedtls/library/pk_wrap.c b/app/mbedtls/library/pk_wrap.c index 626c3b9c..db6274cb 100644 --- a/app/mbedtls/library/pk_wrap.c +++ b/app/mbedtls/library/pk_wrap.c @@ -30,6 +30,7 @@ /* Even if RSA not activated, for the sake of RSA-alt */ #include "mbedtls/rsa.h" +#include "mbedtls/bignum.h" #include @@ -49,6 +50,8 @@ #define mbedtls_free free #endif +#include + #if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { @@ -74,6 +77,11 @@ static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, { int ret; +#if defined(MBEDTLS_HAVE_INT64) + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + if( sig_len < ((mbedtls_rsa_context *) ctx)->len ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); @@ -93,6 +101,11 @@ static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, unsigned char *sig, size_t *sig_len, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { +#if defined(MBEDTLS_HAVE_INT64) + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + *sig_len = ((mbedtls_rsa_context *) ctx)->len; return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, @@ -160,7 +173,7 @@ static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) items->value = &( ((mbedtls_rsa_context *) ctx)->E ); } -const mbedtls_pk_info_t mbedtls_rsa_info ICACHE_RODATA_ATTR = { +const mbedtls_pk_info_t mbedtls_rsa_info = { MBEDTLS_PK_RSA, "RSA", rsa_get_bitlen, @@ -270,7 +283,7 @@ static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); } -const mbedtls_pk_info_t mbedtls_eckey_info ICACHE_RODATA_ATTR = { +const mbedtls_pk_info_t mbedtls_eckey_info = { MBEDTLS_PK_ECKEY, "EC", eckey_get_bitlen, @@ -299,7 +312,7 @@ static int eckeydh_can_do( mbedtls_pk_type_t type ) type == MBEDTLS_PK_ECKEY_DH ); } -const mbedtls_pk_info_t mbedtls_eckeydh_info ICACHE_RODATA_ATTR = { +const mbedtls_pk_info_t mbedtls_eckeydh_info = { MBEDTLS_PK_ECKEY_DH, "EC_DH", eckey_get_bitlen, /* Same underlying key structure */ @@ -362,7 +375,7 @@ static void ecdsa_free_wrap( void *ctx ) mbedtls_free( ctx ); } -const mbedtls_pk_info_t mbedtls_ecdsa_info ICACHE_RODATA_ATTR = { +const mbedtls_pk_info_t mbedtls_ecdsa_info = { MBEDTLS_PK_ECDSA, "ECDSA", eckey_get_bitlen, /* Compatible key structures */ @@ -402,6 +415,11 @@ static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, { mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; +#if defined(MBEDTLS_HAVE_INT64) + if( UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + *sig_len = rsa_alt->key_len_func( rsa_alt->key ); return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, @@ -471,7 +489,7 @@ static void rsa_alt_free_wrap( void *ctx ) mbedtls_free( ctx ); } -const mbedtls_pk_info_t mbedtls_rsa_alt_info ICACHE_RODATA_ATTR = { +const mbedtls_pk_info_t mbedtls_rsa_alt_info = { MBEDTLS_PK_RSA_ALT, "RSA-alt", rsa_alt_get_bitlen, diff --git a/app/mbedtls/library/pkcs12.c b/app/mbedtls/library/pkcs12.c index 7023b9db..c603a135 100644 --- a/app/mbedtls/library/pkcs12.c +++ b/app/mbedtls/library/pkcs12.c @@ -93,7 +93,7 @@ static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_ty unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen ) { - int ret, iterations; + int ret, iterations = 0; mbedtls_asn1_buf salt; size_t i; unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; diff --git a/app/mbedtls/library/pkcs5.c b/app/mbedtls/library/pkcs5.c index 44af9869..e28d5a84 100644 --- a/app/mbedtls/library/pkcs5.c +++ b/app/mbedtls/library/pkcs5.c @@ -391,7 +391,8 @@ int mbedtls_pkcs5_self_test( int verbose ) mbedtls_printf( "passed\n" ); } - mbedtls_printf( "\n" ); + if( verbose != 0 ) + mbedtls_printf( "\n" ); exit: mbedtls_md_free( &sha1_ctx ); diff --git a/app/mbedtls/library/pkparse.c b/app/mbedtls/library/pkparse.c index 275429e6..efdf4374 100644 --- a/app/mbedtls/library/pkparse.c +++ b/app/mbedtls/library/pkparse.c @@ -1187,12 +1187,12 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk, #endif /* MBEDTLS_PEM_PARSE_C */ /* - * At this point we only know it's not a PEM formatted key. Could be any - * of the known DER encoded private key formats - * - * We try the different DER format parsers to see if one passes without - * error - */ + * At this point we only know it's not a PEM formatted key. Could be any + * of the known DER encoded private key formats + * + * We try the different DER format parsers to see if one passes without + * error + */ #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen, pwd, pwdlen ) ) == 0 ) diff --git a/app/mbedtls/library/platform.c b/app/mbedtls/library/platform.c index d634c627..2b6ee8b1 100644 --- a/app/mbedtls/library/platform.c +++ b/app/mbedtls/library/platform.c @@ -1,7 +1,7 @@ /* * Platform abstraction layer * - * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * 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 @@ -29,6 +29,10 @@ #include "mbedtls/platform.h" +extern int ets_snprintf(char *buf, unsigned int size, const char *format, ...); +extern void *pvPortCalloc(unsigned int count, unsigned int size); +extern void vPortFree( void *pv ); + #if defined(MBEDTLS_PLATFORM_MEMORY) #if !defined(MBEDTLS_PLATFORM_STD_CALLOC) static void *platform_calloc_uninit( size_t n, size_t size ) @@ -190,4 +194,138 @@ int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) } #endif /* MBEDTLS_PLATFORM_EXIT_ALT */ +#if defined(MBEDTLS_HAVE_TIME) + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) +{ + ((void) timer); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit +#endif /* !MBEDTLS_PLATFORM_STD_TIME */ + +mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; + +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) +{ + mbedtls_time = time_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Default implementations for the platform independent seed functions use + * standard libc file functions to read from and write to a pre-defined filename + */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) + return -1; + + if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + return -1; + } + + fclose( file ); + return( (int)n ); +} + +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) + return -1; + + if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + return -1; + } + + fclose( file ); + return( (int)n ); +} +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ + +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ + +int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_READ; +int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; + +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) +{ + mbedtls_nv_seed_read = nv_seed_read_func; + mbedtls_nv_seed_write = nv_seed_write_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if !defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) +/* + * Placeholder platform setup that does nothing by default + */ +int mbedtls_platform_setup( mbedtls_platform_context *ctx ) +{ + (void)ctx; + + return( 0 ); +} + +/* + * Placeholder platform teardown that does nothing by default + */ +void mbedtls_platform_teardown( mbedtls_platform_context *ctx ) +{ + (void)ctx; +} +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ + #endif /* MBEDTLS_PLATFORM_C */ diff --git a/app/mbedtls/library/ripemd160.c b/app/mbedtls/library/ripemd160.c index a55cc3eb..cdb0a63c 100644 --- a/app/mbedtls/library/ripemd160.c +++ b/app/mbedtls/library/ripemd160.c @@ -456,6 +456,9 @@ int mbedtls_ripemd160_self_test( int verbose ) mbedtls_printf( "passed\n" ); } + if( verbose != 0 ) + mbedtls_printf( "\n" ); + return( 0 ); } diff --git a/app/mbedtls/library/rsa.c b/app/mbedtls/library/rsa.c index efdd055c..bdd2538c 100644 --- a/app/mbedtls/library/rsa.c +++ b/app/mbedtls/library/rsa.c @@ -19,10 +19,21 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ /* - * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman. + * The following sources were referenced in the design of this implementation + * of the RSA algorithm: + * + * [1] A method for obtaining digital signatures and public-key cryptosystems + * R Rivest, A Shamir, and L Adleman + * http://people.csail.mit.edu/rivest/pubs.html#RSA78 + * + * [2] Handbook of Applied Cryptography - 1997, Chapter 8 + * Menezes, van Oorschot and Vanstone + * + * [3] Malware Guard Extension: Using SGX to Conceal Cache Attacks + * Michael Schwarz, Samuel Weiser, Daniel Gruss, Clémentine Maurice and + * Stefan Mangard + * https://arxiv.org/abs/1702.08719v2 * - * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf - * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf */ #if !defined(MBEDTLS_CONFIG_FILE) @@ -55,6 +66,11 @@ #define mbedtls_free free #endif +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + /* * Initialize an RSA context */ @@ -96,7 +112,11 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, if( f_rng == NULL || nbits < 128 || exponent < 3 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + if( nbits % 2 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); + mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); /* * find primes P and Q with Q < P so that: @@ -106,15 +126,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, do { - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, + MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0, f_rng, p_rng ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0, + MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0, f_rng, p_rng ) ); - if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) - mbedtls_mpi_swap( &ctx->P, &ctx->Q ); - if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) continue; @@ -122,6 +139,9 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, if( mbedtls_mpi_bitlen( &ctx->N ) != nbits ) continue; + if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) + mbedtls_mpi_swap( &ctx->P, &ctx->Q ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); @@ -346,6 +366,27 @@ cleanup: return( ret ); } +/* + * Exponent blinding supposed to prevent side-channel attacks using multiple + * traces of measurements to recover the RSA key. The more collisions are there, + * the more bits of the key can be recovered. See [3]. + * + * Collecting n collisions with m bit long blinding value requires 2^(m-m/n) + * observations on avarage. + * + * For example with 28 byte blinding to achieve 2 collisions the adversary has + * to make 2^112 observations on avarage. + * + * (With the currently (as of 2017 April) known best algorithms breaking 2048 + * bit RSA requires approximately as much time as trying out 2^112 random keys. + * Thus in this sense with 28 byte blinding the security is not reduced by + * side-channel attacks like the one in [3]) + * + * This countermeasure does not help if the key recovery is possible with a + * single trace. + */ +#define RSA_EXPONENT_BLINDING 28 + /* * Do an RSA private key operation */ @@ -358,12 +399,34 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, int ret; size_t olen; mbedtls_mpi T, T1, T2; + mbedtls_mpi P1, Q1, R; +#if defined(MBEDTLS_RSA_NO_CRT) + mbedtls_mpi D_blind; + mbedtls_mpi *D = &ctx->D; +#else + mbedtls_mpi DP_blind, DQ_blind; + mbedtls_mpi *DP = &ctx->DP; + mbedtls_mpi *DQ = &ctx->DQ; +#endif /* Make sure we have private key info, prevent possible misuse */ if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); + mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); mbedtls_mpi_init( &R ); + + + if( f_rng != NULL ) + { +#if defined(MBEDTLS_RSA_NO_CRT) + mbedtls_mpi_init( &D_blind ); +#else + mbedtls_mpi_init( &DP_blind ); + mbedtls_mpi_init( &DQ_blind ); +#endif + } + #if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) @@ -386,19 +449,60 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); + + /* + * Exponent blinding + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + +#if defined(MBEDTLS_RSA_NO_CRT) + /* + * D_blind = ( P - 1 ) * ( Q - 1 ) * R + D + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, + f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &P1, &Q1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &D_blind, &D_blind, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &D_blind, &D_blind, &ctx->D ) ); + + D = &D_blind; +#else + /* + * DP_blind = ( P - 1 ) * R + DP + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, + f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DP_blind, &P1, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DP_blind, &DP_blind, + &ctx->DP ) ); + + DP = &DP_blind; + + /* + * DQ_blind = ( Q - 1 ) * R + DQ + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &R, RSA_EXPONENT_BLINDING, + f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DQ_blind, &Q1, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &DQ_blind, &DQ_blind, + &ctx->DQ ) ); + + DQ = &DQ_blind; +#endif /* MBEDTLS_RSA_NO_CRT */ } #if defined(MBEDTLS_RSA_NO_CRT) - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, D, &ctx->N, &ctx->RN ) ); #else /* - * faster decryption using the CRT + * Faster decryption using the CRT * * T1 = input ^ dP mod P * T2 = input ^ dQ mod Q */ - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, DP, &ctx->P, &ctx->RP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, DQ, &ctx->Q, &ctx->RQ ) ); /* * T = (T1 - T2) * (Q^-1 mod P) mod P @@ -434,6 +538,17 @@ cleanup: #endif mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); + mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &R ); + + if( f_rng != NULL ) + { +#if defined(MBEDTLS_RSA_NO_CRT) + mbedtls_mpi_free( &D_blind ); +#else + mbedtls_mpi_free( &DP_blind ); + mbedtls_mpi_free( &DQ_blind ); +#endif + } if( ret != 0 ) return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); @@ -465,8 +580,7 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, hlen = mbedtls_md_get_size( md_ctx->md_info ); - // Generate and apply dbMask - // + /* Generate and apply dbMask */ p = dst; while( dlen > 0 ) @@ -487,6 +601,8 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, dlen -= use_len; } + + mbedtls_zeroize( mask, sizeof( mask ) ); } #endif /* MBEDTLS_PKCS1_V21 */ @@ -523,22 +639,21 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, olen = ctx->len; hlen = mbedtls_md_get_size( md_info ); - if( olen < ilen + 2 * hlen + 2 ) + /* first comparison checks for overflow */ + if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); memset( output, 0, olen ); *p++ = 0; - // Generate a random octet string seed - // + /* Generate a random octet string seed */ if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); p += hlen; - // Construct DB - // + /* Construct DB */ mbedtls_md( md_info, label, label_len, p ); p += hlen; p += olen - 2 * hlen - 2 - ilen; @@ -546,15 +661,17 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, memcpy( p, input, ilen ); mbedtls_md_init( &md_ctx ); - mbedtls_md_setup( &md_ctx, md_info, 0 ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + return( ret ); + } - // maskedDB: Apply dbMask to DB - // + /* maskedDB: Apply dbMask to DB */ mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, &md_ctx ); - // maskedSeed: Apply seedMask to seed - // + /* maskedSeed: Apply seedMask to seed */ mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, &md_ctx ); @@ -584,12 +701,14 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); - if( f_rng == NULL ) + // We don't check p_rng because it won't be dereferenced here + if( f_rng == NULL || input == NULL || output == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); olen = ctx->len; - if( olen < ilen + 11 ) + /* first comparison checks for overflow */ + if( ilen + 11 < ilen || olen < ilen + 11 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); nb_pad = olen - 3 - ilen; @@ -607,8 +726,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, ret = f_rng( p_rng, p, 1 ); } while( *p == 0 && --rng_dl && ret == 0 ); - // Check if RNG failed to generate data - // + /* Check if RNG failed to generate data */ if( rng_dl == 0 || ret != 0 ) return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); @@ -699,6 +817,12 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + hlen = mbedtls_md_get_size( md_info ); + + // checking for integer underflow + if( 2 * hlen + 2 > ilen ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + /* * RSA operation */ @@ -707,15 +831,18 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); if( ret != 0 ) - return( ret ); + goto cleanup; /* * Unmask data and generate lHash */ - hlen = mbedtls_md_get_size( md_info ); - mbedtls_md_init( &md_ctx ); - mbedtls_md_setup( &md_ctx, md_info, 0 ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + goto cleanup; + } + /* Generate lHash */ mbedtls_md( md_info, label, label_len, lhash ); @@ -764,15 +891,26 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, * the different error conditions. */ if( bad != 0 ) - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + { + ret = MBEDTLS_ERR_RSA_INVALID_PADDING; + goto cleanup; + } if( ilen - ( p - buf ) > output_max_len ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + { + ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; + goto cleanup; + } *olen = ilen - (p - buf); memcpy( output, p, *olen ); + ret = 0; - return( 0 ); +cleanup: + mbedtls_zeroize( buf, sizeof( buf ) ); + mbedtls_zeroize( lhash, sizeof( lhash ) ); + + return( ret ); } #endif /* MBEDTLS_PKCS1_V21 */ @@ -806,7 +944,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); if( ret != 0 ) - return( ret ); + goto cleanup; p = buf; bad = 0; @@ -848,16 +986,28 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, bad |= *p++; /* Must be zero */ } + bad |= ( pad_count < 8 ); + if( bad ) - return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + { + ret = MBEDTLS_ERR_RSA_INVALID_PADDING; + goto cleanup; + } if( ilen - ( p - buf ) > output_max_len ) - return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + { + ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE; + goto cleanup; + } *olen = ilen - (p - buf); memcpy( output, p, *olen ); + ret = 0; - return( 0 ); +cleanup: + mbedtls_zeroize( buf, sizeof( buf ) ); + + return( ret ); } #endif /* MBEDTLS_PKCS1_V15 */ @@ -924,8 +1074,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, if( md_alg != MBEDTLS_MD_NONE ) { - // Gather length of hash to sign - // + /* Gather length of hash to sign */ md_info = mbedtls_md_info_from_type( md_alg ); if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -945,13 +1094,11 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, memset( sig, 0, olen ); - // Generate salt of length slen - // + /* Generate salt of length slen */ if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); - // Note: EMSA-PSS encoding is over the length of N - 1 bits - // + /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; p += olen - hlen * 2 - 2; *p++ = 0x01; @@ -959,23 +1106,26 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, p += slen; mbedtls_md_init( &md_ctx ); - mbedtls_md_setup( &md_ctx, md_info, 0 ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + /* No need to zeroize salt: we didn't use it. */ + return( ret ); + } - // Generate H = Hash( M' ) - // + /* Generate H = Hash( M' ) */ mbedtls_md_starts( &md_ctx ); mbedtls_md_update( &md_ctx, p, 8 ); mbedtls_md_update( &md_ctx, hash, hashlen ); mbedtls_md_update( &md_ctx, salt, slen ); mbedtls_md_finish( &md_ctx, p ); + mbedtls_zeroize( salt, sizeof( salt ) ); - // Compensate for boundary condition when applying mask - // + /* Compensate for boundary condition when applying mask */ if( msb % 8 == 0 ) offset = 1; - // maskedDB: Apply dbMask to DB - // + /* maskedDB: Apply dbMask to DB */ mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx ); mbedtls_md_free( &md_ctx ); @@ -1169,13 +1319,13 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, int ret; size_t siglen; unsigned char *p; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; unsigned char result[MBEDTLS_MD_MAX_SIZE]; unsigned char zeros[8]; unsigned int hlen; size_t slen, msb; const mbedtls_md_info_t *md_info; mbedtls_md_context_t md_ctx; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1199,8 +1349,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, if( md_alg != MBEDTLS_MD_NONE ) { - // Gather length of hash to sign - // + /* Gather length of hash to sign */ md_info = mbedtls_md_info_from_type( md_alg ); if( md_info == NULL ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1217,12 +1366,12 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, memset( zeros, 0, 8 ); - // Note: EMSA-PSS verification is over the length of N - 1 bits - // + /* + * Note: EMSA-PSS verification is over the length of N - 1 bits + */ msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; - // Compensate for boundary condition when applying mask - // + /* Compensate for boundary condition when applying mask */ if( msb % 8 == 0 ) { p++; @@ -1232,7 +1381,11 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); mbedtls_md_init( &md_ctx ); - mbedtls_md_setup( &md_ctx, md_info, 0 ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + return( ret ); + } mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); @@ -1258,8 +1411,9 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_INVALID_PADDING ); } - // Generate H = Hash( M' ) - // + /* + * Generate H = Hash( M' ) + */ mbedtls_md_starts( &md_ctx ); mbedtls_md_update( &md_ctx, zeros, 8 ); mbedtls_md_update( &md_ctx, hash, hashlen ); @@ -1313,11 +1467,11 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, { int ret; size_t len, siglen, asn1_len; - unsigned char *p, *end; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + unsigned char *p, *p0, *end; mbedtls_md_type_t msg_md_alg; const mbedtls_md_info_t *md_info; mbedtls_asn1_buf oid; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); @@ -1345,7 +1499,11 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, return( MBEDTLS_ERR_RSA_INVALID_PADDING ); p++; } - p++; + p++; /* skip 00 byte */ + + /* We've read: 00 01 PS 00 where PS must be at least 8 bytes */ + if( p - buf < 11 ) + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); len = siglen - ( p - buf ); @@ -1364,24 +1522,30 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, end = p + len; - // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure - // + /* + * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure. + * Insist on 2-byte length tags, to protect against variants of + * Bleichenbacher's forgery attack against lax PKCS#1v1.5 verification. + */ + p0 = p; if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - if( asn1_len + 2 != len ) + if( p != p0 + 2 || asn1_len + 2 != len ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + p0 = p; if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - if( asn1_len + 6 + hashlen != len ) + if( p != p0 + 2 || asn1_len + 6 + hashlen != len ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + p0 = p; if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + if( p != p0 + 2 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); oid.p = p; p += oid.len; @@ -1395,13 +1559,16 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, /* * assume the algorithm parameters must be NULL */ + p0 = p; if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + if( p != p0 + 2 ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); - if( asn1_len != hashlen ) + p0 = p; + if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + if( p != p0 + 2 || asn1_len != hashlen ) return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); if( memcmp( p, hash, hashlen ) != 0 ) @@ -1660,7 +1827,7 @@ int mbedtls_rsa_self_test( int verbose ) #if defined(MBEDTLS_SHA1_C) if( verbose != 0 ) - mbedtls_printf( "PKCS#1 data sign : " ); + mbedtls_printf( " PKCS#1 data sign : " ); mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum ); diff --git a/app/mbedtls/library/sha1.c b/app/mbedtls/library/sha1.c index c9acc64e..2ccf2a2f 100644 --- a/app/mbedtls/library/sha1.c +++ b/app/mbedtls/library/sha1.c @@ -49,7 +49,7 @@ /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { - volatile unsigned char *p = v; while( n-- ) *p++ = 0; + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; } /* @@ -307,7 +307,7 @@ void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, memcpy( (void *) (ctx->buffer + left), input, ilen ); } -static const unsigned char sha1_padding[64] ICACHE_RODATA_ATTR = +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, @@ -323,9 +323,6 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; - unsigned char sha1_padding_local[64]; - - memcpy(sha1_padding_local, sha1_padding, 64); high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); @@ -337,7 +334,7 @@ void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - mbedtls_sha1_update( ctx, sha1_padding_local, padn ); + mbedtls_sha1_update( ctx, sha1_padding, padn ); mbedtls_sha1_update( ctx, msglen, 8 ); PUT_UINT32_BE( ctx->state[0], output, 0 ); diff --git a/app/mbedtls/library/sha256.c b/app/mbedtls/library/sha256.c index 946e6724..ad25d383 100644 --- a/app/mbedtls/library/sha256.c +++ b/app/mbedtls/library/sha256.c @@ -33,7 +33,6 @@ #if defined(MBEDTLS_SHA256_C) #include "mbedtls/sha256.h" -#include "c_types.h" #include @@ -42,7 +41,10 @@ #include "mbedtls/platform.h" #else #include +#include #define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ @@ -132,7 +134,7 @@ void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ) } #if !defined(MBEDTLS_SHA256_PROCESS_ALT) -static const uint32_t K[] ICACHE_RODATA_ATTR STORE_ATTR = +static const uint32_t K[] = { 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, @@ -274,7 +276,7 @@ void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *in memcpy( (void *) (ctx->buffer + left), input, ilen ); } -static const unsigned char sha256_padding[64] ICACHE_RODATA_ATTR = +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, @@ -290,9 +292,6 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32 uint32_t last, padn; uint32_t high, low; unsigned char msglen[8]; - unsigned char sha256_padding_local[64]; - - memcpy(sha256_padding_local, sha256_padding, 64); high = ( ctx->total[0] >> 29 ) | ( ctx->total[1] << 3 ); @@ -304,7 +303,7 @@ void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32 last = ctx->total[0] & 0x3F; padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - mbedtls_sha256_update( ctx, sha256_padding_local, padn ); + mbedtls_sha256_update( ctx, sha256_padding, padn ); mbedtls_sha256_update( ctx, msglen, 8 ); PUT_UINT32_BE( ctx->state[0], output, 0 ); @@ -393,10 +392,19 @@ static const unsigned char sha256_test_sum[6][32] = int mbedtls_sha256_self_test( int verbose ) { int i, j, k, buflen, ret = 0; - unsigned char buf[1024]; + unsigned char *buf; unsigned char sha256sum[32]; mbedtls_sha256_context ctx; + buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); + if( NULL == buf ) + { + if( verbose != 0 ) + mbedtls_printf( "Buffer allocation failed\n" ); + + return( 1 ); + } + mbedtls_sha256_init( &ctx ); for( i = 0; i < 6; i++ ) @@ -440,6 +448,7 @@ int mbedtls_sha256_self_test( int verbose ) exit: mbedtls_sha256_free( &ctx ); + mbedtls_free( buf ); return( ret ); } diff --git a/app/mbedtls/library/sha512.c b/app/mbedtls/library/sha512.c index f8be80eb..724522ac 100644 --- a/app/mbedtls/library/sha512.c +++ b/app/mbedtls/library/sha512.c @@ -39,8 +39,7 @@ #else #define UL64(x) x##ULL #endif -#include "c_types.h" -#include "mem.h" + #include #if defined(MBEDTLS_SELF_TEST) @@ -48,7 +47,10 @@ #include "mbedtls/platform.h" #else #include +#include #define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free #endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_SELF_TEST */ @@ -90,53 +92,6 @@ static void mbedtls_zeroize( void *v, size_t n ) { } #endif /* PUT_UINT64_BE */ -/* - * Round constants - */ -static const uint64_t K[80] ICACHE_RODATA_ATTR STORE_ATTR = -{ - UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), - UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), - UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), - UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), - UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), - UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), - UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), - UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), - UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), - UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), - UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), - UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), - UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), - UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), - UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), - UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), - UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), - UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), - UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), - UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), - UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), - UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), - UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), - UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), - UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), - UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), - UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), - UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), - UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), - UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), - UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), - UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), - UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), - UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), - UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), - UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), - UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), - UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), - UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), - UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) -}; - void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) { memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); @@ -193,6 +148,54 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) } #if !defined(MBEDTLS_SHA512_PROCESS_ALT) + +/* + * Round constants + */ +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; + void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) { int i; @@ -303,7 +306,7 @@ void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *in memcpy( (void *) (ctx->buffer + left), input, ilen ); } -static const unsigned char sha512_padding[128] ICACHE_RODATA_ATTR STORE_ATTR = +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, @@ -323,9 +326,6 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64 size_t last, padn; uint64_t high, low; unsigned char msglen[16]; - unsigned char sha512_padding_local[128]; - - memcpy(sha512_padding_local, sha512_padding, 128); high = ( ctx->total[0] >> 61 ) | ( ctx->total[1] << 3 ); @@ -337,8 +337,7 @@ void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64 last = (size_t)( ctx->total[0] & 0x7F ); padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); - - mbedtls_sha512_update( ctx, sha512_padding_local, padn ); + mbedtls_sha512_update( ctx, sha512_padding, padn ); mbedtls_sha512_update( ctx, msglen, 16 ); PUT_UINT64_BE( ctx->state[0], output, 0 ); @@ -449,10 +448,19 @@ static const unsigned char sha512_test_sum[6][64] = int mbedtls_sha512_self_test( int verbose ) { int i, j, k, buflen, ret = 0; - unsigned char buf[1024]; + unsigned char *buf; unsigned char sha512sum[64]; mbedtls_sha512_context ctx; + buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); + if( NULL == buf ) + { + if( verbose != 0 ) + mbedtls_printf( "Buffer allocation failed\n" ); + + return( 1 ); + } + mbedtls_sha512_init( &ctx ); for( i = 0; i < 6; i++ ) @@ -496,6 +504,7 @@ int mbedtls_sha512_self_test( int verbose ) exit: mbedtls_sha512_free( &ctx ); + mbedtls_free( buf ); return( ret ); } diff --git a/app/mbedtls/library/ssl_cache.c b/app/mbedtls/library/ssl_cache.c index 711bc535..c771d7fe 100644 --- a/app/mbedtls/library/ssl_cache.c +++ b/app/mbedtls/library/ssl_cache.c @@ -31,18 +31,18 @@ #if defined(MBEDTLS_SSL_CACHE_C) -#include "mbedtls/ssl_cache.h" - -#include - #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else #include #define mbedtls_calloc calloc -#define mbedtls_free free +#define mbedtls_free free #endif +#include "mbedtls/ssl_cache.h" + +#include + void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) { memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); @@ -59,7 +59,7 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) { int ret = 1; #if defined(MBEDTLS_HAVE_TIME) - time_t t = time( NULL ); + mbedtls_time_t t = mbedtls_time( NULL ); #endif mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; mbedtls_ssl_cache_entry *cur, *entry; @@ -138,7 +138,7 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) { int ret = 1; #if defined(MBEDTLS_HAVE_TIME) - time_t t = time( NULL ), oldest = 0; + mbedtls_time_t t = mbedtls_time( NULL ), oldest = 0; mbedtls_ssl_cache_entry *old = NULL; #endif mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; diff --git a/app/mbedtls/library/ssl_ciphersuites.c b/app/mbedtls/library/ssl_ciphersuites.c index 862deb38..95e6163c 100644 --- a/app/mbedtls/library/ssl_ciphersuites.c +++ b/app/mbedtls/library/ssl_ciphersuites.c @@ -29,11 +29,15 @@ #if defined(MBEDTLS_SSL_TLS_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#endif + #include "mbedtls/ssl_ciphersuites.h" #include "mbedtls/ssl.h" -#include "c_types.h" - #include /* @@ -48,7 +52,7 @@ * 4. By hash function used when relevant * 5. By key exchange/auth again: EC > non-EC */ -static const int ciphersuite_preference[] ICACHE_RODATA_ATTR STORE_ATTR = +static const int ciphersuite_preference[] = { #if defined(MBEDTLS_SSL_CIPHERSUITES) MBEDTLS_SSL_CIPHERSUITES, @@ -260,7 +264,7 @@ static const int ciphersuite_preference[] ICACHE_RODATA_ATTR STORE_ATTR = 0 }; -static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] ICACHE_RODATA_ATTR STORE_ATTR = +static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = { #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) #if defined(MBEDTLS_AES_C) @@ -1813,6 +1817,24 @@ mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciph return( MBEDTLS_PK_NONE ); } } + +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_alg( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + return( MBEDTLS_PK_RSA ); + + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( MBEDTLS_PK_ECDSA ); + + default: + return( MBEDTLS_PK_NONE ); + } +} + #endif /* MBEDTLS_PK_C */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) diff --git a/app/mbedtls/library/ssl_cli.c b/app/mbedtls/library/ssl_cli.c index c41f046a..a2b9f8cf 100644 --- a/app/mbedtls/library/ssl_cli.c +++ b/app/mbedtls/library/ssl_cli.c @@ -27,24 +27,24 @@ #if defined(MBEDTLS_SSL_CLI_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + #include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" #include -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - #include #if defined(MBEDTLS_HAVE_TIME) -#include +#include "mbedtls/platform_time.h" #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -264,12 +264,19 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ECP_C) for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) - { - info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); #else for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) - { #endif + { +#if defined(MBEDTLS_ECP_C) + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#endif + if( info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) ); + return; + } + elliptic_curve_len += 2; } @@ -283,13 +290,13 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ECP_C) for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) - { - info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); #else for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) - { #endif - + { +#if defined(MBEDTLS_ECP_C) + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#endif elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; } @@ -664,7 +671,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) int ret; unsigned char *p = ssl->handshake->randbytes; #if defined(MBEDTLS_HAVE_TIME) - time_t t; + mbedtls_time_t t; #endif /* @@ -679,7 +686,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl ) #endif #if defined(MBEDTLS_HAVE_TIME) - t = time( NULL ); + t = mbedtls_time( NULL ); *p++ = (unsigned char)( t >> 24 ); *p++ = (unsigned char)( t >> 16 ); *p++ = (unsigned char)( t >> 8 ); @@ -1050,8 +1057,6 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - int ret; - #if defined(MBEDTLS_SSL_RENEGOTIATION) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) { @@ -1064,10 +1069,8 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } } @@ -1077,10 +1080,8 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, if( len != 1 || buf[0] != 0x00 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1103,6 +1104,9 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, len != 1 || buf[0] != ssl->conf->mfl_code ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching max fragment length extension" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1118,6 +1122,9 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || len != 0 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching truncated HMAC extension" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1138,6 +1145,9 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || len != 0 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching encrypt-then-MAC extension" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1158,6 +1168,9 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || len != 0 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching extended master secret extension" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1177,6 +1190,9 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || len != 0 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching session ticket extension" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1201,6 +1217,8 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, if( list_size + 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 ); } @@ -1212,7 +1230,7 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, { #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) ssl->handshake->ecdh_ctx.point_format = p[0]; -#endif +#endif #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ssl->handshake->ecjpake_ctx.point_format = p[0]; #endif @@ -1225,6 +1243,8 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, } MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || @@ -1253,6 +1273,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, buf, len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( ret ); } @@ -1269,7 +1291,12 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* If we didn't send it, the server shouldn't send it */ if( ssl->conf->alpn_list == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching ALPN extension" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } /* * opaque ProtocolName<1..2^8-1>; @@ -1283,15 +1310,27 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ if( len < 4 ) + { + 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_len = ( buf[0] << 8 ) | buf[1]; if( list_len != len - 2 ) + { + 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 ); + } name_len = buf[2]; if( name_len != list_len - 1 ) + { + 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 ); + } /* Check that the server chosen protocol was in our list and save it */ for( p = ssl->conf->alpn_list; *p != NULL; p++ ) @@ -1304,6 +1343,9 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, } } + MBEDTLS_SSL_DEBUG_MSG( 1, ( "ALPN extension: no matching protocol" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } #endif /* MBEDTLS_SSL_ALPN */ @@ -1350,6 +1392,15 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) cookie_len = *p++; MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); + if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "cookie length does not match incoming message size" ) ); + 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 ); + } + mbedtls_free( ssl->handshake->verify_cookie ); ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len ); @@ -1399,6 +1450,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { + /* No alert on a read error. */ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); } @@ -1419,11 +1471,15 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) } MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) ); + + ssl->keep_current_message = 1; return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -1450,6 +1506,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) { 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 ); } @@ -1504,6 +1562,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( n > 32 ) { 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 ); } @@ -1516,6 +1576,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_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 ); } } @@ -1526,6 +1588,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) else { 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 ); } @@ -1553,6 +1617,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) #endif/* MBEDTLS_ZLIB_SUPPORT */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); } @@ -1564,6 +1630,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ssl->transform_negotiate->ciphersuite_info == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -1587,7 +1655,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ssl->state++; ssl->handshake->resume = 0; #if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = time( NULL ); + ssl->session_negotiate->start = mbedtls_time( NULL ); #endif ssl->session_negotiate->ciphersuite = i; ssl->session_negotiate->compression = comp; @@ -1601,6 +1669,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( ret ); } } @@ -1620,6 +1690,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1631,6 +1703,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1648,6 +1722,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } ssl->session_negotiate->compression = comp; @@ -1666,6 +1742,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( ext_size + 4 > ext_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 ); } @@ -1836,9 +1914,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) if( handshake_failure == 1 ) { - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } @@ -1977,12 +2054,16 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, if( (*p) + len > end ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message " + "(psk_identity_hint length)" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } - // TODO: Retrieve PSK identity hint and callback to app - // + /* + * Note: we currently ignore the PKS identity hint, as we only allow one + * PSK to be provisionned on the client. This could be changed later if + * someone needs that feature. + */ *p += len; ret = 0; @@ -2116,8 +2197,8 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, */ if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm " - "that was not offered" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm %d that was not offered", + *(p)[0] ) ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } @@ -2175,7 +2256,8 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) { int ret; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; unsigned char *p, *end; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); @@ -2199,6 +2281,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( ret ); } @@ -2220,6 +2304,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -2232,11 +2318,17 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) { - ssl->record_read = 1; + /* Current message is probably either + * CertificateRequest or ServerHelloDone */ + ssl->keep_current_message = 1; goto exit; } - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key exchange message must " + "not be skipped" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -2253,6 +2345,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } /* FALLTROUGH */ @@ -2274,6 +2368,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2290,6 +2386,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2305,6 +2403,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2315,12 +2415,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) + if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) ) { size_t sig_len, hashlen; unsigned char hash[64]; @@ -2339,12 +2435,16 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) &md_alg, &pk_alg ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); } } @@ -2376,6 +2476,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( end != p + sig_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange 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_KEY_EXCHANGE ); } @@ -2447,6 +2549,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( ret ); } @@ -2470,6 +2574,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ssl->session_negotiate->peer_cert == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -2479,19 +2585,21 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); } if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, md_alg, hash, hashlen, p, sig_len ) ) != 0 ) { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); return( ret ); } } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ exit: ssl->state++; @@ -2501,21 +2609,15 @@ exit: return( 0 ); } -#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ - !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if ! defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) { - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); ssl->state++; @@ -2525,61 +2627,51 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } -#else +#else /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) { int ret; - unsigned char *buf, *p; - size_t n = 0, m = 0; + unsigned char *buf; + size_t n = 0; size_t cert_type_len = 0, dn_len = 0; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + if( ! mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); ssl->state++; return( 0 ); } - if( ssl->record_read == 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { - if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } - - ssl->record_read = 1; + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); } - ssl->client_auth = 0; - ssl->state++; + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } - if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ) - ssl->client_auth++; + ssl->state++; + ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", ssl->client_auth ? "a" : "no" ) ); if( ssl->client_auth == 0 ) + { + /* Current message is probably the ServerHelloDone */ + ssl->keep_current_message = 1; goto exit; - - ssl->record_read = 0; - - // TODO: handshake_failure alert for an anonymous server to request - // client authentication + } /* * struct { @@ -2588,77 +2680,76 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only * DistinguishedName certificate_authorities<0..2^16-1>; * } CertificateRequest; + * + * Since we only support a single certificate on clients, let's just + * ignore all the information that's supposed to help us pick a + * certificate. + * + * We could check that our certificate matches the request, and bail out + * if it doesn't, but it's simpler to just send the certificate anyway, + * and give the server the opportunity to decide if it should terminate + * the connection when it doesn't like our certificate. + * + * Same goes for the hash in TLS 1.2's signature_algorithms: at this + * point we only have one hash available (see comments in + * write_certificate_verify), so let's just use what we have. + * + * However, we still minimally parse the message to check it is at least + * superficially sane. */ buf = ssl->in_msg; - // Retrieve cert types - // + /* certificate_types */ cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; n = cert_type_len; if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request 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_REQUEST ); } - p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1; - while( cert_type_len > 0 ) - { -#if defined(MBEDTLS_RSA_C) - if( *p == MBEDTLS_SSL_CERT_TYPE_RSA_SIGN && - mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) ) - { - ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; - break; - } - else -#endif -#if defined(MBEDTLS_ECDSA_C) - if( *p == MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN && - mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) ) - { - ssl->handshake->cert_type = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; - break; - } - else -#endif - { - ; /* Unsupported cert type, ignore */ - } - - cert_type_len--; - p++; - } - + /* supported_signature_algorithms */ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - /* Ignored, see comments about hash in write_certificate_verify */ - // TODO: should check the signature part against our pk_key though size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); +#if defined(MBEDTLS_DEBUG_C) + unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; + size_t i; - m += 2; - n += sig_alg_len; + for( i = 0; i < sig_alg_len; i += 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d" + ",%d", sig_alg[i], sig_alg[i + 1] ) ); + } +#endif + + n += 2 + sig_alg_len; if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request 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_REQUEST ); } } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ - /* Ignore certificate_authorities, we only have one cert anyway */ - // TODO: should not send cert if no CA matches - dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 ) - | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) ); + /* certificate_authorities */ + dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) + | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); n += dn_len; - if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + m + 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, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); } @@ -2667,10 +2758,7 @@ exit: return( 0 ); } -#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) { @@ -2678,26 +2766,24 @@ static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); - if( ssl->record_read == 0 ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { - if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } - - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); - } + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } - ssl->record_read = 0; if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) || ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done 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_DONE ); } @@ -2717,7 +2803,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) { int ret; size_t i, n; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); @@ -2804,10 +2891,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( mbedtls_ssl_ciphersuite_uses_psk( ciphersuite_info ) ) { /* * opaque psk_identity<0..2^16-1>; @@ -2971,11 +3055,14 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) { - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; int ret; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); @@ -3004,7 +3091,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; size_t n = 0, offset = 0; unsigned char hash[48]; unsigned char *hash_start = hash; @@ -3151,7 +3239,10 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) @@ -3173,6 +3264,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -3190,6 +3283,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); } @@ -3203,6 +3298,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); } @@ -3228,6 +3325,8 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } @@ -3284,7 +3383,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET; } #endif - + switch( ssl->state ) { case MBEDTLS_SSL_HELLO_REQUEST: @@ -3350,9 +3449,6 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) case MBEDTLS_SSL_CLIENT_FINISHED: ret = mbedtls_ssl_write_finished( ssl ); -#if defined(ESP8266_PLATFORM) - mbedtls_write_finished(ssl); -#endif break; /* diff --git a/app/mbedtls/library/ssl_cookie.c b/app/mbedtls/library/ssl_cookie.c index 7e0c573a..caf11999 100644 --- a/app/mbedtls/library/ssl_cookie.c +++ b/app/mbedtls/library/ssl_cookie.c @@ -31,16 +31,16 @@ #if defined(MBEDTLS_SSL_COOKIE_C) -#include "mbedtls/ssl_cookie.h" -#include "mbedtls/ssl_internal.h" - #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else #define mbedtls_calloc calloc -#define mbedtls_free free +#define mbedtls_free free #endif +#include "mbedtls/ssl_cookie.h" +#include "mbedtls/ssl_internal.h" + #include /* Implementation that should never be optimized out by the compiler */ @@ -98,7 +98,7 @@ void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) mbedtls_md_free( &ctx->hmac_ctx ); #if defined(MBEDTLS_THREADING_C) - mbedtls_mutex_init( &ctx->mutex ); + mbedtls_mutex_free( &ctx->mutex ); #endif mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); @@ -172,7 +172,7 @@ int mbedtls_ssl_cookie_write( void *p_ctx, return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); #if defined(MBEDTLS_HAVE_TIME) - t = (unsigned long) time( NULL ); + t = (unsigned long) mbedtls_time( NULL ); #else t = ctx->serial++; #endif @@ -242,7 +242,7 @@ int mbedtls_ssl_cookie_check( void *p_ctx, return( -1 ); #if defined(MBEDTLS_HAVE_TIME) - cur_time = (unsigned long) time( NULL ); + cur_time = (unsigned long) mbedtls_time( NULL ); #else cur_time = ctx->serial; #endif diff --git a/app/mbedtls/library/ssl_srv.c b/app/mbedtls/library/ssl_srv.c index 86cf5d85..37f415dd 100644 --- a/app/mbedtls/library/ssl_srv.c +++ b/app/mbedtls/library/ssl_srv.c @@ -27,6 +27,14 @@ #if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + #include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" @@ -37,16 +45,8 @@ #include "mbedtls/ecp.h" #endif -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - #if defined(MBEDTLS_HAVE_TIME) -#include +#include "mbedtls/platform_time.h" #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -101,6 +101,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, if( servername_list_size + 2 != 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 ); } @@ -111,6 +113,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, if( hostname_len + 3 > servername_list_size ) { 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 ); } @@ -135,6 +139,8 @@ static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, if( servername_list_size != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -146,8 +152,6 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { - int ret; - #if defined(MBEDTLS_SSL_RENEGOTIATION) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) { @@ -158,10 +162,8 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, ssl->verify_data_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } } @@ -171,10 +173,8 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, if( len != 1 || buf[0] != 0x0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -186,47 +186,84 @@ static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + +/* + * Status of the implementation of signature-algorithms extension: + * + * Currently, we are only considering the signature-algorithm extension + * to pick a ciphersuite which allows us to send the ServerKeyExchange + * message with a signature-hash combination that the user allows. + * + * We do *not* check whether all certificates in our certificate + * chain are signed with an allowed signature-hash pair. + * This needs to be done at a later stage. + * + */ static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) { size_t sig_alg_list_size; + const unsigned char *p; const unsigned char *end = buf + len; - const int *md_cur; + mbedtls_md_type_t md_cur; + mbedtls_pk_type_t sig_cur; sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); if( sig_alg_list_size + 2 != len || sig_alg_list_size % 2 != 0 ) { 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 ); } - /* - * For now, ignore the SignatureAlgorithm part and rely on offered - * ciphersuites only for that part. To be fixed later. + /* Currently we only guarantee signing the ServerKeyExchange message according + * to the constraints specified in this extension (see above), so it suffices + * to remember only one suitable hash for each possible signature algorithm. * - * So, just look at the HashAlgorithm part. + * This will change when we also consider certificate signatures, + * in which case we will need to remember the whole signature-hash + * pair list from the extension. */ - for( md_cur = ssl->conf->sig_hashes; *md_cur != MBEDTLS_MD_NONE; md_cur++ ) { - for( p = buf + 2; p < end; p += 2 ) { - if( *md_cur == (int) mbedtls_ssl_md_alg_from_hash( p[0] ) ) { - ssl->handshake->sig_alg = p[0]; - goto have_sig_alg; - } + + for( p = buf + 2; p < end; p += 2 ) + { + /* Silently ignore unknown signature or hash algorithms. */ + + if( ( sig_cur = mbedtls_ssl_pk_alg_from_sig( p[1] ) ) == MBEDTLS_PK_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext" + " unknown sig alg encoding %d", p[1] ) ); + continue; + } + + /* Check if we support the hash the user proposes */ + md_cur = mbedtls_ssl_md_alg_from_hash( p[0] ); + if( md_cur == MBEDTLS_MD_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" + " unknown hash alg encoding %d", p[0] ) ); + continue; + } + + if( mbedtls_ssl_check_sig_hash( ssl, md_cur ) == 0 ) + { + mbedtls_ssl_sig_hash_set_add( &ssl->handshake->hash_algs, sig_cur, md_cur ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext:" + " match sig %d and hash %d", + sig_cur, md_cur ) ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: " + "hash alg %d not supported", md_cur ) ); } } - /* Some key echanges do not need signatures at all */ - MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) ); - return( 0 ); - -have_sig_alg: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", - ssl->handshake->sig_alg ) ); - return( 0 ); } #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && @@ -247,6 +284,8 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, list_size % 2 != 0 ) { 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 ); } @@ -254,6 +293,8 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, if( ssl->handshake->curves != NULL ) { 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 ); } @@ -264,7 +305,11 @@ static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, our_size = MBEDTLS_ECP_DP_MAX; if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } ssl->handshake->curves = curves; @@ -297,6 +342,8 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, if( list_size + 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 ); } @@ -342,6 +389,8 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, buf, len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( ret ); } @@ -360,6 +409,8 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -377,6 +428,8 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, if( len != 0 ) { 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 ); } @@ -397,6 +450,8 @@ static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, if( len != 0 ) { 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 ); } @@ -420,6 +475,8 @@ static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, if( len != 0 ) { 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 ); } @@ -531,11 +588,19 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ if( len < 4 ) + { + 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_len = ( buf[0] << 8 ) | buf[1]; if( list_len != len - 2 ) + { + 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 ); + } /* * Use our order of preference @@ -549,13 +614,21 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, { /* If the list is well formed, we should get equality first */ if( theirs > end ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } cur_len = *theirs++; /* Empty strings MUST NOT be included */ if( cur_len == 0 ) + { + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } if( cur_len == ours_len && memcmp( theirs, *ours, cur_len ) == 0 ) @@ -607,7 +680,8 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) { mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; - mbedtls_pk_type_t pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); + mbedtls_pk_type_t pk_alg = + mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); uint32_t flags; #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) @@ -710,6 +784,11 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, { const mbedtls_ssl_ciphersuite_t *suite_info; +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + mbedtls_pk_type_t sig_type; +#endif + suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); if( suite_info == NULL ) { @@ -776,6 +855,25 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, } #endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + /* If the ciphersuite requires signing, check whether + * a suitable hash algorithm is present. */ + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + sig_type = mbedtls_ssl_get_ciphersuite_sig_alg( suite_info ); + if( sig_type != MBEDTLS_PK_NONE && + mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, sig_type ) == MBEDTLS_MD_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no suitable hash algorithm " + "for signature algorithm %d", sig_type ) ); + return( 0 ); + } + } + +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + #if defined(MBEDTLS_X509_CRT_PARSE_C) /* * Final check: if ciphersuite requires us to have a @@ -813,10 +911,8 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -962,9 +1058,8 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " "during renegotiation" ) ); - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif /* MBEDTLS_SSL_RENEGOTIATION */ @@ -1002,11 +1097,9 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) ciphersuite_info = NULL; #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) - { for( i = 0; ciphersuites[i] != 0; i++ ) #else for( i = 0; ciphersuites[i] != 0; i++ ) - { for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) #endif { @@ -1024,7 +1117,6 @@ static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) if( ciphersuite_info != NULL ) goto have_ciphersuite_v2; } - } if( got_common_suite ) { @@ -1043,7 +1135,6 @@ have_ciphersuite_v2: ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); /* * SSLv2 Client Hello relevant renegotiation security checks @@ -1052,10 +1143,8 @@ have_ciphersuite_v2: ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1068,6 +1157,9 @@ have_ciphersuite_v2: } #endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ +/* This function doesn't alert on errors that happen early during + ClientHello parsing because they might indicate that the client is + not talking SSL/TLS at all and would not understand our alert. */ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) { int ret, got_common_suite; @@ -1086,6 +1178,15 @@ static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) const mbedtls_ssl_ciphersuite_t *ciphersuite_info; int major, minor; + /* If there is no signature-algorithm extension present, + * we need to fall back to the default values for allowed + * signature-hash pairs. */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + int sig_hash_alg_ext_present = 0; +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) @@ -1102,6 +1203,7 @@ read_record_header: { if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) { + /* No alert on a read error. */ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); } @@ -1114,7 +1216,7 @@ read_record_header: if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) #endif if( ( buf[0] & 0x80 ) != 0 ) - return ssl_parse_client_hello_v2( ssl ); + return( ssl_parse_client_hello_v2( ssl ) ); #endif MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); @@ -1205,7 +1307,8 @@ read_record_header: return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } - if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) + if( ( ret = mbedtls_ssl_fetch_input( ssl, + mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); @@ -1353,10 +1456,8 @@ read_record_header: " [%d:%d] < [%d:%d]", ssl->major_ver, ssl->minor_ver, ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); - mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); - return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); } @@ -1384,6 +1485,8 @@ read_record_header: sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ { 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 ); } @@ -1407,6 +1510,8 @@ read_record_header: if( cookie_offset + 1 + cookie_len + 2 > msg_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_PROTOCOL_VERSION ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1439,6 +1544,7 @@ read_record_header: /* We know we didn't send a cookie, so it should be empty */ if( cookie_len != 0 ) { + /* This may be an attacker's probe, so don't send an alert */ MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1463,6 +1569,8 @@ read_record_header: ( ciph_len % 2 ) != 0 ) { 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 ); } @@ -1481,6 +1589,8 @@ read_record_header: comp_len + comp_offset + 1 > msg_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 ); } @@ -1505,195 +1615,209 @@ read_record_header: ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; #endif - /* - * Check the extension length - */ - ext_offset = comp_offset + 1 + comp_len; - if( msg_len > ext_offset ) + /* Do not parse the extensions if the protocol is SSLv3 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) { - if( msg_len < ext_offset + 2 ) +#endif + /* + * Check the extension length + */ + ext_offset = comp_offset + 1 + comp_len; + if( msg_len > ext_offset ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + if( msg_len < ext_offset + 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 ); + } + + ext_len = ( buf[ext_offset + 0] << 8 ) + | ( buf[ext_offset + 1] ); + + if( ( ext_len > 0 && ext_len < 4 ) || + msg_len != ext_offset + 2 + ext_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 ); + } } + else + ext_len = 0; - ext_len = ( buf[ext_offset + 0] << 8 ) - | ( buf[ext_offset + 1] ); + ext = buf + ext_offset + 2; + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); - if( ( ext_len > 0 && ext_len < 4 ) || - msg_len != ext_offset + 2 + ext_len ) + while( ext_len != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - } - else - ext_len = 0; + unsigned int ext_id = ( ( ext[0] << 8 ) + | ( ext[1] ) ); + unsigned int ext_size = ( ( ext[2] << 8 ) + | ( ext[3] ) ); - ext = buf + ext_offset + 2; - MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); - - while( ext_len != 0 ) - { - unsigned int ext_id = ( ( ext[0] << 8 ) - | ( ext[1] ) ); - unsigned int ext_size = ( ( ext[2] << 8 ) - | ( ext[3] ) ); - - if( ext_size + 4 > ext_len ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); - } - switch( ext_id ) - { + if( ext_size + 4 > ext_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 ); + } + switch( ext_id ) + { #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - case MBEDTLS_TLS_EXT_SERVERNAME: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); - if( ssl->conf->f_sni == NULL ) - break; + case MBEDTLS_TLS_EXT_SERVERNAME: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); + if( ssl->conf->f_sni == NULL ) + break; - ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ - case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); + case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); #if defined(MBEDTLS_SSL_RENEGOTIATION) - renegotiation_info_seen = 1; + renegotiation_info_seen = 1; #endif - ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) - case MBEDTLS_TLS_EXT_SIG_ALG: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) - break; -#endif + case MBEDTLS_TLS_EXT_SIG_ALG: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); - ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + + sig_hash_alg_ext_present = 1; + break; #endif /* MBEDTLS_SSL_PROTO_TLS1_2 && MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); + case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); - ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; - case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); - ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; + case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); + ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; - ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) - case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) ); + case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) ); - ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) - case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); + case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); - ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) - case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); + case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); - ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) - case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); + case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); - ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) - case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); + case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); - ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) - case MBEDTLS_TLS_EXT_SESSION_TICKET: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); + case MBEDTLS_TLS_EXT_SESSION_TICKET: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); - ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ #if defined(MBEDTLS_SSL_ALPN) - case MBEDTLS_TLS_EXT_ALPN: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + case MBEDTLS_TLS_EXT_ALPN: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); - ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); - if( ret != 0 ) - return( ret ); - break; + ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; #endif /* MBEDTLS_SSL_SESSION_TICKETS */ - default: - MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", - ext_id ) ); - } + default: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", + ext_id ) ); + } - ext_len -= 4 + ext_size; - ext += 4 + ext_size; + ext_len -= 4 + ext_size; + ext += 4 + ext_size; - if( ext_len > 0 && ext_len < 4 ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + if( ext_len > 0 && 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 ); + } } +#if defined(MBEDTLS_SSL_PROTO_SSL3) } +#endif #if defined(MBEDTLS_SSL_FALLBACK_SCSV) - for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 ) + for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) { if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) @@ -1715,6 +1839,26 @@ read_record_header: } #endif /* MBEDTLS_SSL_FALLBACK_SCSV */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + + /* + * Try to fall back to default hash SHA1 if the client + * hasn't provided any preferred signature-hash combinations. + */ + if( sig_hash_alg_ext_present == 0 ) + { + mbedtls_md_type_t md_default = MBEDTLS_MD_SHA1; + + if( mbedtls_ssl_check_sig_hash( ssl, md_default ) != 0 ) + md_default = MBEDTLS_MD_NONE; + + mbedtls_ssl_sig_hash_set_const_hash( &ssl->handshake->hash_algs, md_default ); + } + +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + /* * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ @@ -1726,11 +1870,10 @@ read_record_header: #if defined(MBEDTLS_SSL_RENEGOTIATION) if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); - - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " + "during renegotiation" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } #endif @@ -1774,9 +1917,8 @@ read_record_header: if( handshake_failure == 1 ) { - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); } @@ -1790,11 +1932,9 @@ read_record_header: ciphersuite_info = NULL; #if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) - { for( i = 0; ciphersuites[i] != 0; i++ ) #else for( i = 0; ciphersuites[i] != 0; i++ ) - { for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) #endif { @@ -1811,19 +1951,20 @@ read_record_header: if( ciphersuite_info != NULL ) goto have_ciphersuite; } - } if( got_common_suite ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " "but none of them usable" ) ); - mbedtls_ssl_send_fatal_handshake_failure( ssl ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); } else { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - mbedtls_ssl_send_fatal_handshake_failure( ssl ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); } @@ -1832,7 +1973,6 @@ have_ciphersuite: ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; - mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); ssl->state++; @@ -1841,6 +1981,28 @@ have_ciphersuite: mbedtls_ssl_recv_flight_completed( ssl ); #endif + /* Debugging-only output for testsuite */ +#if defined(MBEDTLS_DEBUG_C) && \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + mbedtls_pk_type_t sig_alg = mbedtls_ssl_get_ciphersuite_sig_alg( ciphersuite_info ); + if( sig_alg != MBEDTLS_PK_NONE ) + { + mbedtls_md_type_t md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, + sig_alg ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", + mbedtls_ssl_hash_from_md_alg( md_alg ) ) ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "no hash algorithm for signature algorithm " + "%d - should not happen", sig_alg ) ); + } + } +#endif + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); return( 0 ); @@ -2210,7 +2372,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) { #if defined(MBEDTLS_HAVE_TIME) - time_t t; + mbedtls_time_t t; #endif int ret; size_t olen, ext_len = 0, n; @@ -2253,7 +2415,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) buf[4], buf[5] ) ); #if defined(MBEDTLS_HAVE_TIME) - t = time( NULL ); + t = mbedtls_time( NULL ); *p++ = (unsigned char)( t >> 24 ); *p++ = (unsigned char)( t >> 16 ); *p++ = (unsigned char)( t >> 8 ); @@ -2302,7 +2464,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ssl->state++; #if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = time( NULL ); + ssl->session_negotiate->start = mbedtls_time( NULL ); #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -2361,6 +2523,12 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", ssl->session_negotiate->compression ) ); + /* Do not write the extensions if the protocol is SSLv3 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) + { +#endif + /* * First write extensions, then the total length */ @@ -2417,6 +2585,10 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) p += ext_len; } +#if defined(MBEDTLS_SSL_PROTO_SSL3) + } +#endif + ssl->out_msglen = p - buf; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; @@ -2430,11 +2602,14 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); @@ -2456,7 +2631,8 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; size_t dn_size, total_dn_size; /* excluding length bytes */ size_t ct_len, sa_len; /* including length bytes */ unsigned char *buf, *p; @@ -2536,29 +2712,27 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) */ if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - /* - * Only use current running hash algorithm that is already required - * for requested ciphersuite. - */ - ssl->handshake->verify_sig_alg = MBEDTLS_SSL_HASH_SHA256; - - if( ssl->transform_negotiate->ciphersuite_info->mac == - MBEDTLS_MD_SHA384 ) - { - ssl->handshake->verify_sig_alg = MBEDTLS_SSL_HASH_SHA384; - } + const int *cur; /* * Supported signature algorithms */ + for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) + { + unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); + + if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) + continue; + #if defined(MBEDTLS_RSA_C) - p[2 + sa_len++] = ssl->handshake->verify_sig_alg; - p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; + p[2 + sa_len++] = hash; + p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; #endif #if defined(MBEDTLS_ECDSA_C) - p[2 + sa_len++] = ssl->handshake->verify_sig_alg; - p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; + p[2 + sa_len++] = hash; + p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; #endif + } p[0] = (unsigned char)( sa_len >> 8 ); p[1] = (unsigned char)( sa_len ); @@ -2572,35 +2746,40 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) * opaque DistinguishedName<1..2^16-1>; */ p += 2; -#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) - if( ssl->handshake->sni_ca_chain != NULL ) - crt = ssl->handshake->sni_ca_chain; - else -#endif - crt = ssl->conf->ca_chain; total_dn_size = 0; - while( crt != NULL && crt->version != 0 ) + + if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) { - dn_size = crt->subject_raw.len; +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_ca_chain != NULL ) + crt = ssl->handshake->sni_ca_chain; + else +#endif + crt = ssl->conf->ca_chain; - if( end < p || - (size_t)( end - p ) < dn_size || - (size_t)( end - p ) < 2 + dn_size ) + while( crt != NULL && crt->version != 0 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); - break; + dn_size = crt->subject_raw.len; + + if( end < p || + (size_t)( end - p ) < dn_size || + (size_t)( end - p ) < 2 + dn_size ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); + break; + } + + *p++ = (unsigned char)( dn_size >> 8 ); + *p++ = (unsigned char)( dn_size ); + memcpy( p, crt->subject_raw.p, dn_size ); + p += dn_size; + + MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); + + total_dn_size += 2 + dn_size; + crt = crt->next; } - - *p++ = (unsigned char)( dn_size >> 8 ); - *p++ = (unsigned char)( dn_size ); - memcpy( p, crt->subject_raw.p, dn_size ); - p += dn_size; - - MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); - - total_dn_size += 2 + dn_size; - crt = crt->next; } ssl->out_msglen = p - buf; @@ -2617,7 +2796,9 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ @@ -2652,73 +2833,81 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#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, len; - ((void) dig_signed); - ((void) dig_signed_len); - ((void) len); -#endif + size_t dig_signed_len = 0; +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); -#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) - { - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); - ssl->state++; - return( 0 ); - } -#endif + /* + * + * Part 1: Extract static ECDH parameters and abort + * if ServerKeyExchange not needed. + * + */ -#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + /* 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 */ + /* 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 +#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */ + /* + * + * Part 2: Provide key exchange parameters for chosen ciphersuite. + * + */ + + /* + * - ECJPAKE key exchanges + */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) { - size_t jlen; const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, - p, end - p, &jlen, ssl->conf->f_rng, ssl->conf->p_rng ); + p, end - p, &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 += jlen; - n += jlen; + p += len; + n += len; } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + /* + * For (EC)DHE key exchanges with PSK, parameters are prefixed by support + * identity hint (RFC 4279, Sec. 3). Until someone needs this feature, + * we use empty support identity hints here. + **/ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) { - /* TODO: Support identity hints */ *(p++) = 0x00; *(p++) = 0x00; @@ -2727,10 +2916,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + /* + * - DHE key exchanges + */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED) + if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) ) { if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) { @@ -2762,8 +2952,10 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) return( ret ); } +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) dig_signed = p; dig_signed_len = len; +#endif p += len; n += len; @@ -2773,13 +2965,13 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED */ + /* + * - ECDHE key exchanges + */ #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + if( mbedtls_ssl_ciphersuite_uses_ecdhe( ciphersuite_info ) ) { /* * Ephemeral ECDH parameters: @@ -2822,8 +3014,10 @@ curve_matching_done: return( ret ); } - dig_signed = p; +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) + dig_signed = p; dig_signed_len = len; +#endif p += len; n += len; @@ -2832,29 +3026,44 @@ curve_matching_done: } #endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ -#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) - if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || - ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + /* + * + * Part 3: 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]; - mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; /* - * Choose hash algorithm. NONE means MD5 + SHA1 here. + * 3.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 + * (RFC 4492, Sec. 5.4) + * C: Otherwise, use MD5 + SHA1 (RFC 4346, Sec. 7.4.3) */ + + mbedtls_md_type_t md_alg; + #if defined(MBEDTLS_SSL_PROTO_TLS1_2) + mbedtls_pk_type_t sig_alg = + mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->sig_alg ); - - if( md_alg == MBEDTLS_MD_NONE ) + /* A: For TLS 1.2, obey signature-hash-algorithm extension + * (RFC 5246, Sec. 7.4.1.4.1). */ + if( sig_alg == MBEDTLS_PK_NONE || + ( md_alg = mbedtls_ssl_sig_hash_set_find( &ssl->handshake->hash_algs, + sig_alg ) ) == MBEDTLS_MD_NONE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + /* (... because we choose a cipher suite + * only if there is a matching hash.) */ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } } @@ -2862,19 +3071,23 @@ curve_matching_done: #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) - if( ciphersuite_info->key_exchange == - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) { + /* B: Default hash SHA1 */ md_alg = MBEDTLS_MD_SHA1; } else -#endif +#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ + MBEDTLS_SSL_PROTO_TLS1_1 */ { + /* C: MD5 + SHA1 */ md_alg = MBEDTLS_MD_NONE; } + MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) ); + /* - * Compute the hash to be signed + * 3.2: Compute the hash to be signed */ #if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_1) @@ -2899,6 +3112,7 @@ curve_matching_done: * SHA(ClientHello.random + ServerHello.random * + ServerParams); */ + mbedtls_md5_starts( &mbedtls_md5 ); mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 ); mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len ); @@ -2960,7 +3174,7 @@ curve_matching_done: (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); /* - * Make the signature + * 3.3: Compute and add the signature */ if( mbedtls_ssl_own_key( ssl ) == NULL ) { @@ -2971,16 +3185,31 @@ curve_matching_done: #if defined(MBEDTLS_SSL_PROTO_TLS1_2) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) { - *(p++) = ssl->handshake->sig_alg; - *(p++) = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); + /* + * For TLS 1.2, we need to specify signature and hash algorithm + * explicitly through a prefix to the signature. + * + * struct { + * HashAlgorithm hash; + * SignatureAlgorithm signature; + * } SignatureAndHashAlgorithm; + * + * struct { + * SignatureAndHashAlgorithm algorithm; + * opaque signature<0..2^16-1>; + * } DigitallySigned; + * + */ + + *(p++) = mbedtls_ssl_hash_from_md_alg( md_alg ); + *(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg ); n += 2; } #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 ) + p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); return( ret ); @@ -2994,9 +3223,9 @@ curve_matching_done: n += signature_len; } -#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || - MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || - MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ + + /* Done with actual work; add header and send. */ ssl->out_msglen = 4 + n; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; @@ -3238,13 +3467,8 @@ static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned cha if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ) { MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 ) - { - return( ret ); - } - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ); return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ); } @@ -3506,11 +3730,14 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); @@ -3540,7 +3767,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) mbedtls_pk_type_t pk_alg; #endif mbedtls_md_type_t md_alg; - const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); @@ -3556,17 +3784,28 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) return( 0 ); } - /* Needs to be done before read_record() to exclude current message */ - ssl->handshake->calc_verify( ssl, hash ); + /* Read the message without adding it to the checksum */ + do { - if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); + } + + ret = mbedtls_ssl_handle_message_type( ssl ); + + } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ); + + if( 0 != ret ) { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); return( ret ); } ssl->state++; + /* Process the message contents */ if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) { @@ -3613,14 +3852,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) /* * Hash */ - if( ssl->in_msg[i] != ssl->handshake->verify_sig_alg ) + md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); + + if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" " for verify message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } - md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->verify_sig_alg ); +#if !defined(MBEDTLS_MD_SHA1) + if( MBEDTLS_MD_SHA1 == md_alg ) + hash_start += 16; +#endif /* Info from md_alg will be used instead */ hashlen = 0; @@ -3671,6 +3915,9 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); } + /* Calculate hash and verify signature */ + ssl->handshake->calc_verify( ssl, hash ); + if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, md_alg, hash_start, hashlen, ssl->in_msg + i, sig_len ) ) != 0 ) @@ -3679,13 +3926,18 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) return( ret ); } + mbedtls_ssl_update_handshake_status( ssl ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); return( ret ); } #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && - !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) @@ -3860,9 +4112,6 @@ int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) case MBEDTLS_SSL_SERVER_FINISHED: ret = mbedtls_ssl_write_finished( ssl ); -#if defined(ESP8266_PLATFORM) - mbedtls_write_finished(ssl); -#endif break; case MBEDTLS_SSL_FLUSH_BUFFERS: diff --git a/app/mbedtls/library/ssl_ticket.c b/app/mbedtls/library/ssl_ticket.c index 0e27900b..4d9116d2 100644 --- a/app/mbedtls/library/ssl_ticket.c +++ b/app/mbedtls/library/ssl_ticket.c @@ -27,16 +27,16 @@ #if defined(MBEDTLS_SSL_TICKET_C) -#include "mbedtls/ssl_ticket.h" - #if defined(MBEDTLS_PLATFORM_C) #include "mbedtls/platform.h" #else #include #define mbedtls_calloc calloc -#define mbedtls_free free +#define mbedtls_free free #endif +#include "mbedtls/ssl_ticket.h" + #include /* Implementation that should never be optimized out by the compiler */ @@ -69,7 +69,7 @@ static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, mbedtls_ssl_ticket_key *key = ctx->keys + index; #if defined(MBEDTLS_HAVE_TIME) - key->generation_time = (uint32_t) time( NULL ); + key->generation_time = (uint32_t) mbedtls_time( NULL ); #endif if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) @@ -98,7 +98,7 @@ static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) #else if( ctx->ticket_lifetime != 0 ) { - uint32_t current_time = (uint32_t) time( NULL ); + uint32_t current_time = (uint32_t) mbedtls_time( NULL ); uint32_t key_time = ctx->keys[ctx->active].generation_time; if( current_time > key_time && @@ -451,7 +451,7 @@ int mbedtls_ssl_ticket_parse( void *p_ticket, #if defined(MBEDTLS_HAVE_TIME) { /* Check for expiration */ - time_t current_time = time( NULL ); + mbedtls_time_t current_time = mbedtls_time( NULL ); if( current_time < session->start || (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime ) diff --git a/app/mbedtls/library/ssl_tls.c b/app/mbedtls/library/ssl_tls.c index 8a8e7898..5693ed99 100644 --- a/app/mbedtls/library/ssl_tls.c +++ b/app/mbedtls/library/ssl_tls.c @@ -35,25 +35,24 @@ #if defined(MBEDTLS_SSL_TLS_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + #include "mbedtls/debug.h" #include "mbedtls/ssl.h" #include "mbedtls/ssl_internal.h" #include -#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ - defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) +#if defined(MBEDTLS_X509_CRT_PARSE_C) #include "mbedtls/oid.h" #endif -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#else -#include -#define mbedtls_calloc calloc -#define mbedtls_free free -#endif - /* Implementation that should never be optimized out by the compiler */ static void mbedtls_zeroize( void *v, size_t n ) { volatile unsigned char *p = v; while( n-- ) *p++ = 0; @@ -1374,17 +1373,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) /* * Generate IV */ -#if defined(MBEDTLS_SSL_AEAD_RANDOM_IV) - ret = ssl->conf->f_rng( ssl->conf->p_rng, - ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, - ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); - if( ret != 0 ) - return( ret ); - - memcpy( ssl->out_iv, - ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, - ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); -#else if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 ) { /* Reminder if we ever add an AEAD mode with a different size */ @@ -1395,7 +1383,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, ssl->out_ctr, 8 ); memcpy( ssl->out_iv, ssl->out_ctr, 8 ); -#endif MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); @@ -2708,7 +2695,7 @@ void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) */ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) { - int ret, done = 0; + int ret, done = 0, out_msg_type; size_t len = ssl->out_msglen; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); @@ -2724,7 +2711,9 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) #endif if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) { - if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST && + out_msg_type = ssl->out_msg[0]; + + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST && ssl->handshake == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); @@ -2751,7 +2740,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) len += 8; /* Write message_seq and update it, except for HelloRequest */ - if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ) + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) { ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; @@ -2769,7 +2758,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_PROTO_DTLS */ - if( ssl->out_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST ) + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) ssl->handshake->update_checksum( ssl, ssl->out_msg, len ); } @@ -3081,7 +3070,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_PROTO_DTLS */ -static int ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) +int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) { if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) { @@ -3163,6 +3152,12 @@ static int ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); } + return( 0 ); +} + +void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) +{ + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && ssl->handshake != NULL ) { @@ -3177,8 +3172,6 @@ static int ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) ssl->handshake->in_msg_seq++; } #endif - - return( 0 ); } /* @@ -3435,7 +3428,7 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) { - /* Dont check write errors as we can't do anything here. + /* Don't check write errors as we can't do anything here. * If the error is permanent we'll catch it later, * if it's not, then hopefully it'll work next time. */ (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len ); @@ -3480,7 +3473,6 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) */ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) { - int ret; int major_ver, minor_ver; MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); @@ -3501,14 +3493,8 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); - - if( ( ret = mbedtls_ssl_send_alert_message( ssl, - MBEDTLS_SSL_ALERT_LEVEL_FATAL, - MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ) ) != 0 ) - { - return( ret ); - } - + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } @@ -3529,7 +3515,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN - (size_t)( ssl->in_msg - ssl->in_buf ) ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } @@ -3539,7 +3525,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) if( ssl->in_msglen < 1 || ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } } @@ -3547,7 +3533,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) { if( ssl->in_msglen < ssl->transform_in->minlen ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } @@ -3568,7 +3554,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN + 256 ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } #endif @@ -3692,7 +3678,7 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length: in_msglen=%d", ssl->in_msglen ) ); return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } } @@ -3706,10 +3692,6 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); return( ret ); } - - // TODO: what's the purpose of these lines? is in_len used? - ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); - ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); } #endif /* MBEDTLS_ZLIB_SUPPORT */ @@ -3738,31 +3720,156 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); - if( ssl->in_hslen != 0 && ssl->in_hslen < ssl->in_msglen ) + if( ssl->keep_current_message == 0 ) { + do { + + if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); + } + + ret = mbedtls_ssl_handle_message_type( ssl ); + + } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ); + + if( 0 != ret ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); + } + + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) + { + mbedtls_ssl_update_handshake_status( ssl ); + } + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= reuse previously read message" ) ); + ssl->keep_current_message = 0; + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); + + return( 0 ); +} + +int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ) +{ + int ret; + + /* + * Step A + * + * Consume last content-layer message and potentially + * update in_msglen which keeps track of the contents' + * consumption state. + * + * (1) Handshake messages: + * Remove last handshake message, move content + * and adapt in_msglen. + * + * (2) Alert messages: + * Consume whole record content, in_msglen = 0. + * + * NOTE: This needs to be fixed, since like for + * handshake messages it is allowed to have + * multiple alerts witin a single record. + * Internal reference IOTSSL-1321. + * + * (3) Change cipher spec: + * Consume whole record content, in_msglen = 0. + * + * (4) Application data: + * Don't do anything - the record layer provides + * the application data as a stream transport + * and consumes through mbedtls_ssl_read only. + * + */ + + /* Case (1): Handshake messages */ + if( ssl->in_hslen != 0 ) + { + /* Hard assertion to be sure that no application data + * is in flight, as corrupting ssl->in_msglen during + * ssl->in_offt != NULL is fatal. */ + if( ssl->in_offt != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + /* * Get next Handshake message in the current record */ - ssl->in_msglen -= ssl->in_hslen; - memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, - ssl->in_msglen ); + /* Notes: + * (1) in_hslen is *NOT* necessarily the size of the + * current handshake content: If DTLS handshake + * fragmentation is used, that's the fragment + * size instead. Using the total handshake message + * size here is FAULTY and should be changed at + * some point. Internal reference IOTSSL-1414. + * (2) While it doesn't seem to cause problems, one + * has to be very careful not to assume that in_hslen + * is always <= in_msglen in a sensible communication. + * Again, it's wrong for DTLS handshake fragmentation. + * The following check is therefore mandatory, and + * should not be treated as a silently corrected assertion. + * Additionally, ssl->in_hslen might be arbitrarily out of + * bounds after handling a DTLS message with an unexpected + * sequence number, see mbedtls_ssl_prepare_handshake_record. + */ + if( ssl->in_hslen < ssl->in_msglen ) + { + ssl->in_msglen -= ssl->in_hslen; + memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, + ssl->in_msglen ); - MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", - ssl->in_msg, ssl->in_msglen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", + ssl->in_msg, ssl->in_msglen ); + } + else + { + ssl->in_msglen = 0; + } - if( ( ret = ssl_prepare_handshake_record( ssl ) ) != 0 ) - return( ret ); + ssl->in_hslen = 0; + } + /* Case (4): Application data */ + else if( ssl->in_offt != NULL ) + { + return( 0 ); + } + /* Everything else (CCS & Alerts) */ + else + { + ssl->in_msglen = 0; + } + /* + * Step B + * + * Fetch and decode new record if current one is fully consumed. + * + */ + + if( ssl->in_msglen > 0 ) + { + /* There's something left to be processed in the current record. */ return( 0 ); } - ssl->in_hslen = 0; + /* Need to fetch a new record */ - /* - * Read the record header and parse it - */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) read_record_header: +#endif + + /* Current record either fully processed or to be discarded. */ + if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); @@ -3854,6 +3961,12 @@ read_record_header: } #endif + /* As above, invalid records cause + * dismissal of the whole datagram. */ + + ssl->next_record_offset = 0; + ssl->in_left = 0; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); goto read_record_header; } @@ -3916,13 +4029,22 @@ read_record_header: } #endif + return( 0 ); +} + +int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) +{ + int ret; + /* * Handle particular types of records */ if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) { - if( ( ret = ssl_prepare_handshake_record( ssl ) ) != 0 ) + if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) + { return( ret ); + } } if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) @@ -3970,11 +4092,9 @@ read_record_header: #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ /* Silently ignore: fetch new message */ - goto read_record_header; + return MBEDTLS_ERR_SSL_NON_FATAL; } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); - return( 0 ); } @@ -4002,6 +4122,7 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "send alert level=%u message=%u", level, message )); ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; ssl->out_msglen = 2; @@ -4013,7 +4134,6 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); return( ret ); } - MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); return( 0 ); @@ -4029,6 +4149,7 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +/* No certificate support -> dummy functions */ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) { const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; @@ -4068,7 +4189,10 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } + #else +/* Some certificate support -> implement write and parse */ + int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) { int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; @@ -4191,6 +4315,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) size_t i, n; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; int authmode = ssl->conf->authmode; + uint8_t alert; MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); @@ -4230,6 +4355,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { + /* mbedtls_ssl_read_record may have sent an alert already. We + let it decide whether to alert. */ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); return( ret ); } @@ -4251,6 +4378,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); + /* The client was asked for a certificate but didn't send + one. The client should know what's going on, so we + don't send an alert. */ ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) return( 0 ); @@ -4272,6 +4402,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); + /* The client was asked for a certificate but didn't send + one. The client should know what's going on, so we + don't send an alert. */ ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) return( 0 ); @@ -4286,6 +4419,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -4293,6 +4428,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) { 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 ); } @@ -4307,6 +4444,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) { 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 ); } @@ -4322,6 +4461,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", sizeof( mbedtls_x509_crt ) ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } @@ -4334,6 +4475,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( ssl->in_msg[i] != 0 ) { 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 ); } @@ -4344,13 +4487,33 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( n < 128 || i + n > 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 ); } ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, ssl->in_msg + i, n ); - if( ret != 0 ) + switch( ret ) { + case 0: /*ok*/ + case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND: + /* Ignore certificate with an unknown algorithm: maybe a + prior certificate was already trusted. */ + break; + + case MBEDTLS_ERR_X509_ALLOC_FAILED: + alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR; + goto crt_parse_der_failed; + + case MBEDTLS_ERR_X509_UNKNOWN_VERSION: + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + goto crt_parse_der_failed; + + default: + alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; + crt_parse_der_failed: + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert ); MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); return( ret ); } @@ -4371,6 +4534,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( ssl->session->peer_cert == NULL ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } @@ -4381,6 +4546,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ssl->session->peer_cert->raw.len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); } } @@ -4404,12 +4571,6 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ca_crl = ssl->conf->ca_crl; } - if( ca_chain == NULL ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); - return( MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED ); - } - /* * Main check: verify certificate */ @@ -4423,6 +4584,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( ret != 0 ) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "x509_verify_cert flags: %d", ssl->session_negotiate->verify_result ) ); MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); } @@ -4438,6 +4600,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) { + ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); if( ret == 0 ) ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; @@ -4446,8 +4610,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_ECP_C */ if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert, - ciphersuite_info, - ! ssl->conf->endpoint, + ciphersuite_info, + ! ssl->conf->endpoint, &ssl->session_negotiate->verify_result ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); @@ -4455,8 +4619,67 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; } - if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) + /* mbedtls_x509_crt_verify_with_profile is supposed to report a + * verification failure through MBEDTLS_ERR_X509_CERT_VERIFY_FAILED, + * with details encoded in the verification flags. All other kinds + * of error codes, including those from the user provided f_vrfy + * functions, are treated as fatal and lead to a failure of + * ssl_parse_certificate even if verification was optional. */ + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && + ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || + ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) + { ret = 0; + } + + if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); + ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; + } + + if( ret != 0 ) + { + /* The certificate may have been rejected for several reasons. + Pick one and send the corresponding alert. Which alert to send + may be a subject of debate in some cases. */ + if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_OTHER ) + alert = MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_CN_MISMATCH ) + alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_KEY_USAGE ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXT_KEY_USAGE ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NS_CERT_TYPE ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_PK ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_BAD_KEY ) + alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_EXPIRED ) + alert = MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_REVOKED ) + alert = MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED; + else if( ssl->session_negotiate->verify_result & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) + alert = MBEDTLS_SSL_ALERT_MSG_UNKNOWN_CA; + else + alert = MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN; + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + alert ); + } + +#if defined(MBEDTLS_DEBUG_C) + if( ssl->session_negotiate->verify_result != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "! Certificate verification flags %x", + ssl->session_negotiate->verify_result ) ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Certificate verification flags clear" ) ); + } +#endif /* MBEDTLS_DEBUG_C */ } MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); @@ -4509,12 +4732,16 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC ); } @@ -4537,6 +4764,8 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) if( ++ssl->in_epoch == 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); + /* This is highly unlikely to happen for legitimate reasons, so + treat it as an attack and don't send an alert. */ return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); } } @@ -4561,6 +4790,8 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); } } @@ -5015,7 +5246,12 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); - // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63) + /* + * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites + * may define some other value. Currently (early 2016), no defined + * ciphersuite does this (and this is unlikely to change as activity has + * moved to TLS 1.3 now) so we can keep the hardcoded 12 here. + */ hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -5134,6 +5370,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } @@ -5149,6 +5387,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); } @@ -5156,6 +5396,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) buf, hash_len ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); } @@ -5211,7 +5453,11 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ handshake->update_checksum = ssl_update_checksum_start; - handshake->sig_alg = MBEDTLS_SSL_HASH_SHA1; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + mbedtls_ssl_sig_hash_set_init( &handshake->hash_algs ); +#endif #if defined(MBEDTLS_DHM_C) mbedtls_dhm_init( &handshake->dhm_ctx ); @@ -5368,7 +5614,6 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, /* * Prepare base structures */ -#if !defined(ESP8266_PLATFORM) if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL || ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL ) { @@ -5377,16 +5622,6 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, ssl->in_buf = NULL; return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); } -#else - if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) ); - mbedtls_free( ssl->in_buf ); - ssl->in_buf = NULL; - return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); - } - ssl->out_buf = ssl->in_buf; -#endif #if defined(MBEDTLS_SSL_PROTO_DTLS) if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) @@ -5468,7 +5703,8 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) ssl->in_hslen = 0; ssl->nb_zero = 0; - ssl->record_read = 0; + + ssl->keep_current_message = 0; ssl->out_msg = ssl->out_buf + 13; ssl->out_msgtype = 0; @@ -5608,9 +5844,9 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, void *p_bio, - int (*f_send)(void *, const unsigned char *, size_t), - int (*f_recv)(void *, unsigned char *, size_t), - int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) ) + mbedtls_ssl_send_t *f_send, + mbedtls_ssl_recv_t *f_recv, + mbedtls_ssl_recv_timeout_t *f_recv_timeout ) { ssl->p_bio = p_bio; ssl->f_send = f_send; @@ -5625,8 +5861,8 @@ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, - void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms), - int (*f_get_timer)(void *) ) + mbedtls_ssl_set_timer_t *f_set_timer, + mbedtls_ssl_get_timer_t *f_get_timer ) { ssl->p_timer = p_timer; ssl->f_set_timer = f_set_timer; @@ -5780,7 +6016,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, { mbedtls_ecjpake_role role; - if( ssl->handshake == NULL && ssl->conf == NULL ) + if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) @@ -5984,8 +6220,9 @@ int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **prot const char **p; /* - * "Empty strings MUST NOT be included and byte strings MUST NOT be - * truncated". Check lengths now rather than later. + * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings + * MUST NOT be truncated." + * We check lengths now rather than later. */ tot_len = 0; for( p = protos; *p != NULL; p++ ) @@ -6027,6 +6264,14 @@ void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) } #endif +#if defined(MBEDTLS_SSL_SRV_C) +void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, + char cert_req_ca_list ) +{ + conf->cert_req_ca_list = cert_req_ca_list; +} +#endif + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ) { @@ -6299,7 +6544,6 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) return( ret ); } -void mbedtls_handshake_heap(mbedtls_ssl_context *ssl); /* * Perform the SSL handshake @@ -6315,7 +6559,6 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { - //mbedtls_handshake_heap(ssl); ret = mbedtls_ssl_handshake_step( ssl ); if( ret != 0 ) @@ -6461,6 +6704,10 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) */ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) { + size_t ep_len = ssl_ep_len( ssl ); + int in_ctr_cmp; + int out_ctr_cmp; + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) @@ -6468,8 +6715,12 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) return( 0 ); } - if( memcmp( ssl->in_ctr, ssl->conf->renego_period, 8 ) <= 0 && - memcmp( ssl->out_ctr, ssl->conf->renego_period, 8 ) <= 0 ) + in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, + ssl->conf->renego_period + ep_len, 8 - ep_len ); + out_ctr_cmp = memcmp( ssl->out_ctr + ep_len, + ssl->conf->renego_period + ep_len, 8 - ep_len ); + + if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) { return( 0 ); } @@ -6484,7 +6735,7 @@ static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) */ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) { - int ret, record_read = 0; + int ret; size_t n; if( ssl == NULL || ssl->conf == NULL ) @@ -6507,8 +6758,22 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } #endif + /* + * Check if renegotiation is necessary and/or handshake is + * in process. If yes, perform/continue, and fall through + * if an unexpected packet is received while the client + * is waiting for the ServerHello. + * + * (There is no equivalent to the last condition on + * the server-side as it is not treated as within + * a handshake while waiting for the ClientHello + * after a renegotiation request.) + */ + #if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) + ret = ssl_check_ctr_renegotiate( ssl ); + if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && + ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); return( ret ); @@ -6518,17 +6783,49 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) { ret = mbedtls_ssl_handshake( ssl ); - if( ret == MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ) - { - record_read = 1; - } - else if( ret != 0 ) + if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && + ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); return( ret ); } } + /* + * TODO + * + * The logic should be streamlined here: + * + * Instead of + * + * - Manually checking whether ssl->in_offt is NULL + * - Fetching a new record if yes + * - Setting ssl->in_offt if one finds an application record + * - Resetting keep_current_message after handling the application data + * + * one should + * + * - Adapt read_record to set ssl->in_offt automatically + * when a new application data record is processed. + * - Always call mbedtls_ssl_read_record here. + * + * This way, the logic of ssl_read would be much clearer: + * + * (1) Always call record layer and see what kind of record is on + * and have it ready for consumption (in particular, in_offt + * properly set for application data records). + * (2) If it's application data (either freshly fetched + * or something already being partially processed), + * serve the read request from it. + * (3) If it's something different from application data, + * handle it accordingly, e.g. potentially start a + * renegotiation. + * + * This will also remove the need to manually reset + * ssl->keep_current_message = 0 below. + * + */ + if( ssl->in_offt == NULL ) { /* Start timer if not already running */ @@ -6538,16 +6835,13 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) ssl_set_timer( ssl, ssl->conf->read_timeout ); } - if( ! record_read ) + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) { - if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) - return( 0 ); + if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) + return( 0 ); - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); - return( ret ); - } + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); } if( ssl->in_msglen == 0 && @@ -6571,10 +6865,16 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); + /* + * - For client-side, expect SERVER_HELLO_REQUEST. + * - For server-side, expect CLIENT_HELLO. + * - Fail (TLS) or silently drop record (DTLS) in other cases. + */ + #if defined(MBEDTLS_SSL_CLI_C) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || - ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) + ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); @@ -6585,7 +6885,9 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) #endif return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) { @@ -6598,23 +6900,29 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) #endif return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } -#endif +#endif /* MBEDTLS_SSL_SRV_C */ + + /* Determine whether renegotiation attempt should be accepted */ if( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) { + /* + * Refuse renegotiation + */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); #if defined(MBEDTLS_SSL_PROTO_SSL3) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) { - /* - * SSLv3 does not have a "no_renegotiation" alert - */ - if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); + /* SSLv3 does not have a "no_renegotiation" warning, so + we send a fatal alert and abort the connection. */ + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); } else #endif /* MBEDTLS_SSL_PROTO_SSL3 */ @@ -6639,6 +6947,10 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } else { + /* + * Accept renegotiation request + */ + /* DTLS clients need to know renego is server-initiated */ #if defined(MBEDTLS_SSL_PROTO_DTLS) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && @@ -6648,25 +6960,18 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } #endif ret = ssl_start_renegotiation( ssl ); - if( ret == MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ) - { - record_read = 1; - } - else if( ret != 0 ) + if( ret != MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO && + ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); return( ret ); } } - /* If a non-handshake record was read during renego, fallthrough, - * else tell the user they should call mbedtls_ssl_read() again */ - if( ! record_read ) - return( MBEDTLS_ERR_SSL_WANT_READ ); + return( MBEDTLS_ERR_SSL_WANT_READ ); } else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { - if( ssl->conf->renego_max_records >= 0 ) { if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) @@ -6714,7 +7019,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) } } #endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ -#endif +#endif /* MBEDTLS_SSL_PROTO_DTLS */ } n = ( len < ssl->in_msglen ) @@ -6724,11 +7029,16 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) ssl->in_msglen -= n; if( ssl->in_msglen == 0 ) - /* all bytes consumed */ + { + /* all bytes consumed */ ssl->in_offt = NULL; + ssl->keep_current_message = 0; + } else + { /* more data available */ ssl->in_offt += n; + } MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); @@ -6962,7 +7272,8 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ) #endif #endif -#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) /* explicit void pointer cast for buggy MS compiler */ mbedtls_free( (void *) handshake->curves ); #endif @@ -7033,8 +7344,6 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) ); -#if !defined(ESP8266_PLATFORM) - if( ssl->out_buf != NULL ) { mbedtls_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN ); @@ -7046,14 +7355,6 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) mbedtls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN ); mbedtls_free( ssl->in_buf ); } -#else - if( ssl->in_buf != NULL ) - { - mbedtls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN ); - mbedtls_free( ssl->in_buf ); - } - -#endif #if defined(MBEDTLS_ZLIB_SUPPORT) if( ssl->compress_buf != NULL ) @@ -7130,7 +7431,7 @@ static int ssl_preset_default_hashes[] = { MBEDTLS_MD_SHA256, MBEDTLS_MD_SHA224, #endif -#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_SHA1_C) && defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE) MBEDTLS_MD_SHA1, #endif MBEDTLS_MD_NONE @@ -7212,6 +7513,10 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; #endif +#if defined(MBEDTLS_SSL_SRV_C) + conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; +#endif + #if defined(MBEDTLS_SSL_PROTO_DTLS) conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; @@ -7219,8 +7524,8 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_RENEGOTIATION) conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; - memset( conf->renego_period, 0xFF, 7 ); - conf->renego_period[7] = 0x00; + memset( conf->renego_period, 0x00, 2 ); + memset( conf->renego_period + 2, 0xFF, 6 ); #endif #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) @@ -7355,6 +7660,19 @@ unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ) return( MBEDTLS_SSL_SIG_ANON ); } +unsigned char mbedtls_ssl_sig_from_pk_alg( mbedtls_pk_type_t type ) +{ + switch( type ) { + case MBEDTLS_PK_RSA: + return( MBEDTLS_SSL_SIG_RSA ); + case MBEDTLS_PK_ECDSA: + case MBEDTLS_PK_ECKEY: + return( MBEDTLS_SSL_SIG_ECDSA ); + default: + return( MBEDTLS_SSL_SIG_ANON ); + } +} + mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) { switch( sig ) @@ -7373,6 +7691,57 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) } #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + +/* Find an entry in a signature-hash set matching a given hash algorithm. */ +mbedtls_md_type_t mbedtls_ssl_sig_hash_set_find( mbedtls_ssl_sig_hash_set_t *set, + mbedtls_pk_type_t sig_alg ) +{ + switch( sig_alg ) + { + case MBEDTLS_PK_RSA: + return( set->rsa ); + case MBEDTLS_PK_ECDSA: + return( set->ecdsa ); + default: + return( MBEDTLS_MD_NONE ); + } +} + +/* Add a signature-hash-pair to a signature-hash set */ +void mbedtls_ssl_sig_hash_set_add( mbedtls_ssl_sig_hash_set_t *set, + mbedtls_pk_type_t sig_alg, + mbedtls_md_type_t md_alg ) +{ + switch( sig_alg ) + { + case MBEDTLS_PK_RSA: + if( set->rsa == MBEDTLS_MD_NONE ) + set->rsa = md_alg; + break; + + case MBEDTLS_PK_ECDSA: + if( set->ecdsa == MBEDTLS_MD_NONE ) + set->ecdsa = md_alg; + break; + + default: + break; + } +} + +/* Allow exactly one hash algorithm for each signature. */ +void mbedtls_ssl_sig_hash_set_const_hash( mbedtls_ssl_sig_hash_set_t *set, + mbedtls_md_type_t md_alg ) +{ + set->rsa = md_alg; + set->ecdsa = md_alg; +} + +#endif /* MBEDTLS_SSL_PROTO_TLS1_2) && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + /* * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX */ @@ -7574,7 +7943,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, * and, for DTLS, to/from TLS equivalent. * * For TLS this is the identity. - * For DTLS, use one complement (v -> 255 - v, and then map as follows: + * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) */ @@ -7622,4 +7991,46 @@ void mbedtls_ssl_read_version( int *major, int *minor, int transport, } } +int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) +{ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + + switch( md ) + { +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_SSL_HASH_MD5: + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_SSL_HASH_SHA1: + ssl->handshake->calc_verify = ssl_calc_verify_tls; + break; +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_SSL_HASH_SHA384: + ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_SSL_HASH_SHA256: + ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; + break; +#endif + default: + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + } + + return 0; +#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ + (void) ssl; + (void) md; + + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/app/mbedtls/library/threading.c b/app/mbedtls/library/threading.c index 1b6d9cd4..07586756 100644 --- a/app/mbedtls/library/threading.c +++ b/app/mbedtls/library/threading.c @@ -40,10 +40,11 @@ static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) { - if( mutex == NULL ) + if( mutex == NULL || !mutex->is_valid ) return; (void) pthread_mutex_destroy( &mutex->mutex ); + mutex->is_valid = 0; } static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) diff --git a/app/mbedtls/library/timing.c b/app/mbedtls/library/timing.c index 5d8b25b9..a7c7ff02 100644 --- a/app/mbedtls/library/timing.c +++ b/app/mbedtls/library/timing.c @@ -38,6 +38,11 @@ #if !defined(MBEDTLS_TIMING_ALT) +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) +#error "This module only works on Unix and Windows, see MBEDTLS_TIMING_C in config.h" +#endif + #ifndef asm #define asm __asm #endif diff --git a/app/mbedtls/library/version_features.c b/app/mbedtls/library/version_features.c index 1575e093..5cbe8aca 100644 --- a/app/mbedtls/library/version_features.c +++ b/app/mbedtls/library/version_features.c @@ -36,6 +36,9 @@ static const char *features[] = { #if defined(MBEDTLS_HAVE_ASM) "MBEDTLS_HAVE_ASM", #endif /* MBEDTLS_HAVE_ASM */ +#if defined(MBEDTLS_NO_UDBL_DIVISION) + "MBEDTLS_NO_UDBL_DIVISION", +#endif /* MBEDTLS_NO_UDBL_DIVISION */ #if defined(MBEDTLS_HAVE_SSE2) "MBEDTLS_HAVE_SSE2", #endif /* MBEDTLS_HAVE_SSE2 */ @@ -54,6 +57,9 @@ static const char *features[] = { #if defined(MBEDTLS_PLATFORM_EXIT_ALT) "MBEDTLS_PLATFORM_EXIT_ALT", #endif /* MBEDTLS_PLATFORM_EXIT_ALT */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) + "MBEDTLS_PLATFORM_TIME_ALT", +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) "MBEDTLS_PLATFORM_FPRINTF_ALT", #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ @@ -63,6 +69,12 @@ static const char *features[] = { #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) "MBEDTLS_PLATFORM_SNPRINTF_ALT", #endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) + "MBEDTLS_PLATFORM_NV_SEED_ALT", +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#if defined(MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT) + "MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT", +#endif /* MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT */ #if defined(MBEDTLS_DEPRECATED_WARNING) "MBEDTLS_DEPRECATED_WARNING", #endif /* MBEDTLS_DEPRECATED_WARNING */ @@ -111,6 +123,9 @@ static const char *features[] = { #if defined(MBEDTLS_SHA512_ALT) "MBEDTLS_SHA512_ALT", #endif /* MBEDTLS_SHA512_ALT */ +#if defined(MBEDTLS_ECP_ALT) + "MBEDTLS_ECP_ALT", +#endif /* MBEDTLS_ECP_ALT */ #if defined(MBEDTLS_MD2_PROCESS_ALT) "MBEDTLS_MD2_PROCESS_ALT", #endif /* MBEDTLS_MD2_PROCESS_ALT */ @@ -153,6 +168,36 @@ static const char *features[] = { #if defined(MBEDTLS_AES_DECRYPT_ALT) "MBEDTLS_AES_DECRYPT_ALT", #endif /* MBEDTLS_AES_DECRYPT_ALT */ +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + "MBEDTLS_ECP_INTERNAL_ALT", +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + "MBEDTLS_ECP_RANDOMIZE_JAC_ALT", +#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + "MBEDTLS_ECP_ADD_MIXED_ALT", +#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + "MBEDTLS_ECP_DOUBLE_JAC_ALT", +#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + "MBEDTLS_ECP_NORMALIZE_JAC_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", +#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", +#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + "MBEDTLS_ECP_NORMALIZE_MXZ_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ +#if defined(MBEDTLS_TEST_NULL_ENTROPY) + "MBEDTLS_TEST_NULL_ENTROPY", +#endif /* MBEDTLS_TEST_NULL_ENTROPY */ #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) "MBEDTLS_ENTROPY_HARDWARE_ALT", #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ @@ -288,6 +333,9 @@ static const char *features[] = { #if defined(MBEDTLS_ENTROPY_FORCE_SHA256) "MBEDTLS_ENTROPY_FORCE_SHA256", #endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) + "MBEDTLS_ENTROPY_NV_SEED", +#endif /* MBEDTLS_ENTROPY_NV_SEED */ #if defined(MBEDTLS_MEMORY_DEBUG) "MBEDTLS_MEMORY_DEBUG", #endif /* MBEDTLS_MEMORY_DEBUG */ @@ -312,9 +360,6 @@ static const char *features[] = { #if defined(MBEDTLS_SHA256_SMALLER) "MBEDTLS_SHA256_SMALLER", #endif /* MBEDTLS_SHA256_SMALLER */ -#if defined(MBEDTLS_SSL_AEAD_RANDOM_IV) - "MBEDTLS_SSL_AEAD_RANDOM_IV", -#endif /* MBEDTLS_SSL_AEAD_RANDOM_IV */ #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) "MBEDTLS_SSL_ALL_ALERT_MESSAGES", #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ @@ -453,6 +498,9 @@ static const char *features[] = { #if defined(MBEDTLS_CIPHER_C) "MBEDTLS_CIPHER_C", #endif /* MBEDTLS_CIPHER_C */ +#if defined(MBEDTLS_CMAC_C) + "MBEDTLS_CMAC_C", +#endif /* MBEDTLS_CMAC_C */ #if defined(MBEDTLS_CTR_DRBG_C) "MBEDTLS_CTR_DRBG_C", #endif /* MBEDTLS_CTR_DRBG_C */ diff --git a/app/mbedtls/library/x509.c b/app/mbedtls/library/x509.c index ffc3d6c9..e94a8a32 100644 --- a/app/mbedtls/library/x509.c +++ b/app/mbedtls/library/x509.c @@ -53,10 +53,15 @@ #else #include #include -#define mbedtls_free free +#define mbedtls_free free #define mbedtls_calloc calloc -#define mbedtls_printf printf -#define mbedtls_snprintf snprintf +#define mbedtls_printf printf +#define mbedtls_snprintf snprintf +#endif + + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" #endif #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) @@ -75,6 +80,7 @@ #endif #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } +#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } /* * CertificateSerialNumber ::= INTEGER @@ -474,14 +480,111 @@ int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, } } -static int x509_parse_int(unsigned char **p, unsigned n, int *res){ +static int x509_parse_int( unsigned char **p, size_t n, int *res ) +{ *res = 0; - for( ; n > 0; --n ){ - if( ( **p < '0') || ( **p > '9' ) ) return MBEDTLS_ERR_X509_INVALID_DATE; + + for( ; n > 0; --n ) + { + if( ( **p < '0') || ( **p > '9' ) ) + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + *res *= 10; - *res += (*(*p)++ - '0'); + *res += ( *(*p)++ - '0' ); } - return 0; + + return( 0 ); +} + +static int x509_date_is_valid(const mbedtls_x509_time *t) +{ + int ret = MBEDTLS_ERR_X509_INVALID_DATE; + + CHECK_RANGE( 0, 9999, t->year ); + CHECK_RANGE( 0, 23, t->hour ); + CHECK_RANGE( 0, 59, t->min ); + CHECK_RANGE( 0, 59, t->sec ); + + switch( t->mon ) + { + case 1: case 3: case 5: case 7: case 8: case 10: case 12: + CHECK_RANGE( 1, 31, t->day ); + break; + case 4: case 6: case 9: case 11: + CHECK_RANGE( 1, 30, t->day ); + break; + case 2: + CHECK_RANGE( 1, 28 + (t->year % 4 == 0), t->day ); + break; + default: + return( ret ); + } + + return( 0 ); +} + +/* + * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) + * field. + */ +static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, + mbedtls_x509_time *tm ) +{ + int ret; + + /* + * Minimum length is 10 or 12 depending on yearlen + */ + if ( len < yearlen + 8 ) + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + len -= yearlen + 8; + + /* + * Parse year, month, day, hour, minute + */ + CHECK( x509_parse_int( p, yearlen, &tm->year ) ); + if ( 2 == yearlen ) + { + if ( tm->year < 50 ) + tm->year += 100; + + tm->year += 1900; + } + + CHECK( x509_parse_int( p, 2, &tm->mon ) ); + CHECK( x509_parse_int( p, 2, &tm->day ) ); + CHECK( x509_parse_int( p, 2, &tm->hour ) ); + CHECK( x509_parse_int( p, 2, &tm->min ) ); + + /* + * Parse seconds if present + */ + if ( len >= 2 ) + { + CHECK( x509_parse_int( p, 2, &tm->sec ) ); + len -= 2; + } + else + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + + /* + * Parse trailing 'Z' if present + */ + if ( 1 == len && 'Z' == **p ) + { + (*p)++; + len--; + } + + /* + * We should have parsed all characters at this point + */ + if ( 0 != len ) + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + + CHECK( x509_date_is_valid( tm ) ); + + return ( 0 ); } /* @@ -490,10 +593,10 @@ static int x509_parse_int(unsigned char **p, unsigned n, int *res){ * generalTime GeneralizedTime } */ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *time ) + mbedtls_x509_time *tm ) { int ret; - size_t len; + size_t len, year_len; unsigned char tag; if( ( end - *p ) < 1 ) @@ -503,67 +606,38 @@ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, tag = **p; if( tag == MBEDTLS_ASN1_UTC_TIME ) - { - (*p)++; - ret = mbedtls_asn1_get_len( p, end, &len ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - CHECK( x509_parse_int( p, 2, &time->year ) ); - CHECK( x509_parse_int( p, 2, &time->mon ) ); - CHECK( x509_parse_int( p, 2, &time->day ) ); - CHECK( x509_parse_int( p, 2, &time->hour ) ); - CHECK( x509_parse_int( p, 2, &time->min ) ); - if( len > 10 ) - CHECK( x509_parse_int( p, 2, &time->sec ) ); - if( len > 12 && *(*p)++ != 'Z' ) - return( MBEDTLS_ERR_X509_INVALID_DATE ); - - time->year += 100 * ( time->year < 50 ); - time->year += 1900; - - return( 0 ); - } + year_len = 2; else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) - { - (*p)++; - ret = mbedtls_asn1_get_len( p, end, &len ); - - if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); - - CHECK( x509_parse_int( p, 4, &time->year ) ); - CHECK( x509_parse_int( p, 2, &time->mon ) ); - CHECK( x509_parse_int( p, 2, &time->day ) ); - CHECK( x509_parse_int( p, 2, &time->hour ) ); - CHECK( x509_parse_int( p, 2, &time->min ) ); - if( len > 12 ) - CHECK( x509_parse_int( p, 2, &time->sec ) ); - if( len > 14 && *(*p)++ != 'Z' ) - return( MBEDTLS_ERR_X509_INVALID_DATE ); - - return( 0 ); - } + year_len = 4; else return( MBEDTLS_ERR_X509_INVALID_DATE + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + (*p)++; + ret = mbedtls_asn1_get_len( p, end, &len ); + + if( ret != 0 ) + return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); + + return x509_parse_time( p, len, year_len, tm ); } int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) { int ret; size_t len; + int tag_type; if( ( end - *p ) < 1 ) return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - sig->tag = **p; + tag_type = **p; if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); + sig->tag = tag_type; sig->len = len; sig->p = *p; @@ -622,7 +696,7 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50 /* * X.509 Extensions (No parsing of extensions, pointer should - * be either manually updated or extensions should be parsed! + * be either manually updated or extensions should be parsed!) */ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *ext, int tag ) @@ -843,7 +917,7 @@ static int x509_get_current_time( mbedtls_x509_time *now ) static int x509_get_current_time( mbedtls_x509_time *now ) { struct tm *lt; - time_t tt; + mbedtls_time_t tt; int ret = 0; #if defined(MBEDTLS_THREADING_C) @@ -851,7 +925,7 @@ static int x509_get_current_time( mbedtls_x509_time *now ) return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); #endif - tt = time( NULL ); + tt = mbedtls_time( NULL ); lt = gmtime( &tt ); if( lt == NULL ) @@ -961,7 +1035,7 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) */ int mbedtls_x509_self_test( int verbose ) { -#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) int ret; uint32_t flags; mbedtls_x509_crt cacert; diff --git a/app/mbedtls/library/x509_create.c b/app/mbedtls/library/x509_create.c index 823747bc..df20ec8e 100644 --- a/app/mbedtls/library/x509_create.c +++ b/app/mbedtls/library/x509_create.c @@ -30,7 +30,7 @@ #include "mbedtls/x509.h" #include "mbedtls/asn1write.h" #include "mbedtls/oid.h" -#include "c_types.h" + #include typedef struct { @@ -41,7 +41,7 @@ typedef struct { #define ADD_STRLEN( s ) s, sizeof( s ) - 1 -static const x509_attr_descriptor_t x509_attrs[] ICACHE_RODATA_ATTR STORE_ATTR = +static const x509_attr_descriptor_t x509_attrs[] = { { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN }, { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN }, diff --git a/app/mbedtls/library/x509_crl.c b/app/mbedtls/library/x509_crl.c index 125a7739..55d12acd 100644 --- a/app/mbedtls/library/x509_crl.c +++ b/app/mbedtls/library/x509_crl.c @@ -352,14 +352,14 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, return( ret ); } - crl->version++; - - if( crl->version > 2 ) + if( crl->version < 0 || crl->version > 1 ) { mbedtls_x509_crl_free( crl ); return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); } + crl->version++; + if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1, &crl->sig_md, &crl->sig_pk, &crl->sig_opts ) ) != 0 ) @@ -502,14 +502,15 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s { mbedtls_pem_init( &pem ); - /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ - if( buflen == 0 || buf[buflen - 1] != '\0' ) - ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; - else - ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN X509 CRL-----", - "-----END X509 CRL-----", - buf, NULL, 0, &use_len ); + // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated + // string + if( buflen == 0 || buf[buflen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN X509 CRL-----", + "-----END X509 CRL-----", + buf, NULL, 0, &use_len ); if( ret == 0 ) { @@ -524,16 +525,17 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s if( ( ret = mbedtls_x509_crl_parse_der( chain, pem.buf, pem.buflen ) ) != 0 ) { + mbedtls_pem_free( &pem ); return( ret ); } - - mbedtls_pem_free( &pem ); } - else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + else if( is_pem ) { mbedtls_pem_free( &pem ); return( ret ); } + + mbedtls_pem_free( &pem ); } /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte. * And a valid CRL cannot be less than 1 byte anyway. */ diff --git a/app/mbedtls/library/x509_crt.c b/app/mbedtls/library/x509_crt.c index da657453..c6209fb4 100644 --- a/app/mbedtls/library/x509_crt.c +++ b/app/mbedtls/library/x509_crt.c @@ -83,33 +83,28 @@ static void mbedtls_zeroize( void *v, size_t n ) { /* * Default profile */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default ICACHE_RODATA_ATTR = +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = { - /* Hashes from SHA-1 and above */ +#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) + /* Allow SHA-1 (weak, but still safe in controlled environments) */ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) | +#endif + /* Only SHA-2 hashes */ MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), 0xFFFFFFF, /* Any PK alg */ 0xFFFFFFF, /* Any curve */ -#if defined(ESP8266_PLATFORM) - 512, -#else 2048, -#endif }; /* * Next-default profile */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next ICACHE_RODATA_ATTR = +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = { /* Hashes from SHA-256 and above */ -#if defined(ESP8266_PLATFORM) - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | -#endif MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), @@ -126,22 +121,15 @@ const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next ICACHE_RODATA_ATTR #else 0, #endif -#if defined(ESP8266_PLATFORM) - 512, -#else 2048, -#endif }; /* * NSA Suite B Profile */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb ICACHE_RODATA_ATTR = +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = { /* Only SHA-256 and 384 */ -#if defined(ESP8266_PLATFORM) - MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | -#endif MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), /* Only ECDSA */ @@ -530,9 +518,6 @@ static int x509_get_subject_alt_name( unsigned char **p, /* * X.509 v3 extensions * - * TODO: Perform all of the basic constraints tests required by the RFC - * TODO: Set values for undetected extensions to a sane default? - * */ static int x509_get_crt_ext( unsigned char **p, const unsigned char *end, @@ -694,14 +679,9 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char * if( crt == NULL || buf == NULL ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - p = mbedtls_calloc( 1, len = buflen ); - if( p == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - memcpy( p, buf, buflen ); - - crt->raw.p = p; - crt->raw.len = len; + // Use the original buffer until we figure out actual length + p = (unsigned char*) buf; + len = buflen; end = p + len; /* @@ -725,6 +705,18 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char * } crt_end = p + len; + // Create and populate a new buffer for the raw field + crt->raw.len = crt_end - buf; + crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); + if( p == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + memcpy( p, buf, crt->raw.len ); + + // Direct pointers to the new buffer + p += crt->raw.len - len; + end = crt_end = p + len; + /* * TBSCertificate ::= SEQUENCE { */ @@ -756,14 +748,14 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char * return( ret ); } - crt->version++; - - if( crt->version > 3 ) + if( crt->version < 0 || crt->version > 2 ) { mbedtls_x509_crt_free( crt ); return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); } + crt->version++; + if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, &crt->sig_md, &crt->sig_pk, &crt->sig_opts ) ) != 0 ) @@ -979,8 +971,10 @@ int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *bu */ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) { +#if defined(MBEDTLS_PEM_PARSE_C) int success = 0, first_error = 0, total_failed = 0; int buf_format = MBEDTLS_X509_FORMAT_DER; +#endif /* * Check for valid input @@ -998,10 +992,12 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s { buf_format = MBEDTLS_X509_FORMAT_PEM; } -#endif if( buf_format == MBEDTLS_X509_FORMAT_DER ) return mbedtls_x509_crt_parse_der( chain, buf, buflen ); +#else + return mbedtls_x509_crt_parse_der( chain, buf, buflen ); +#endif #if defined(MBEDTLS_PEM_PARSE_C) if( buf_format == MBEDTLS_X509_FORMAT_PEM ) @@ -1074,7 +1070,6 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s success = 1; } } -#endif /* MBEDTLS_PEM_PARSE_C */ if( success ) return( total_failed ); @@ -1082,6 +1077,7 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s return( first_error ); else return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); +#endif /* MBEDTLS_PEM_PARSE_C */ } #if defined(MBEDTLS_FS_IO) @@ -1128,7 +1124,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) p = filename + len; filename[len++] = '*'; - w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, + w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, MAX_PATH - 3 ); if( w_ret == 0 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); @@ -1150,7 +1146,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) p, (int) len - 1, NULL, NULL ); if( w_ret == 0 ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + { + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto cleanup; + } w_ret = mbedtls_x509_crt_parse_file( chain, filename ); if( w_ret < 0 ) @@ -1163,32 +1162,39 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) if( GetLastError() != ERROR_NO_MORE_FILES ) ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; +cleanup: FindClose( hFind ); #else /* _WIN32 */ int t_ret; + int snp_ret; struct stat sb; struct dirent *entry; - char entry_name[255]; + char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; DIR *dir = opendir( path ); if( dir == NULL ) return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); -#if defined(MBEDTLS_THREADING_PTHREAD) +#if defined(MBEDTLS_THREADING_C) if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 ) { closedir( dir ); return( ret ); } -#endif +#endif /* MBEDTLS_THREADING_C */ while( ( entry = readdir( dir ) ) != NULL ) { - mbedtls_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name ); + snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, + "%s/%s", path, entry->d_name ); - if( stat( entry_name, &sb ) == -1 ) + if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) + { + ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; + goto cleanup; + } + else if( stat( entry_name, &sb ) == -1 ) { - closedir( dir ); ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; goto cleanup; } @@ -1204,13 +1210,14 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) else ret += t_ret; } - closedir( dir ); cleanup: -#if defined(MBEDTLS_THREADING_PTHREAD) + closedir( dir ); + +#if defined(MBEDTLS_THREADING_C) if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; -#endif +#endif /* MBEDTLS_THREADING_C */ #endif /* _WIN32 */ @@ -1363,6 +1370,14 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, p = buf; n = size; + if( NULL == crt ) + { + ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); + MBEDTLS_X509_SAFE_SNPRINTF; + + return( (int) ( size - n ) ); + } + ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", prefix, crt->version ); MBEDTLS_X509_SAFE_SNPRINTF; @@ -1481,7 +1496,6 @@ struct x509_crt_verify_string { const char *string; }; -#if 0 static const struct x509_crt_verify_string x509_crt_verify_strings[] = { { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, @@ -1505,31 +1519,6 @@ static const struct x509_crt_verify_string x509_crt_verify_strings[] = { { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, { 0, NULL } }; -#else -static const struct x509_crt_verify_string x509_crt_verify_strings[] = { - { MBEDTLS_X509_BADCERT_EXPIRED, NULL }, - { MBEDTLS_X509_BADCERT_REVOKED, NULL }, - { MBEDTLS_X509_BADCERT_CN_MISMATCH, NULL }, - { MBEDTLS_X509_BADCERT_NOT_TRUSTED, NULL }, - { MBEDTLS_X509_BADCRL_NOT_TRUSTED, NULL }, - { MBEDTLS_X509_BADCRL_EXPIRED, NULL }, - { MBEDTLS_X509_BADCERT_MISSING, NULL }, - { MBEDTLS_X509_BADCERT_SKIP_VERIFY, NULL }, - { MBEDTLS_X509_BADCERT_OTHER, NULL }, - { MBEDTLS_X509_BADCERT_FUTURE, NULL }, - { MBEDTLS_X509_BADCRL_FUTURE, NULL }, - { MBEDTLS_X509_BADCERT_KEY_USAGE, NULL }, - { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, NULL }, - { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, NULL }, - { MBEDTLS_X509_BADCERT_BAD_MD, NULL }, - { MBEDTLS_X509_BADCERT_BAD_PK, NULL }, - { MBEDTLS_X509_BADCERT_BAD_KEY, NULL }, - { MBEDTLS_X509_BADCRL_BAD_MD, NULL }, - { MBEDTLS_X509_BADCRL_BAD_PK, NULL }, - { MBEDTLS_X509_BADCRL_BAD_KEY, NULL }, - { 0, NULL } -}; -#endif int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, uint32_t flags ) @@ -1640,7 +1629,8 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509 } /* - * Check that the given certificate is valid according to the CRL. + * Check that the given certificate is not revoked according to the CRL. + * Skip validation is no CRL for the given CA is present. */ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, mbedtls_x509_crl *crl_list, @@ -1653,12 +1643,6 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, if( ca == NULL ) return( flags ); - /* - * TODO: What happens if no CRL is present? - * Suggestion: Revocation state should be unknown if no CRL is present. - * For backwards compatibility this is not yet implemented. - */ - while( crl_list != NULL ) { if( crl_list->version == 0 || @@ -1926,6 +1910,7 @@ static int x509_crt_verify_top( int check_path_cnt; unsigned char hash[MBEDTLS_MD_MAX_SIZE]; const mbedtls_md_info_t *md_info; + mbedtls_x509_crt *future_past_ca = NULL; if( mbedtls_x509_time_is_past( &child->valid_to ) ) *flags |= MBEDTLS_X509_BADCERT_EXPIRED; @@ -1987,6 +1972,20 @@ static int x509_crt_verify_top( continue; } + if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) || + mbedtls_x509_time_is_future( &trust_ca->valid_from ) ) + { + if ( future_past_ca == NULL ) + future_past_ca = trust_ca; + + continue; + } + + break; + } + + if( trust_ca != NULL || ( trust_ca = future_past_ca ) != NULL ) + { /* * Top of chain is signed by a trusted CA */ @@ -1994,8 +1993,6 @@ static int x509_crt_verify_top( if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 ) *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - - break; } /* @@ -2064,8 +2061,8 @@ static int x509_crt_verify_child( /* path_cnt is 0 for the first intermediate CA */ if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) { - *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); + /* return immediately as the goal is to avoid unbounded recursion */ + return( MBEDTLS_ERR_X509_FATAL_ERROR ); } if( mbedtls_x509_time_is_past( &child->valid_to ) ) @@ -2209,11 +2206,14 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, mbedtls_x509_sequence *cur = NULL; mbedtls_pk_type_t pk_type; - if( profile == NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - *flags = 0; + if( profile == NULL ) + { + ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; + goto exit; + } + if( cn != NULL ) { name = &crt->subject; @@ -2287,7 +2287,7 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, ret = x509_crt_verify_top( crt, parent, ca_crl, profile, pathlen, selfsigned, flags, f_vrfy, p_vrfy ); if( ret != 0 ) - return( ret ); + goto exit; } else { @@ -2302,17 +2302,30 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile, pathlen, selfsigned, flags, f_vrfy, p_vrfy ); if( ret != 0 ) - return( ret ); + goto exit; } else { ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile, pathlen, selfsigned, flags, f_vrfy, p_vrfy ); if( ret != 0 ) - return( ret ); + goto exit; } } +exit: + /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by + * the SSL module for authmode optional, but non-zero return from the + * callback means a fatal error so it shouldn't be ignored */ + if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + + if( ret != 0 ) + { + *flags = (uint32_t) -1; + return( ret ); + } + if( *flags != 0 ) return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); diff --git a/app/mbedtls/library/x509_csr.c b/app/mbedtls/library/x509_csr.c index dbf659b4..26a06db4 100644 --- a/app/mbedtls/library/x509_csr.c +++ b/app/mbedtls/library/x509_csr.c @@ -104,7 +104,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, /* * Check for valid input */ - if( csr == NULL || buf == NULL ) + if( csr == NULL || buf == NULL || buflen == 0 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); mbedtls_x509_csr_init( csr ); @@ -168,14 +168,14 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, return( ret ); } - csr->version++; - - if( csr->version != 1 ) + if( csr->version != 0 ) { mbedtls_x509_csr_free( csr ); return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); } + csr->version++; + /* * subject Name */ @@ -207,6 +207,13 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, /* * attributes [0] Attributes + * + * The list of possible attributes is open-ended, though RFC 2985 + * (PKCS#9) defines a few in section 5.4. We currently don't support any, + * so we just ignore them. This is a safe thing to do as the worst thing + * that could happen is that we issue a certificate that does not match + * the requester's expectations - this cannot cause a violation of our + * signature policies. */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) @@ -214,7 +221,6 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, mbedtls_x509_csr_free( csr ); return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } - // TODO Parse Attributes / extension requests p += len; @@ -259,8 +265,8 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, */ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) { - int ret; #if defined(MBEDTLS_PEM_PARSE_C) + int ret; size_t use_len; mbedtls_pem_context pem; #endif @@ -268,14 +274,14 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz /* * Check for valid input */ - if( csr == NULL || buf == NULL ) + if( csr == NULL || buf == NULL || buflen == 0 ) 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( buflen == 0 || buf[buflen - 1] != '\0' ) + if( buf[buflen - 1] != '\0' ) ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; else ret = mbedtls_pem_read_buffer( &pem, diff --git a/app/mbedtls/library/x509write_crt.c b/app/mbedtls/library/x509write_crt.c index 9041d440..4d674abc 100644 --- a/app/mbedtls/library/x509write_crt.c +++ b/app/mbedtls/library/x509write_crt.c @@ -264,7 +264,7 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, } static int x509_write_time( unsigned char **p, unsigned char *start, - const char *time, size_t size ) + const char *t, size_t size ) { int ret; size_t len = 0; @@ -272,10 +272,10 @@ static int x509_write_time( unsigned char **p, unsigned char *start, /* * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) */ - if( time[0] == '2' && time[1] == '0' && time [2] < '5' ) + if( t[0] == '2' && t[1] == '0' && t[2] < '5' ) { MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) time + 2, + (const unsigned char *) t + 2, size - 2 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) ); @@ -283,7 +283,7 @@ static int x509_write_time( unsigned char **p, unsigned char *start, else { MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, - (const unsigned char *) time, + (const unsigned char *) t, size ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) ); @@ -413,6 +413,9 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, sig_oid, sig_oid_len, sig, sig_len ) ); + if( len > (size_t)( c2 - buf ) ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + c2 -= len; memcpy( c2, c, len ); diff --git a/app/mbedtls/library/x509write_csr.c b/app/mbedtls/library/x509write_csr.c index 0b9a2851..8fd856b2 100644 --- a/app/mbedtls/library/x509write_csr.c +++ b/app/mbedtls/library/x509write_csr.c @@ -213,6 +213,9 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, sig_oid, sig_oid_len, sig, sig_len ) ); + if( len > (size_t)( c2 - buf ) ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + c2 -= len; memcpy( c2, c, len ); diff --git a/app/mbedtls/platform/mbedtls_net.c b/app/mbedtls/platform/mbedtls_net.c index 6231a05d..e58053cf 100644 --- a/app/mbedtls/platform/mbedtls_net.c +++ b/app/mbedtls/platform/mbedtls_net.c @@ -24,7 +24,7 @@ #if defined(MBEDTLS_NET_C) -#include "mbedtls/net.h" +#include "mbedtls/net_sockets.h" #include //