Merge pull request #4778 from leoetlino/update-mbedtls

Externals: Update mbedtls to 2.4.1
This commit is contained in:
Mat M 2017-02-15 11:30:18 -05:00 committed by GitHub
commit 8fd16db80d
104 changed files with 6445 additions and 1270 deletions

View File

@ -10,7 +10,7 @@ set(MBEDTLS_LIBRARIES ${MBEDTLS_LIBRARY} ${MBEDX509_LIBRARY} ${MBEDCRYPTO_LIBRAR
set(CMAKE_REQUIRED_INCLUDES ${MBEDTLS_INCLUDE_DIRS}) set(CMAKE_REQUIRED_INCLUDES ${MBEDTLS_INCLUDE_DIRS})
check_cxx_source_compiles(" check_cxx_source_compiles("
#include <mbedtls/version.h> #include <mbedtls/version.h>
#if MBEDTLS_VERSION_NUMBER < 0x02010100 #if MBEDTLS_VERSION_NUMBER < 0x02040000
#error \"Your mbed TLS version is too old.\" #error \"Your mbed TLS version is too old.\"
#endif #endif
int main() {}" int main() {}"
@ -20,4 +20,4 @@ include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MBEDTLS DEFAULT_MSG find_package_handle_standard_args(MBEDTLS DEFAULT_MSG
MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY MBEDTLS_VERSION_OK) MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY MBEDTLS_VERSION_OK)
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY) mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)

View File

@ -44,6 +44,9 @@ extern "C" {
* \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL. * \return 0 if successful, or MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL.
* *olen is always updated to reflect the amount * *olen is always updated to reflect the amount
* of data that has (or would have) been written. * of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to the maximum
* length representable as a size_t.
* *
* \note Call this function with dlen = 0 to obtain the * \note Call this function with dlen = 0 to obtain the
* required buffer size in *olen * required buffer size in *olen

View File

@ -122,6 +122,7 @@
#define MBEDTLS_HAVE_INT64 #define MBEDTLS_HAVE_INT64
typedef int64_t mbedtls_mpi_sint; typedef int64_t mbedtls_mpi_sint;
typedef uint64_t mbedtls_mpi_uint; typedef uint64_t mbedtls_mpi_uint;
/* mbedtls_t_udbl defined as 128-bit unsigned int */
typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI)));
#define MBEDTLS_HAVE_UDBL #define MBEDTLS_HAVE_UDBL
#else #else

View File

@ -162,10 +162,6 @@
#define MULADDC_INIT \ #define MULADDC_INIT \
asm( \ 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" "xorq %%r8, %%r8 \n\t"
#define MULADDC_CORE \ #define MULADDC_CORE \
@ -181,12 +177,9 @@
"addq $8, %%rdi \n\t" "addq $8, %%rdi \n\t"
#define MULADDC_STOP \ #define MULADDC_STOP \
"movq %%rcx, %0 \n\t" \ : "+c" (c), "+D" (d), "+S" (s) \
"movq %%rdi, %1 \n\t" \ : "b" (b) \
"movq %%rsi, %2 \n\t" \ : "rax", "rdx", "r8" \
: "=m" (c), "=m" (d), "=m" (s) \
: "m" (s), "m" (d), "m" (c), "m" (b) \
: "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \
); );
#endif /* AMD64 */ #endif /* AMD64 */
@ -412,10 +405,11 @@
#endif /* PPC32 */ #endif /* PPC32 */
/* /*
* The Sparc64 assembly is reported to be broken. * The Sparc(64) assembly is reported to be broken.
* Disable it for now, until we're able to fix it. * Disable it for now, until we're able to fix it.
*/ */
#if 0 && defined(__sparc__) && defined(__sparc64__) #if 0 && defined(__sparc__)
#if defined(__sparc64__)
#define MULADDC_INIT \ #define MULADDC_INIT \
asm( \ asm( \
@ -446,9 +440,8 @@
: "g1", "o0", "o1", "o2", "o3", "o4", \ : "g1", "o0", "o1", "o2", "o3", "o4", \
"o5" \ "o5" \
); );
#endif /* SPARCv9 */
#if defined(__sparc__) && !defined(__sparc64__) #else /* __sparc64__ */
#define MULADDC_INIT \ #define MULADDC_INIT \
asm( \ asm( \
@ -480,7 +473,8 @@
"o5" \ "o5" \
); );
#endif /* SPARCv8 */ #endif /* __sparc64__ */
#endif /* __sparc__ */
#if defined(__microblaze__) || defined(microblaze) #if defined(__microblaze__) || defined(microblaze)
@ -562,7 +556,23 @@
#endif /* TriCore */ #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__) #if defined(__thumb__) && !defined(__thumb2__)

View File

@ -3,7 +3,7 @@
* *
* \brief Consistency checks for configuration options * \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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * 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" #error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif #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) #if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites" #error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif #endif
@ -88,6 +93,11 @@
#error "MBEDTLS_ECDSA_C defined, but not all prerequisites" #error "MBEDTLS_ECDSA_C defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_ECJPAKE_C) && \
( !defined(MBEDTLS_ECP_C) || !defined(MBEDTLS_MD_C) )
#error "MBEDTLS_ECJPAKE_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C) #if defined(MBEDTLS_ECDSA_DETERMINISTIC) && !defined(MBEDTLS_HMAC_DRBG_C)
#error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites" #error "MBEDTLS_ECDSA_DETERMINISTIC defined, but not all prerequisites"
#endif #endif
@ -125,6 +135,16 @@
#error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" #error "MBEDTLS_ENTROPY_FORCE_SHA256 defined, but not all prerequisites"
#endif #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) && ( \ #if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) ) !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites" #error "MBEDTLS_GCM_C defined, but not all prerequisites"
@ -187,6 +207,12 @@
#error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" #error "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) && \
( !defined(MBEDTLS_ECJPAKE_C) || !defined(MBEDTLS_SHA256_C) || \
!defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) )
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \ #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) ) ( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" #error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"
@ -235,6 +261,36 @@
#error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously" #error "MBEDTLS_PLATFORM_EXIT_MACRO and MBEDTLS_PLATFORM_STD_EXIT/MBEDTLS_PLATFORM_EXIT_ALT cannot be defined simultaneously"
#endif #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) #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) && !defined(MBEDTLS_PLATFORM_C)
#error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites" #error "MBEDTLS_PLATFORM_FPRINTF_ALT defined, but not all prerequisites"
#endif #endif
@ -331,6 +387,12 @@
#error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites" #error "MBEDTLS_PLATFORM_STD_EXIT defined, but not all prerequisites"
#endif #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) &&\ #if defined(MBEDTLS_PLATFORM_STD_FPRINTF) &&\
!defined(MBEDTLS_PLATFORM_FPRINTF_ALT) !defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
#error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites" #error "MBEDTLS_PLATFORM_STD_FPRINTF defined, but not all prerequisites"
@ -346,11 +408,48 @@
#error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites" #error "MBEDTLS_PLATFORM_STD_SNPRINTF defined, but not all prerequisites"
#endif #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) || \ #if defined(MBEDTLS_RSA_C) && ( !defined(MBEDTLS_BIGNUM_C) || \
!defined(MBEDTLS_OID_C) ) !defined(MBEDTLS_OID_C) )
#error "MBEDTLS_RSA_C defined, but not all prerequisites" #error "MBEDTLS_RSA_C defined, but not all prerequisites"
#endif #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) && \ #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) && \
( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) ) ( !defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_PKCS1_V21) )
#error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" #error "MBEDTLS_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites"

View File

@ -46,7 +46,8 @@
#define MBEDTLS_CIPHER_MODE_STREAM #define MBEDTLS_CIPHER_MODE_STREAM
#endif #endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
#endif #endif
@ -56,6 +57,7 @@
#define MBEDTLS_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ #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_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_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_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */
#define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ #define MBEDTLS_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */
@ -174,6 +176,11 @@ enum {
*/ */
typedef struct mbedtls_cipher_base_t mbedtls_cipher_base_t; 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. * Cipher information. Allows cipher functions to be called in a generic way.
*/ */
@ -239,6 +246,11 @@ typedef struct {
/** Cipher-specific context */ /** Cipher-specific context */
void *cipher_ctx; void *cipher_ctx;
#if defined(MBEDTLS_CMAC_C)
/** CMAC Specific context */
mbedtls_cmac_context_t *cmac_ctx;
#endif
} mbedtls_cipher_context_t; } mbedtls_cipher_context_t;
/** /**

166
Externals/mbedtls/include/mbedtls/cmac.h vendored Normal file
View File

@ -0,0 +1,166 @@
/**
* \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 initialised cipher context.
*
* \param ctx Cipher context
* \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( hmac 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 */

View File

@ -1,7 +1,8 @@
/** /**
* \file config.h * \file compat-1.3.h
* *
* \brief Compatibility names (set of defines) * \brief Compatibility definitions for using mbed TLS with client code written
* for the PolarSSL naming conventions.
* *
* \deprecated Use the new names directly instead * \deprecated Use the new names directly instead
* *

View File

@ -3,6 +3,10 @@
* *
* \brief Configuration options (set of defines) * \brief Configuration options (set of defines)
* *
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
* memory footprint.
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
@ -21,11 +25,6 @@
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*/ */
/*
* This set of compile-time options may be used to enable
* or disable features selectively, and reduce the global
* memory footprint.
*/
#ifndef MBEDTLS_CONFIG_H #ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H #define MBEDTLS_CONFIG_H
@ -72,6 +71,10 @@
* The time does not need to be correct, only time differences are used, * The time does not need to be correct, only time differences are used,
* by contrast with MBEDTLS_HAVE_TIME_DATE * 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 * Comment if your system does not support time functions
*/ */
#define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME
@ -132,10 +135,10 @@
//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS //#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
/** /**
* \def MBEDTLS_PLATFORM_XXX_ALT * \def MBEDTLS_PLATFORM_EXIT_ALT
* *
* Uncomment a macro to let mbed TLS support the function in the platform * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
* abstraction layer. * function in the platform abstraction layer.
* *
* Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
* provide a function "mbedtls_platform_set_printf()" that allows you to set an * provide a function "mbedtls_platform_set_printf()" that allows you to set an
@ -149,13 +152,17 @@
* \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
* MBEDTLS_PLATFORM_XXX_MACRO! * MBEDTLS_PLATFORM_XXX_MACRO!
* *
* Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
*
* Uncomment a macro to enable alternate implementation of specific base * Uncomment a macro to enable alternate implementation of specific base
* platform function * platform function
*/ */
//#define MBEDTLS_PLATFORM_EXIT_ALT //#define MBEDTLS_PLATFORM_EXIT_ALT
//#define MBEDTLS_PLATFORM_TIME_ALT
//#define MBEDTLS_PLATFORM_FPRINTF_ALT //#define MBEDTLS_PLATFORM_FPRINTF_ALT
//#define MBEDTLS_PLATFORM_PRINTF_ALT //#define MBEDTLS_PLATFORM_PRINTF_ALT
//#define MBEDTLS_PLATFORM_SNPRINTF_ALT //#define MBEDTLS_PLATFORM_SNPRINTF_ALT
//#define MBEDTLS_PLATFORM_NV_SEED_ALT
/** /**
* \def MBEDTLS_DEPRECATED_WARNING * \def MBEDTLS_DEPRECATED_WARNING
@ -208,12 +215,12 @@
//#define MBEDTLS_TIMING_ALT //#define MBEDTLS_TIMING_ALT
/** /**
* \def MBEDTLS__MODULE_NAME__ALT * \def MBEDTLS_AES_ALT
* *
* Uncomment a macro to let mbed TLS use your alternate core implementation of * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
* a symmetric crypto or hash module (e.g. platform specific assembly * alternate core implementation of a symmetric crypto or hash module (e.g.
* optimized implementations). Keep in mind that the function prototypes * platform specific assembly optimized implementations). Keep in mind that
* should remain the same. * the function prototypes should remain the same.
* *
* This replaces the whole module. If you only want to replace one of the * This replaces the whole module. If you only want to replace one of the
* functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
@ -241,11 +248,11 @@
//#define MBEDTLS_SHA512_ALT //#define MBEDTLS_SHA512_ALT
/** /**
* \def MBEDTLS__FUNCTION_NAME__ALT * \def MBEDTLS_MD2_PROCESS_ALT
* *
* Uncomment a macro to let mbed TLS use you alternate core implementation of * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
* symmetric crypto or hash function. Keep in mind that function prototypes * alternate core implementation of symmetric crypto or hash function. Keep in
* should remain the same. * mind that function prototypes should remain the same.
* *
* This replaces only one function. The header file from mbed TLS is still * This replaces only one function. The header file from mbed TLS is still
* used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
@ -278,6 +285,23 @@
//#define MBEDTLS_AES_ENCRYPT_ALT //#define MBEDTLS_AES_ENCRYPT_ALT
//#define MBEDTLS_AES_DECRYPT_ALT //#define MBEDTLS_AES_DECRYPT_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 * \def MBEDTLS_ENTROPY_HARDWARE_ALT
* *
@ -364,10 +388,11 @@
//#define MBEDTLS_CIPHER_NULL_CIPHER //#define MBEDTLS_CIPHER_NULL_CIPHER
/** /**
* \def MBEDTLS_CIPHER_PADDING_XXX * \def MBEDTLS_CIPHER_PADDING_PKCS7
* *
* Uncomment or comment macros to add support for specific padding modes * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
* in the cipher layer with cipher modes that support padding (e.g. CBC) * specific padding modes in the cipher layer with cipher modes that support
* padding (e.g. CBC)
* *
* If you disable all padding modes, only full blocks can be used with CBC. * If you disable all padding modes, only full blocks can be used with CBC.
* *
@ -407,10 +432,10 @@
#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES #define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
/** /**
* \def MBEDTLS_ECP_XXXX_ENABLED * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
* *
* Enables specific curves within the Elliptic Curve module. * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
* By default all supported curves are enabled. * module. By default all supported curves are enabled.
* *
* Comment macros to disable the curve and functions for it * Comment macros to disable the curve and functions for it
*/ */
@ -694,6 +719,25 @@
*/ */
#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED #define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
/**
* \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
*
* Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
*
* \warning This is currently experimental. EC J-PAKE support is based on the
* Thread v1.0.0 specification; incompatible changes to the specification
* might still happen. For this reason, this is disabled by default.
*
* Requires: MBEDTLS_ECJPAKE_C
* MBEDTLS_SHA256_C
* MBEDTLS_ECP_DP_SECP256R1_ENABLED
*
* This enables the following ciphersuites (if other requisites are
* enabled as well):
* MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
*/
//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
/** /**
* \def MBEDTLS_PK_PARSE_EC_EXTENDED * \def MBEDTLS_PK_PARSE_EC_EXTENDED
* *
@ -779,6 +823,34 @@
*/ */
//#define MBEDTLS_ENTROPY_FORCE_SHA256 //#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 * \def MBEDTLS_MEMORY_DEBUG
* *
@ -868,18 +940,6 @@
*/ */
//#define MBEDTLS_SHA256_SMALLER //#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 * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
* *
@ -1039,7 +1099,7 @@
* *
* Comment this macro to disable support for SSL 3.0 * 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 * \def MBEDTLS_SSL_PROTO_TLS1
@ -1175,6 +1235,16 @@
*/ */
#define MBEDTLS_SSL_SESSION_TICKETS #define MBEDTLS_SSL_SESSION_TICKETS
/**
* \def MBEDTLS_SSL_EXPORT_KEYS
*
* Enable support for exporting key block and master secret.
* This is required for certain users of TLS, e.g. EAP-TLS.
*
* Comment this macro to disable support for key export
*/
#define MBEDTLS_SSL_EXPORT_KEYS
/** /**
* \def MBEDTLS_SSL_SERVER_NAME_INDICATION * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
* *
@ -1246,6 +1316,8 @@
* If set, the X509 parser will not break-off when parsing an X509 certificate * If set, the X509 parser will not break-off when parsing an X509 certificate
* and encountering an unknown critical extension. * and encountering an unknown critical extension.
* *
* \warning Depending on your PKI use, enabling this can be a security risk!
*
* Uncomment to prevent an error. * Uncomment to prevent an error.
*/ */
//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION //#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
@ -1587,6 +1659,19 @@
*/ */
#define MBEDTLS_CIPHER_C #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 * \def MBEDTLS_CTR_DRBG_C
* *
@ -1686,6 +1771,25 @@
*/ */
#define MBEDTLS_ECDSA_C #define MBEDTLS_ECDSA_C
/**
* \def MBEDTLS_ECJPAKE_C
*
* Enable the elliptic curve J-PAKE library.
*
* \warning This is currently experimental. EC J-PAKE support is based on the
* Thread v1.0.0 specification; incompatible changes to the specification
* might still happen. For this reason, this is disabled by default.
*
* Module: library/ecjpake.c
* Caller:
*
* This module is used by the following key exchanges:
* ECJPAKE
*
* Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
*/
//#define MBEDTLS_ECJPAKE_C
/** /**
* \def MBEDTLS_ECP_C * \def MBEDTLS_ECP_C
* *
@ -1694,6 +1798,7 @@
* Module: library/ecp.c * Module: library/ecp.c
* Caller: library/ecdh.c * Caller: library/ecdh.c
* library/ecdsa.c * library/ecdsa.c
* library/ecjpake.c
* *
* Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
*/ */
@ -1846,11 +1951,19 @@
/** /**
* \def MBEDTLS_NET_C * \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 #define MBEDTLS_NET_C
@ -2196,7 +2309,8 @@
* By default mbed TLS assumes it is used in a non-threaded environment or that * 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 * 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 * 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 * Module: library/threading.c
* *
@ -2213,7 +2327,18 @@
/** /**
* \def MBEDTLS_TIMING_C * \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 * Module: library/timing.c
* Caller: library/havege.c * Caller: library/havege.c
@ -2385,6 +2510,7 @@
/* Entropy options */ /* Entropy options */
//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ //#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_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 */ /* Memory buffer allocator options */
//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ //#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
@ -2394,20 +2520,30 @@
//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ //#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_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_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_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_PRINTF printf /**< Default printf to use, can be undefined */
/* Note: your snprintf must correclty zero-terminate the buffer! */ /* 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_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 */ /* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ /* 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_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_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_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_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_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */
/* Note: your snprintf must correclty zero-terminate the buffer! */ /* 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_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 */ /* SSL Cache options */
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ //#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
@ -2435,11 +2571,15 @@
/* X509 options */ /* X509 options */
//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ //#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 */ /* \} name SECTION: Customisation configuration options */
#if defined(TARGET_LIKE_MBED) /* Target and application specific configurations */
#include "mbedtls/target_config.h" //#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 #endif
/* /*

View File

@ -111,7 +111,7 @@ mbedtls_ctr_drbg_context;
/** /**
* \brief CTR_DRBG context initialization * \brief CTR_DRBG context initialization
* Makes the context ready for mbetls_ctr_drbg_seed() or * Makes the context ready for mbedtls_ctr_drbg_seed() or
* mbedtls_ctr_drbg_free(). * mbedtls_ctr_drbg_free().
* *
* \param ctx CTR_DRBG context to be initialized * \param ctx CTR_DRBG context to be initialized

View File

@ -1,7 +1,7 @@
/** /**
* \file debug.h * \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 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
@ -80,39 +80,141 @@ extern "C" {
#endif #endif
/** /**
* \brief Set the level threshold to handle globally. Messages that have a * \brief Set the threshold error level to handle globally all debug output.
* level over the threshold value are ignored. * Debug messages that have a level over the threshold value are
* (Default value: 0 (No debug)) * 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 ); 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, void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *file, int line,
const char *format, ... ); 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, void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *file, int line,
const char *text, int ret ); 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, void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *text, const char *file, int line, const char *text,
const unsigned char *buf, size_t len ); const unsigned char *buf, size_t len );
#if defined(MBEDTLS_BIGNUM_C) #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, void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *file, int line,
const char *text, const mbedtls_mpi *X ); const char *text, const mbedtls_mpi *X );
#endif #endif
#if defined(MBEDTLS_ECP_C) #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, void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *file, int line,
const char *text, const mbedtls_ecp_point *X ); const char *text, const mbedtls_ecp_point *X );
#endif #endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) #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, void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level,
const char *file, int line, const char *file, int line,
const char *text, const mbedtls_x509_crt *crt ); 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
#endif /* debug.h */ #endif /* debug.h */

View File

@ -221,7 +221,7 @@ int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
* \param ctx DHM context * \param ctx DHM context
* \param x_size private value size in bytes * \param x_size private value size in bytes
* \param output destination buffer * \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 f_rng RNG function
* \param p_rng RNG parameter * \param p_rng RNG parameter
* *

View File

@ -0,0 +1,238 @@
/**
* \file ecjpake.h
*
* \brief Elliptic curve J-PAKE
*
* 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_ECJPAKE_H
#define MBEDTLS_ECJPAKE_H
/*
* J-PAKE is a password-authenticated key exchange that allows deriving a
* strong shared secret from a (potentially low entropy) pre-shared
* passphrase, with forward secrecy and mutual authentication.
* https://en.wikipedia.org/wiki/Password_Authenticated_Key_Exchange_by_Juggling
*
* This file implements the Elliptic Curve variant of J-PAKE,
* as defined in Chapter 7.4 of the Thread v1.0 Specification,
* available to members of the Thread Group http://threadgroup.org/
*
* As the J-PAKE algorithm is inherently symmetric, so is our API.
* Each party needs to send its first round message, in any order, to the
* other party, then each sends its second round message, in any order.
* The payloads are serialized in a way suitable for use in TLS, but could
* also be use outside TLS.
*/
#include "ecp.h"
#include "md.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Roles in the EC J-PAKE exchange
*/
typedef enum {
MBEDTLS_ECJPAKE_CLIENT = 0, /**< Client */
MBEDTLS_ECJPAKE_SERVER, /**< Server */
} mbedtls_ecjpake_role;
/**
* EC J-PAKE context structure.
*
* J-PAKE is a symmetric protocol, except for the identifiers used in
* Zero-Knowledge Proofs, and the serialization of the second message
* (KeyExchange) as defined by the Thread spec.
*
* In order to benefit from this symmetry, we choose a different naming
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct
{
const mbedtls_md_info_t *md_info; /**< Hash to use */
mbedtls_ecp_group grp; /**< Elliptic curve */
mbedtls_ecjpake_role role; /**< Are we client or server? */
int point_format; /**< Format for point export */
mbedtls_ecp_point Xm1; /**< My public key 1 C: X1, S: X3 */
mbedtls_ecp_point Xm2; /**< My public key 2 C: X2, S: X4 */
mbedtls_ecp_point Xp1; /**< Peer public key 1 C: X3, S: X1 */
mbedtls_ecp_point Xp2; /**< Peer public key 2 C: X4, S: X2 */
mbedtls_ecp_point Xp; /**< Peer public key C: Xs, S: Xc */
mbedtls_mpi xm1; /**< My private key 1 C: x1, S: x3 */
mbedtls_mpi xm2; /**< My private key 2 C: x2, S: x4 */
mbedtls_mpi s; /**< Pre-shared secret (passphrase) */
} mbedtls_ecjpake_context;
/**
* \brief Initialize a context
* (just makes it ready for setup() or free()).
*
* \param ctx context to initialize
*/
void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx );
/**
* \brief Set up a context for use
*
* \note Currently the only values for hash/curve allowed by the
* standard are MBEDTLS_MD_SHA256/MBEDTLS_ECP_DP_SECP256R1.
*
* \param ctx context to set up
* \param role Our role: client or server
* \param hash hash function to use (MBEDTLS_MD_XXX)
* \param curve elliptic curve identifier (MBEDTLS_ECP_DP_XXX)
* \param secret pre-shared secret (passphrase)
* \param len length of the shared secret
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx,
mbedtls_ecjpake_role role,
mbedtls_md_type_t hash,
mbedtls_ecp_group_id curve,
const unsigned char *secret,
size_t len );
/*
* \brief Check if a context is ready for use
*
* \param ctx Context to check
*
* \return 0 if the context is ready for use,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx );
/**
* \brief Generate and write the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the first round message
* (TLS: contents of the Client/ServerHello extension,
* excluding extension type and length bytes)
*
* \param ctx Context to use
* \param buf Pointer to extension contents
* \param len Extension length
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Generate and write the second round message
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Read and process the second round message
* (TLS: contents of the Client/ServerKeyExchange)
*
* \param ctx Context to use
* \param buf Pointer to the message
* \param len Message length
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx,
const unsigned char *buf,
size_t len );
/**
* \brief Derive the shared secret
* (TLS: Pre-Master Secret)
*
* \param ctx Context to use
* \param buf Buffer to write the contents to
* \param len Buffer size
* \param olen Will be updated with the number of bytes written
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successfull,
* a negative error code otherwise
*/
int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx,
unsigned char *buf, size_t len, size_t *olen,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/**
* \brief Free a context's content
*
* \param ctx context to free
*/
void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx );
#if defined(MBEDTLS_SELF_TEST)
/**
* \brief Checkup routine
*
* \return 0 if successful, or 1 if a test failed
*/
int mbedtls_ecjpake_self_test( int verbose );
#endif
#ifdef __cplusplus
}
#endif
#endif /* ecjpake.h */

View File

@ -346,6 +346,21 @@ int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt );
*/ */
int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ); int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt );
/**
* \brief Compare two points
*
* \note This assumes the points are normalized. Otherwise,
* they may compare as "not equal" even if they are.
*
* \param P First point to compare
* \param Q Second point to compare
*
* \return 0 if the points are equal,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA otherwise
*/
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q );
/** /**
* \brief Import a non-zero point from two ASCII strings * \brief Import a non-zero point from two ASCII strings
* *
@ -569,6 +584,29 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_po
*/ */
int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ); int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d );
/**
* \brief Generate a keypair with configurable base point
*
* \param grp ECP group
* \param G Chosen base point
* \param d Destination MPI (secret part)
* \param Q Destination point (public part)
* \param f_rng RNG function
* \param p_rng RNG parameter
*
* \return 0 if successful,
* or a MBEDTLS_ERR_ECP_XXX or MBEDTLS_MPI_XXX error code
*
* \note Uses bare components rather than an mbedtls_ecp_keypair structure
* in order to ease use with other structures such as
* mbedtls_ecdh_context of mbedtls_ecdsa_context.
*/
int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng );
/** /**
* \brief Generate a keypair * \brief Generate a keypair
* *

View File

@ -3,7 +3,7 @@
* *
* \brief Entropy accumulator implementation * \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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -134,6 +134,9 @@ typedef struct
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
mbedtls_threading_mutex_t mutex; /*!< mutex */ mbedtls_threading_mutex_t mutex; /*!< mutex */
#endif #endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
int initial_entropy_run;
#endif
} }
mbedtls_entropy_context; 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, int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
const unsigned char *data, size_t len ); 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) #if defined(MBEDTLS_FS_IO)
/** /**
* \brief Write a seed file * \brief Write a seed file
@ -240,9 +255,29 @@ int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *
/** /**
* \brief Checkup routine * \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 * \return 0 if successful, or 1 if a test failed
*/ */
int mbedtls_entropy_self_test( int verbose ); 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 */ #endif /* MBEDTLS_SELF_TEST */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -3,7 +3,7 @@
* *
* \brief Platform-specific and custom entropy polling functions * \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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * 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_PLATFORM 32 /**< Minimum for platform source */
#define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */ #define MBEDTLS_ENTROPY_MIN_HAVEGE 32 /**< Minimum for HAVEGE */
#define MBEDTLS_ENTROPY_MIN_HARDCLOCK 4 /**< Minimum for mbedtls_timing_hardclock() */ #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 */ #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) #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 ); unsigned char *output, size_t len, size_t *olen );
#endif #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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -79,7 +79,7 @@
* ECP 4 8 (Started from top) * ECP 4 8 (Started from top)
* MD 5 4 * MD 5 4
* CIPHER 6 6 * CIPHER 6 6
* SSL 6 16 (Started from top) * SSL 6 17 (Started from top)
* SSL 7 31 * SSL 7 31
* *
* Module dependent error code (5 bits 0x.00.-0x.F8.) * Module dependent error code (5 bits 0x.00.-0x.F8.)

View File

@ -190,8 +190,8 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
* 16 bytes. * 16 bytes.
* *
* \param ctx GCM context * \param ctx GCM context
* \param tag buffer for holding the tag (may be NULL if tag_len is 0) * \param tag buffer for holding the tag
* \param tag_len length of the tag to generate * \param tag_len length of the tag to generate (must be at least 4)
* *
* \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT * \return 0 if successful or MBEDTLS_ERR_GCM_BAD_INPUT
*/ */

View File

@ -98,7 +98,7 @@ typedef struct
/** /**
* \brief HMAC_DRBG context initialization * \brief HMAC_DRBG context initialization
* Makes the context ready for mbetls_hmac_drbg_seed(), * Makes the context ready for mbedtls_hmac_drbg_seed(),
* mbedtls_hmac_drbg_seed_buf() or * mbedtls_hmac_drbg_seed_buf() or
* mbedtls_hmac_drbg_free(). * mbedtls_hmac_drbg_free().
* *

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_md.h * \file md.h
* *
* \brief Generic message digest wrapper * \brief Generic message digest wrapper
* *
@ -27,10 +27,6 @@
#include <stddef.h> #include <stddef.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline)
#define inline __inline
#endif
#define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */ #define MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */
#define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */
#define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ #define MBEDTLS_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */
@ -308,8 +304,8 @@ int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *inpu
/** /**
* \brief Output HMAC. * \brief Output HMAC.
* Called after mbedtls_md_hmac_update(). * Called after mbedtls_md_hmac_update().
* Usually followed my mbedtls_md_hmac_reset(), mbedtls_md_hmac_starts(), * Usually followed by mbedtls_md_hmac_reset(),
* or mbedtls_md_free(). * mbedtls_md_hmac_starts(), or mbedtls_md_free().
* *
* \param ctx HMAC context * \param ctx HMAC context
* \param output Generic HMAC checksum result * \param output Generic HMAC checksum result
@ -321,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. * \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 * \param ctx HMAC context to be reset
* *

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_md2.h * \file md2.h
* *
* \brief MD2 message digest algorithm (hash function) * \brief MD2 message digest algorithm (hash function)
* *

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_md4.h * \file md4.h
* *
* \brief MD4 message digest algorithm (hash function) * \brief MD4 message digest algorithm (hash function)
* *

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_md5.h * \file md5.h
* *
* \brief MD5 message digest algorithm (hash function) * \brief MD5 message digest algorithm (hash function)
* *

View File

@ -98,8 +98,10 @@ void mbedtls_memory_buffer_alloc_status( void );
/** /**
* \brief Get the peak heap usage so far * \brief Get the peak heap usage so far
* *
* \param max_used Peak number of bytes reauested by the application * \param max_used Peak number of bytes in use or committed. This
* \param max_blocks Peak number of blocks reauested by the application * 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 ); 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 * \brief Get the current heap usage
* *
* \param cur_used Number of bytes reauested by the application * \param cur_used Current number of bytes in use or committed. This
* \param cur_blocks Number of blocks reauested by the application * 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 ); void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks );
#endif /* MBEDTLS_MEMORY_DEBUG */ #endif /* MBEDTLS_MEMORY_DEBUG */

View File

@ -1,9 +1,9 @@
/** /**
* \file net.h * \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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -19,207 +19,13 @@
* limitations under the License. * limitations under the License.
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*
* \deprecated Superseded by mbedtls/net_sockets.h
*/ */
#ifndef MBEDTLS_NET_H
#define MBEDTLS_NET_H
#if !defined(MBEDTLS_CONFIG_FILE) #if !defined(MBEDTLS_DEPRECATED_REMOVED)
#include "config.h" #include "mbedtls/net_sockets.h"
#else #if defined(MBEDTLS_DEPRECATED_WARNING)
#include MBEDTLS_CONFIG_FILE #warning "Deprecated header file: Superseded by mbedtls/net_sockets.h"
#endif #endif /* MBEDTLS_DEPRECATED_WARNING */
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#include "ssl.h"
#include <stddef.h>
#include <stdint.h>
#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 */

View File

@ -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 <stddef.h>
#include <stdint.h>
#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 */

View File

@ -44,6 +44,11 @@
#include "ecdsa.h" #include "ecdsa.h"
#endif #endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline
#endif
#define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */ #define MBEDTLS_ERR_PK_ALLOC_FAILED -0x3F80 /**< Memory allocation failed. */
#define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */ #define MBEDTLS_ERR_PK_TYPE_MISMATCH -0x3F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */
#define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */ #define MBEDTLS_ERR_PK_BAD_INPUT_DATA -0x3E80 /**< Bad input parameters to function. */
@ -59,7 +64,6 @@
#define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ #define MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE -0x3980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */
#define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The signature is valid but its length is less than expected. */ #define MBEDTLS_ERR_PK_SIG_LEN_MISMATCH -0x3900 /**< The signature is valid but its length is less than expected. */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -317,7 +321,7 @@ int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options,
/** /**
* \brief Make signature, including padding if relevant. * \brief Make signature, including padding if relevant.
* *
* \param ctx PK context to use * \param ctx PK context to use - must hold a private key
* \param md_alg Hash algorithm used (see notes) * \param md_alg Hash algorithm used (see notes)
* \param hash Hash of the message to sign * \param hash Hash of the message to sign
* \param hash_len Hash length or 0 (see notes) * \param hash_len Hash length or 0 (see notes)
@ -346,7 +350,7 @@ int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg,
/** /**
* \brief Decrypt message (including padding if relevant). * \brief Decrypt message (including padding if relevant).
* *
* \param ctx PK context to use * \param ctx PK context to use - must hold a private key
* \param input Input to decrypt * \param input Input to decrypt
* \param ilen Input size * \param ilen Input size
* \param output Decrypted output * \param output Decrypted output
@ -492,11 +496,12 @@ int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx,
* \brief Load and parse a public key * \brief Load and parse a public key
* *
* \param ctx key to be initialized * \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 * \note On entry, ctx must be empty, either freshly initialised
* with mbedtls_pk_init() or reset with mbedtls_pk_free(). If you need a * with mbedtls_pk_init() or reset with mbedtls_pk_free(). If
* specific key type, check the result with mbedtls_pk_can_do(). * you need a specific key type, check the result with
* mbedtls_pk_can_do().
* *
* \note The key is also checked for correctness. * \note The key is also checked for correctness.
* *

View File

@ -37,7 +37,8 @@
#include <pkcs11-helper-1.0/pkcs11h-certificate.h> #include <pkcs11-helper-1.0/pkcs11h-certificate.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
#endif #endif
@ -54,7 +55,7 @@ typedef struct {
} mbedtls_pkcs11_context; } mbedtls_pkcs11_context;
/** /**
* Initialize a mbetls_pkcs11_context. * Initialize a mbedtls_pkcs11_context.
* (Just making memory references valid.) * (Just making memory references valid.)
*/ */
void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ); void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx );

View File

@ -3,7 +3,7 @@
* *
* \brief mbed TLS Platform abstraction layer * \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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -29,6 +29,10 @@
#include MBEDTLS_CONFIG_FILE #include MBEDTLS_CONFIG_FILE
#endif #endif
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -44,6 +48,7 @@ extern "C" {
#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS)
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) #if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF)
#if defined(_WIN32) #if defined(_WIN32)
#define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */ #define MBEDTLS_PLATFORM_STD_SNPRINTF mbedtls_platform_win32_snprintf /**< Default snprintf to use */
@ -64,14 +69,35 @@ extern "C" {
#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */ #define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use */
#endif #endif
#if !defined(MBEDTLS_PLATFORM_STD_EXIT) #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 #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 */ #else /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
#if defined(MBEDTLS_PLATFORM_STD_MEM_HDR) #if defined(MBEDTLS_PLATFORM_STD_MEM_HDR)
#include MBEDTLS_PLATFORM_STD_MEM_HDR #include MBEDTLS_PLATFORM_STD_MEM_HDR
#endif #endif
#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ #endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */
/* \} name SECTION: Module settings */ /* \} name SECTION: Module settings */
/* /*
@ -207,6 +233,61 @@ int mbedtls_platform_set_exit( void (*exit_func)( int status ) );
#endif /* MBEDTLS_PLATFORM_EXIT_MACRO */ #endif /* MBEDTLS_PLATFORM_EXIT_MACRO */
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ #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 */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -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 <time.h>
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 */

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_ripemd160.h * \file ripemd160.h
* *
* \brief RIPE MD-160 message digest * \brief RIPE MD-160 message digest
* *

View File

@ -99,7 +99,7 @@ typedef struct
mbedtls_mpi Vf; /*!< cached un-blinding value */ mbedtls_mpi Vf; /*!< cached un-blinding value */
int padding; /*!< MBEDTLS_RSA_PKCS_V15 for 1.5 padding and 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 int hash_id; /*!< Hash identifier of mbedtls_md_type_t as
specified in the mbedtls_md.h header file specified in the mbedtls_md.h header file
for the EME-OAEP and EMSA-PSS for the EME-OAEP and EMSA-PSS

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_sha1.h * \file sha1.h
* *
* \brief SHA-1 cryptographic hash function * \brief SHA-1 cryptographic hash function
* *

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_sha256.h * \file sha256.h
* *
* \brief SHA-224 and SHA-256 cryptographic hash function * \brief SHA-224 and SHA-256 cryptographic hash function
* *

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_sha512.h * \file sha512.h
* *
* \brief SHA-384 and SHA-512 cryptographic hash function * \brief SHA-384 and SHA-512 cryptographic hash function
* *

View File

@ -52,27 +52,7 @@
#endif #endif
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
#include <time.h> #include "mbedtls/platform_time.h"
#endif
/* For convenience below and in programs */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
#endif
#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__SOME__SIGNATURE_ENABLED
#endif #endif
/* /*
@ -126,6 +106,9 @@
#define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */ #define MBEDTLS_ERR_SSL_WANT_WRITE -0x6880 /**< Connection requires a write call. */
#define MBEDTLS_ERR_SSL_TIMEOUT -0x6800 /**< The operation timed out. */ #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_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 * Various constants
@ -139,6 +122,8 @@
#define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */ #define MBEDTLS_SSL_TRANSPORT_STREAM 0 /*!< TLS */
#define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */ #define MBEDTLS_SSL_TRANSPORT_DATAGRAM 1 /*!< DTLS */
#define MBEDTLS_SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */
/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c /* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c
* NONE must be zero so that memset()ing structure to zero works */ * NONE must be zero so that memset()ing structure to zero works */
#define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ #define MBEDTLS_SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */
@ -249,7 +234,7 @@
* Signaling ciphersuite values (SCSV) * Signaling ciphersuite values (SCSV)
*/ */
#define MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ #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) * Supported Signature and Hash algorithms (For TLS 1.2)
@ -350,6 +335,8 @@
#define MBEDTLS_TLS_EXT_SESSION_TICKET 35 #define MBEDTLS_TLS_EXT_SESSION_TICKET 35
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */
#define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01
/* /*
@ -388,6 +375,9 @@ union mbedtls_ssl_premaster_secret
unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES unsigned char _pms_ecdhe_psk[4 + MBEDTLS_ECP_MAX_BYTES
+ MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */ + MBEDTLS_PSK_MAX_LEN]; /* RFC 5489 2 */
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
unsigned char _pms_ecjpake[32]; /* Thread spec: SHA-256 output */
#endif
}; };
#define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret ) #define MBEDTLS_PREMASTER_SIZE sizeof( union mbedtls_ssl_premaster_secret )
@ -423,6 +413,116 @@ typedef enum
} }
mbedtls_ssl_states; 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 */ /* Defined below */
typedef struct mbedtls_ssl_session mbedtls_ssl_session; typedef struct mbedtls_ssl_session mbedtls_ssl_session;
typedef struct mbedtls_ssl_context mbedtls_ssl_context; typedef struct mbedtls_ssl_context mbedtls_ssl_context;
@ -444,7 +544,7 @@ typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
struct mbedtls_ssl_session struct mbedtls_ssl_session
{ {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
time_t start; /*!< starting time */ mbedtls_time_t start; /*!< starting time */
#endif #endif
int ciphersuite; /*!< chosen ciphersuite */ int ciphersuite; /*!< chosen ciphersuite */
int compression; /*!< chosen compression */ int compression; /*!< chosen compression */
@ -540,6 +640,13 @@ struct mbedtls_ssl_config
void *p_ticket; /*!< context for the ticket callbacks */ void *p_ticket; /*!< context for the ticket callbacks */
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
/** Callback to export key block and master secret */
int (*f_export_keys)( void *, const unsigned char *,
const unsigned char *, size_t, size_t, size_t );
void *p_export_keys; /*!< context for key export callback */
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */
mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */
@ -547,7 +654,7 @@ struct mbedtls_ssl_config
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */ mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
#endif /* MBEDTLS_X509_CRT_PARSE_C */ #endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
const int *sig_hashes; /*!< allowed signature hashes */ const int *sig_hashes; /*!< allowed signature hashes */
#endif #endif
@ -667,12 +774,11 @@ struct mbedtls_ssl_context
unsigned badmac_seen; /*!< records with a bad MAC received */ unsigned badmac_seen; /*!< records with a bad MAC received */
#endif #endif
/* mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
* Callbacks mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
*/ mbedtls_ssl_recv_timeout_t *f_recv_timeout;
int (*f_send)(void *, const unsigned char *, size_t); /*!< Callback for network receive with timeout */
int (*f_recv)(void *, unsigned char *, size_t);
int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t);
void *p_bio; /*!< context for I/O operations */ void *p_bio; /*!< context for I/O operations */
/* /*
@ -698,8 +804,9 @@ struct mbedtls_ssl_context
* Timers * Timers
*/ */
void *p_timer; /*!< context for the timer callbacks */ 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) * Record layer (incoming data)
@ -840,7 +947,7 @@ int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name );
/** /**
* \brief Initialize an SSL context * \brief Initialize an SSL context
* Just makes the context ready for mbetls_ssl_setup() or * Just makes the context ready for mbedtls_ssl_setup() or
* mbedtls_ssl_free() * mbedtls_ssl_free()
* *
* \param ssl SSL context * \param ssl SSL context
@ -853,7 +960,7 @@ void mbedtls_ssl_init( mbedtls_ssl_context *ssl );
* \note No copy of the configuration context is made, it can be * \note No copy of the configuration context is made, it can be
* shared by many mbedtls_ssl_context structures. * 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! * function is unsupported!
* *
* \param ssl SSL context * \param ssl SSL context
@ -871,7 +978,7 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
* pointers and data. * pointers and data.
* *
* \param ssl SSL context * \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_HW_ACCEL_FAILED or
* MBEDTLS_ERR_SSL_COMPRESSION_FAILED * MBEDTLS_ERR_SSL_COMPRESSION_FAILED
*/ */
@ -919,6 +1026,7 @@ void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport );
* *
* MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, * MBEDTLS_SSL_VERIFY_REQUIRED: peer *must* present a valid certificate,
* handshake is aborted if verification failed. * handshake is aborted if verification failed.
* (default on client)
* *
* \note On client, MBEDTLS_SSL_VERIFY_REQUIRED is the recommended mode. * \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 * With MBEDTLS_SSL_VERIFY_OPTIONAL, the user needs to call mbedtls_ssl_get_verify_result() at
@ -983,8 +1091,6 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
* \param f_send write callback * \param f_send write callback
* \param f_recv read callback * \param f_recv read callback
* \param f_recv_timeout blocking read callback with timeout. * \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 * \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 * the other is used. If both are non-NULL, f_recv_timeout is
@ -996,12 +1102,21 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
* *
* \note For DTLS, you need to provide either a non-NULL * \note For DTLS, you need to provide either a non-NULL
* f_recv_timeout callback, or a f_recv that doesn't block. * 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 mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
void *p_bio, void *p_bio,
int (*f_send)(void *, const unsigned char *, size_t), mbedtls_ssl_send_t *f_send,
int (*f_recv)(void *, unsigned char *, size_t), mbedtls_ssl_recv_t *f_recv,
int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) ); mbedtls_ssl_recv_timeout_t *f_recv_timeout );
/** /**
* \brief Set the timeout period for mbedtls_ssl_read() * \brief Set the timeout period for mbedtls_ssl_read()
@ -1022,37 +1137,42 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout );
/** /**
* \brief Set the timer callbacks * \brief Set the timer callbacks (Mandatory for DTLS.)
* (Mandatory for DTLS.)
* *
* \param ssl SSL context * \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 * \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: * \param f_get_timer get timer callback. Must return:
* -1 if cancelled *
* 0 if none of the delays is expired * \note See the documentation of \c mbedtls_ssl_set_timer_t and
* 1 if the intermediate delay only is expired * \c mbedtls_ssl_get_timer_t for the conventions this pair of
* 2 if the final delay is expired * callbacks must fallow.
*
* \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 mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
void *p_timer, void *p_timer,
void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms), mbedtls_ssl_set_timer_t *f_set_timer,
int (*f_get_timer)(void *) ); mbedtls_ssl_get_timer_t *f_get_timer );
/** /**
* \brief Callback type: generate and write session ticket * \brief Callback type: generate and write session ticket
* *
* \note This describes what a callback implementation should do. * \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 * authenticated ticket for the session and write it to the
* output buffer. Here, ticket means the opaque ticket part * output buffer. Here, ticket means the opaque ticket part
* of the NewSessionTicket structure of RFC 5077. * of the NewSessionTicket structure of RFC 5077.
* *
* \param p_ticket Context for the callback * \param p_ticket Context for the callback
* \param session SSL session to bo written in the ticket * \param session SSL session to be written in the ticket
* \param start Start of the outpur buffer * \param start Start of the output buffer
* \param end End of the output buffer * \param end End of the output buffer
* \param tlen On exit, holds the length written * \param tlen On exit, holds the length written
* \param lifetime On exit, holds the lifetime of the ticket in seconds * \param lifetime On exit, holds the lifetime of the ticket in seconds
@ -1067,6 +1187,35 @@ typedef int mbedtls_ssl_ticket_write_t( void *p_ticket,
size_t *tlen, size_t *tlen,
uint32_t *lifetime ); uint32_t *lifetime );
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
/**
* \brief Callback type: Export key block and master secret
*
* \note This is required for certain uses of TLS, e.g. EAP-TLS
* (RFC 5216) and Thread. The key pointers are ephemeral and
* therefore must not be stored. The master secret and keys
* should not be used directly except as an input to a key
* derivation function.
*
* \param p_expkey Context for the callback
* \param ms Pointer to master secret (fixed length: 48 bytes)
* \param kb Pointer to key block, see RFC 5246 section 6.3
* (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
* \param maclen MAC length
* \param keylen Key length
* \param ivlen IV length
*
* \return 0 if successful, or
* a specific MBEDTLS_ERR_XXX code.
*/
typedef int mbedtls_ssl_export_keys_t( void *p_expkey,
const unsigned char *ms,
const unsigned char *kb,
size_t maclen,
size_t keylen,
size_t ivlen );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/** /**
* \brief Callback type: parse and load session ticket * \brief Callback type: parse and load session ticket
* *
@ -1116,6 +1265,22 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
void *p_ticket ); void *p_ticket );
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */ #endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_SRV_C */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
/**
* \brief Configure key export callback.
* (Default: none.)
*
* \note See \c mbedtls_ssl_export_keys_t.
*
* \param conf SSL configuration context
* \param f_export_keys Callback for exporting keys
* \param p_export_keys Context for the callback
*/
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys );
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
/** /**
* \brief Callback type: generate a cookie * \brief Callback type: generate a cookie
* *
@ -1258,7 +1423,7 @@ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limi
#if defined(MBEDTLS_SSL_PROTO_DTLS) #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.) * (DTLS only, no effect on TLS.)
* *
* \param conf SSL configuration * \param conf SSL configuration
@ -1269,9 +1434,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 Default values are from RFC 6347 section 4.2.4.1.
* *
* \note Higher values for initial timeout may increase average * \note The 'min' value should typically be slightly above the
* handshake latency. Lower values may increase the risk of * expected round-trip time to your peer, plus whatever time
* network congestion by causing more retransmissions. * 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 ); void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max );
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #endif /* MBEDTLS_SSL_PROTO_DTLS */
@ -1341,7 +1521,7 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session
/** /**
* \brief Set the list of allowed ciphersuites and the preference * \brief Set the list of allowed ciphersuites and the preference
* order. First in the list has the highest 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 * The ciphersuites array is not copied, and must remain
* valid for the lifetime of the ssl_config. * valid for the lifetime of the ssl_config.
@ -1383,6 +1563,10 @@ void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf,
/** /**
* \brief Set the X.509 security profile used for verification * \brief Set the X.509 security profile used for verification
* *
* \note The restrictions are enforced for all certificates in the
* chain. However, signatures in the handshake are not covered
* by this setting but by \b mbedtls_ssl_conf_sig_hashes().
*
* \param conf SSL configuration * \param conf SSL configuration
* \param profile Profile to use * \param profile Profile to use
*/ */
@ -1415,7 +1599,12 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
* adequate, preference is given to the one set by the first * adequate, preference is given to the one set by the first
* call to this function, then second, etc. * 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 conf SSL configuration
* \param own_cert own public certificate chain * \param own_cert own public certificate chain
@ -1435,6 +1624,12 @@ int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
* \note This is mainly useful for clients. Servers will usually * \note This is mainly useful for clients. Servers will usually
* want to use \c mbedtls_ssl_conf_psk_cb() instead. * 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 conf SSL configuration
* \param psk pointer to the pre-shared key * \param psk pointer to the pre-shared key
* \param psk_len pre-shared key length * \param psk_len pre-shared key length
@ -1544,16 +1739,14 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
* On client: this affects the list of curves offered for any * On client: this affects the list of curves offered for any
* use. The server can override our preference order. * use. The server can override our preference order.
* *
* Both sides: limits the set of curves used by peer to the * Both sides: limits the set of curves accepted for use in
* listed curves for any use ECDHE and the end-entity * ECDHE and in the peer's end-entity certificate.
* certificate.
* *
* \note This has no influence on which curve are allowed inside the * \note This has no influence on which curves are allowed inside the
* certificate chains, see \c mbedtls_ssl_conf_cert_profile() * certificate chains, see \c mbedtls_ssl_conf_cert_profile()
* for that. For example, if the peer's certificate chain is * for that. For the end-entity certificate however, the key
* EE -> CA_int -> CA_root, then the allowed curves for EE are * will be accepted only if it is allowed both by this list
* controlled by \c mbedtls_ssl_conf_curves() but for CA_int * and by the cert profile.
* and CA_root it's \c mbedtls_ssl_conf_cert_profile().
* *
* \note This list should be ordered by decreasing preference * \note This list should be ordered by decreasing preference
* (preferred curve first). * (preferred curve first).
@ -1566,10 +1759,10 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
const mbedtls_ecp_group_id *curves ); const mbedtls_ecp_group_id *curves );
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/** /**
* \brief Set the allowed hashes for signatures during the handshake. * \brief Set the allowed hashes for signatures during the handshake.
* (Default: all available hashes.) * (Default: all available hashes except MD5.)
* *
* \note This only affects which hashes are offered and can be used * \note This only affects which hashes are offered and can be used
* for signatures during the handshake. Hashes for message * for signatures during the handshake. Hashes for message
@ -1587,14 +1780,15 @@ void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf,
*/ */
void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf,
const int *hashes ); const int *hashes );
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #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) * (client-side only)
* *
*
* \param ssl SSL context * \param ssl SSL context
* \param hostname the server hostname * \param hostname the server hostname
* *
@ -1677,13 +1871,39 @@ void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf,
void *p_sni ); void *p_sni );
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/**
* \brief Set the EC J-PAKE password for current handshake.
*
* \note An internal copy is made, and destroyed as soon as the
* handshake is completed, or when the SSL context is reset or
* freed.
*
* \note The SSL context needs to be already set up. The right place
* to call this function is between \c mbedtls_ssl_setup() or
* \c mbedtls_ssl_reset() and \c mbedtls_ssl_handshake().
*
* \param ssl SSL context
* \param pw EC J-PAKE password (pre-shared secret)
* \param pw_len length of pw in bytes
*
* \return 0 on success, or a negative error code.
*/
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len );
#endif /*MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
/** /**
* \brief Set the supported Application Layer Protocols. * \brief Set the supported Application Layer Protocols.
* *
* \param conf SSL configuration * \param conf SSL configuration
* \param protos NULL-terminated list of supported protocols, * \param protos Pointer to a NULL-terminated list of supported protocols,
* in decreasing preference order. * 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. * \return 0 on success, or MBEDTLS_ERR_SSL_BAD_INPUT_DATA.
*/ */
@ -1797,11 +2017,13 @@ void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems
* \brief Disable or enable support for RC4 * \brief Disable or enable support for RC4
* (Default: MBEDTLS_SSL_ARC4_DISABLED) * (Default: MBEDTLS_SSL_ARC4_DISABLED)
* *
* \warning Use of RC4 in (D)TLS has been prohibited by RFC ???? * \warning Use of RC4 in DTLS/TLS has been prohibited by RFC 7465
* for security reasons. Use at your own risks. * for security reasons. Use at your own risk.
* *
* \note This function will likely be removed in future versions as * \note This function is deprecated and will likely be removed in
* RC4 will then be disabled by default at compile time. * 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 conf SSL configuration
* \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED * \param arc4 MBEDTLS_SSL_ARC4_ENABLED or MBEDTLS_SSL_ARC4_DISABLED
@ -1877,7 +2099,7 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets
* *
* \warning It is recommended to always disable renegotation unless you * \warning It is recommended to always disable renegotation unless you
* know you need it and you know what you're doing. In the * 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. * renegotiation or a poor understanding of its properties.
* *
* \note Server-side, enabling renegotiation also makes the server * \note Server-side, enabling renegotiation also makes the server
@ -2103,7 +2325,8 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session
* \note If this function returns something other than 0 or * \note If this function returns something other than 0 or
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context * MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
* becomes unusable, and you should either free it or call * becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it. * \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
* *
* \note If DTLS is in use, then you may choose to handle * \note If DTLS is in use, then you may choose to handle
* MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging * MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED specially for logging
@ -2116,8 +2339,14 @@ int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl );
* \brief Perform a single step of the SSL handshake * \brief Perform a single step of the SSL handshake
* *
* \note The state of the context (ssl->state) will be at * \note The state of the context (ssl->state) will be at
* the following state after execution of this function. * the next state after execution of this function. Do not
* Do not call this function if state is MBEDTLS_SSL_HANDSHAKE_OVER. * 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
* becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
* *
* \param ssl SSL context * \param ssl SSL context
* *
@ -2132,11 +2361,19 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl );
* \brief Initiate an SSL renegotiation on the running connection. * \brief Initiate an SSL renegotiation on the running connection.
* Client: perform the renegotiation right now. * Client: perform the renegotiation right now.
* Server: request renegotiation, which will be performed * 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 * \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
* becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
*/ */
int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ); int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_RENEGOTIATION */ #endif /* MBEDTLS_SSL_RENEGOTIATION */
@ -2154,6 +2391,13 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl );
* MBEDTLS_ERR_SSL_CLIENT_RECONNECT (see below), or * MBEDTLS_ERR_SSL_CLIENT_RECONNECT (see below), or
* another negative error code. * another negative error code.
* *
* \note If this function returns something other than a positive
* value or MBEDTLS_ERR_SSL_WANT_READ/WRITE or
* MBEDTLS_ERR_SSL_CLIENT_RECONNECT, then the ssl context
* becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
*
* \note When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT * \note When this function return MBEDTLS_ERR_SSL_CLIENT_RECONNECT
* (which can only happen server-side), it means that a client * (which can only happen server-side), it means that a client
* is initiating a new connection using the same source port. * is initiating a new connection using the same source port.
@ -2187,6 +2431,12 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* or MBEDTLS_ERR_SSL_WANT_WRITE of MBEDTLS_ERR_SSL_WANT_READ, * or MBEDTLS_ERR_SSL_WANT_WRITE of MBEDTLS_ERR_SSL_WANT_READ,
* or another negative error code. * or another negative error code.
* *
* \note If this function returns something other than a positive
* value or MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context
* becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
*
* \note When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, * \note When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ,
* it must be called later with the *same* arguments, * it must be called later with the *same* arguments,
* until it returns a positive value. * until it returns a positive value.
@ -2210,6 +2460,12 @@ int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_
* \param message The alert message (SSL_ALERT_MSG_*) * \param message The alert message (SSL_ALERT_MSG_*)
* *
* \return 0 if successful, or a specific SSL error code. * \return 0 if successful, or a specific SSL error code.
*
* \note If this function returns something other than 0 or
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
* becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
*/ */
int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
unsigned char level, unsigned char level,
@ -2218,6 +2474,14 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
* \brief Notify the peer that the connection is being closed * \brief Notify the peer that the connection is being closed
* *
* \param ssl SSL context * \param ssl SSL context
*
* \return 0 if successful, or a specific SSL error code.
*
* \note If this function returns something other than 0 or
* MBEDTLS_ERR_SSL_WANT_READ/WRITE, then the ssl context
* becomes unusable, and you should either free it or call
* \c mbedtls_ssl_session_reset() on it before re-using it for
* a new connection; the current connection must be closed.
*/ */
int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ); int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl );

View File

@ -60,7 +60,7 @@ typedef struct mbedtls_ssl_cache_entry mbedtls_ssl_cache_entry;
struct mbedtls_ssl_cache_entry struct mbedtls_ssl_cache_entry
{ {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
time_t timestamp; /*!< entry timestamp */ mbedtls_time_t timestamp; /*!< entry timestamp */
#endif #endif
mbedtls_ssl_session session; /*!< entry session */ mbedtls_ssl_session session; /*!< entry session */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
@ -121,7 +121,7 @@ void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeou
#endif /* MBEDTLS_HAVE_TIME */ #endif /* MBEDTLS_HAVE_TIME */
/** /**
* \brief Set the cache timeout * \brief Set the maximum number of cache entries
* (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) * (Default: MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES (50))
* *
* \param cache SSL cache context * \param cache SSL cache context

View File

@ -229,8 +229,10 @@ extern "C" {
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */
#define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ #define MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */
#define MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 0xC0FF /**< experimental */
/* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange. /* Reminder: update mbedtls_ssl_premaster_secret when adding a new key exchange.
* Reminder: update MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED below. * Reminder: update MBEDTLS_KEY_EXCHANGE__xxx below
*/ */
typedef enum { typedef enum {
MBEDTLS_KEY_EXCHANGE_NONE = 0, MBEDTLS_KEY_EXCHANGE_NONE = 0,
@ -244,19 +246,35 @@ typedef enum {
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_KEY_EXCHANGE_ECDH_RSA, MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_KEY_EXCHANGE_ECJPAKE,
} mbedtls_key_exchange_type_t; } mbedtls_key_exchange_type_t;
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ /* Key exchanges using a certificate */
defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED #define MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED
#endif #endif
/* Key exchanges using a PSK */
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED
#endif
/* Key exchanges using a ECDHE */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
#define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
#endif
typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t; typedef struct mbedtls_ssl_ciphersuite_t mbedtls_ssl_ciphersuite_t;
#define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ #define MBEDTLS_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */

View File

@ -41,7 +41,12 @@
#include "sha512.h" #include "sha512.h"
#endif #endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#include "ecjpake.h"
#endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
#endif #endif
@ -146,6 +151,7 @@
* of state of the renegotiation flag, so no indicator is required) * of state of the renegotiation flag, so no indicator is required)
*/ */
#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) #define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0)
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -160,7 +166,6 @@ struct mbedtls_ssl_handshake_params
* Handshake specific crypto variables * Handshake specific crypto variables
*/ */
int sig_alg; /*!< Hash algorithm for signature */ int sig_alg; /*!< Hash algorithm for signature */
int cert_type; /*!< Requested cert type */
int verify_sig_alg; /*!< Signature algorithm for verify */ int verify_sig_alg; /*!< Signature algorithm for verify */
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */
@ -168,7 +173,15 @@ struct mbedtls_ssl_handshake_params
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */
#endif #endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */
#if defined(MBEDTLS_SSL_CLI_C)
unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */
size_t ecjpake_cache_len; /*!< Length of cached data */
#endif
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
@ -342,6 +355,11 @@ int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl );
void mbedtls_ssl_reset_checksum( 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_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 );
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ); int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl );
int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want );
@ -371,12 +389,13 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig );
mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash );
unsigned char mbedtls_ssl_hash_from_md_alg( int md ); 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) #if defined(MBEDTLS_ECP_C)
int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
mbedtls_md_type_t md ); mbedtls_md_type_t md );
#endif #endif

View File

@ -81,6 +81,7 @@ void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t *
void mbedtls_threading_free_alt( void ); void mbedtls_threading_free_alt( void );
#endif /* MBEDTLS_THREADING_ALT */ #endif /* MBEDTLS_THREADING_ALT */
#if defined(MBEDTLS_THREADING_C)
/* /*
* The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock * 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_readdir_mutex;
extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex; extern mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex;
#endif /* MBEDTLS_THREADING_C */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -92,7 +92,7 @@ void mbedtls_set_alarm( int seconds );
* (See \c mbedtls_timing_get_delay().) * (See \c mbedtls_timing_get_delay().)
* *
* \param data Pointer to timing data * \param data Pointer to timing data
* Must point to a valid \c mbetls_timing_delay_context struct. * Must point to a valid \c mbedtls_timing_delay_context struct.
* \param int_ms First (intermediate) delay in milliseconds. * \param int_ms First (intermediate) delay in milliseconds.
* \param fin_ms Second (final) delay in milliseconds. * \param fin_ms Second (final) delay in milliseconds.
* Pass 0 to cancel the current delay. * Pass 0 to cancel the current delay.
@ -104,7 +104,7 @@ void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms );
* (Memory helper: number of delays passed.) * (Memory helper: number of delays passed.)
* *
* \param data Pointer to timing data * \param data Pointer to timing data
* Must point to a valid \c mbetls_timing_delay_context struct. * Must point to a valid \c mbedtls_timing_delay_context struct.
* *
* \return -1 if cancelled (fin_ms = 0) * \return -1 if cancelled (fin_ms = 0)
* 0 if none of the delays are passed, * 0 if none of the delays are passed,

View File

@ -38,7 +38,7 @@
* Major, Minor, Patchlevel * Major, Minor, Patchlevel
*/ */
#define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 1 #define MBEDTLS_VERSION_MINOR 4
#define MBEDTLS_VERSION_PATCH 1 #define MBEDTLS_VERSION_PATCH 1
/** /**
@ -46,9 +46,9 @@
* MMNNPP00 * MMNNPP00
* Major version | Minor version | Patch version * Major version | Minor version | Patch version
*/ */
#define MBEDTLS_VERSION_NUMBER 0x02010100 #define MBEDTLS_VERSION_NUMBER 0x02040100
#define MBEDTLS_VERSION_STRING "2.1.1" #define MBEDTLS_VERSION_STRING "2.4.1"
#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.1.1" #define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.4.1"
#if defined(MBEDTLS_VERSION_C) #if defined(MBEDTLS_VERSION_C)

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_x509_crl.h * \file x509_crl.h
* *
* \brief X.509 certificate revocation list parsing * \brief X.509 certificate revocation list parsing
* *
@ -100,6 +100,7 @@ mbedtls_x509_crl;
* *
* \param chain points to the start of the chain * \param chain points to the start of the chain
* \param buf buffer holding the CRL data in DER format * \param buf buffer holding the CRL data in DER format
* \param buflen size of the buffer
* (including the terminating null byte for PEM data) * (including the terminating null byte for PEM data)
* *
* \return 0 if successful, or a specific X509 or PEM error code * \return 0 if successful, or a specific X509 or PEM error code

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_x509_crt.h * \file x509_crt.h
* *
* \brief X.509 certificate parsing and writing * \brief X.509 certificate parsing and writing
* *
@ -120,6 +120,10 @@ mbedtls_x509_crt_profile;
#define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32 #define MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN 32
#define MBEDTLS_X509_RFC5280_UTC_TIME_LEN 15 #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) * Container for writing a certificate (CRT)
*/ */
@ -271,9 +275,14 @@ 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 * \note Same as \c mbedtls_x509_crt_verify_with_profile() with the
* default security profile. * default security profile.
* *
* \param crt a certificate to be verified * \note It is your responsibility to provide up-to-date CRLs for
* \param trust_ca the trusted CA chain * all trusted CAs. If no CRL is provided for the CA that was
* \param ca_crl the CRL chain for trusted CA's * 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 * \param cn expected Common Name (can be set to
* NULL if the CN must not be verified) * NULL if the CN must not be verified)
* \param flags result of the verification * \param flags result of the verification
@ -301,12 +310,12 @@ int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
* security profile. * security profile.
* *
* \note The restrictions on keys (RSA minimum size, allowed curves * \note The restrictions on keys (RSA minimum size, allowed curves
* for ECDSA) only applys to (intermediate) CAs, not to the * for ECDSA) apply to all certificates: trusted root,
* end-entity certificate. * intermediate CAs if any, and end entity certificate.
* *
* \param crt a certificate to be verified * \param crt a certificate (chain) to be verified
* \param trust_ca the trusted CA chain * \param trust_ca the list of trusted CAs
* \param ca_crl the CRL chain for trusted CA's * \param ca_crl the list of CRLs for trusted CAs
* \param profile security profile for verification * \param profile security profile for verification
* \param cn expected Common Name (can be set to * \param cn expected Common Name (can be set to
* NULL if the CN must not be verified) * NULL if the CN must not be verified)

View File

@ -1,5 +1,5 @@
/** /**
* \file mbedtls_x509_csr.h * \file x509_csr.h
* *
* \brief X.509 certificate signing request parsing and writing * \brief X.509 certificate signing request parsing and writing
* *
@ -83,6 +83,8 @@ mbedtls_x509write_csr;
/** /**
* \brief Load a Certificate Signing Request (CSR) in DER format * \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 csr CSR context to fill
* \param buf buffer holding the CRL data * \param buf buffer holding the CRL data
* \param buflen size of the buffer * \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 * \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 csr CSR context to fill
* \param buf buffer holding the CRL data * \param buf buffer holding the CRL data
* \param buflen size of the buffer * \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) * \brief Load a Certificate Signing Request (CSR)
* *
* \note See notes for \c mbedtls_x509_csr_parse()
*
* \param csr CSR context to fill * \param csr CSR context to fill
* \param path filename to read the CSR from * \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 * \note f_rng may be NULL if RSA is used for signature and the
* signature is made offline (otherwise f_rng is desirable * 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. * ECDSA signatures always require a non-NULL f_rng.
*/ */
int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,

View File

@ -15,11 +15,13 @@ set(src_crypto
ccm.c ccm.c
cipher.c cipher.c
cipher_wrap.c cipher_wrap.c
cmac.c
ctr_drbg.c ctr_drbg.c
des.c des.c
dhm.c dhm.c
ecdh.c ecdh.c
ecdsa.c ecdsa.c
ecjpake.c
ecp.c ecp.c
ecp_curves.c ecp_curves.c
entropy.c entropy.c
@ -70,7 +72,7 @@ set(src_x509
set(src_tls set(src_tls
debug.c debug.c
net.c net_sockets.c
ssl_cache.c ssl_cache.c
ssl_ciphersuites.c ssl_ciphersuites.c
ssl_cli.c ssl_cli.c
@ -130,20 +132,28 @@ if(USE_STATIC_MBEDTLS_LIBRARY)
add_library(${mbedtls_static_target} STATIC ${src_tls}) add_library(${mbedtls_static_target} STATIC ${src_tls})
set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls) set_target_properties(${mbedtls_static_target} PROPERTIES OUTPUT_NAME mbedtls)
target_link_libraries(${mbedtls_static_target} ${libs} ${mbedx509_static_target}) target_link_libraries(${mbedtls_static_target} ${libs} ${mbedx509_static_target})
install(TARGETS ${mbedtls_static_target} ${mbedx509_static_target} ${mbedcrypto_static_target}
DESTINATION ${LIB_INSTALL_DIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif(USE_STATIC_MBEDTLS_LIBRARY) endif(USE_STATIC_MBEDTLS_LIBRARY)
if(USE_SHARED_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY)
add_library(mbedcrypto SHARED ${src_crypto}) add_library(mbedcrypto SHARED ${src_crypto})
set_target_properties(mbedcrypto PROPERTIES VERSION 2.1.1 SOVERSION 0) set_target_properties(mbedcrypto PROPERTIES VERSION 2.4.1 SOVERSION 0)
target_link_libraries(mbedcrypto ${libs}) target_link_libraries(mbedcrypto ${libs})
add_library(mbedx509 SHARED ${src_x509}) add_library(mbedx509 SHARED ${src_x509})
set_target_properties(mbedx509 PROPERTIES VERSION 2.1.1 SOVERSION 0) set_target_properties(mbedx509 PROPERTIES VERSION 2.4.1 SOVERSION 0)
target_link_libraries(mbedx509 ${libs} mbedcrypto) target_link_libraries(mbedx509 ${libs} mbedcrypto)
add_library(mbedtls SHARED ${src_tls}) add_library(mbedtls SHARED ${src_tls})
set_target_properties(mbedtls PROPERTIES VERSION 2.1.1 SOVERSION 10) set_target_properties(mbedtls PROPERTIES VERSION 2.4.1 SOVERSION 10)
target_link_libraries(mbedtls ${libs} mbedx509) target_link_libraries(mbedtls ${libs} mbedx509)
install(TARGETS mbedtls mbedx509 mbedcrypto
DESTINATION ${LIB_INSTALL_DIR}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif(USE_SHARED_MBEDTLS_LIBRARY) endif(USE_SHARED_MBEDTLS_LIBRARY)
#add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls) #add_custom_target(lib DEPENDS mbedcrypto mbedx509 mbedtls)

View File

@ -48,8 +48,9 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
asn1parse.o asn1write.o base64.o \ asn1parse.o asn1write.o base64.o \
bignum.o blowfish.o camellia.o \ bignum.o blowfish.o camellia.o \
ccm.o cipher.o cipher_wrap.o \ ccm.o cipher.o cipher_wrap.o \
ctr_drbg.o des.o dhm.o \ cmac.o ctr_drbg.o des.o \
ecdh.o ecdsa.o ecp.o \ dhm.o ecdh.o ecdsa.o \
ecjpake.o ecp.o \
ecp_curves.o entropy.o entropy_poll.o \ ecp_curves.o entropy.o entropy_poll.o \
error.o gcm.o havege.o \ error.o gcm.o havege.o \
hmac_drbg.o md.o md2.o \ hmac_drbg.o md.o md2.o \
@ -67,9 +68,10 @@ OBJS_X509= certs.o pkcs11.o x509.o \
x509_create.o x509_crl.o x509_crt.o \ x509_create.o x509_crl.o x509_crt.o \
x509_csr.o x509write_crt.o x509write_csr.o x509_csr.o x509write_crt.o x509write_csr.o
OBJS_TLS= debug.o net.o ssl_cache.o \ OBJS_TLS= debug.o net_sockets.o \
ssl_ciphersuites.o ssl_cli.o \ ssl_cache.o ssl_ciphersuites.o \
ssl_cookie.o ssl_srv.o ssl_ticket.o \ ssl_cli.o ssl_cookie.o \
ssl_srv.o ssl_ticket.o \
ssl_tls.o ssl_tls.o
.SILENT: .SILENT:
@ -89,9 +91,9 @@ shared: libmbedcrypto.$(DLEXT) libmbedx509.$(DLEXT) libmbedtls.$(DLEXT)
# tls # tls
libmbedtls.a: $(OBJS_TLS) libmbedtls.a: $(OBJS_TLS)
echo " AR $@" echo " AR $@"
$(AR) rc $@ $(OBJS_TLS) $(AR) -rc $@ $(OBJS_TLS)
echo " RL $@" echo " RL $@"
$(AR) s $@ $(AR) -s $@
libmbedtls.$(SOEXT_TLS): $(OBJS_TLS) libmbedx509.so libmbedtls.$(SOEXT_TLS): $(OBJS_TLS) libmbedx509.so
echo " LD $@" echo " LD $@"
@ -112,9 +114,9 @@ libmbedtls.dll: $(OBJS_TLS) libmbedx509.dll
# x509 # x509
libmbedx509.a: $(OBJS_X509) libmbedx509.a: $(OBJS_X509)
echo " AR $@" echo " AR $@"
$(AR) rc $@ $(OBJS_X509) $(AR) -rc $@ $(OBJS_X509)
echo " RL $@" echo " RL $@"
$(AR) s $@ $(AR) -s $@
libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so libmbedx509.$(SOEXT_X509): $(OBJS_X509) libmbedcrypto.so
echo " LD $@" echo " LD $@"
@ -135,9 +137,9 @@ libmbedx509.dll: $(OBJS_X509) libmbedcrypto.dll
# crypto # crypto
libmbedcrypto.a: $(OBJS_CRYPTO) libmbedcrypto.a: $(OBJS_CRYPTO)
echo " AR $@" echo " AR $@"
$(AR) rc $@ $(OBJS_CRYPTO) $(AR) -rc $@ $(OBJS_CRYPTO)
echo " RL $@" echo " RL $@"
$(AR) s $@ $(AR) -s $@
libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO) libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO)
echo " LD $@" echo " LD $@"

View File

@ -56,7 +56,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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;
} }
/* /*
@ -1222,7 +1222,9 @@ int mbedtls_aes_self_test( int verbose )
int ret = 0, i, j, u, v; int ret = 0, i, j, u, v;
unsigned char key[32]; unsigned char key[32];
unsigned char buf[64]; unsigned char buf[64];
#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
unsigned char iv[16]; unsigned char iv[16];
#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC) #if defined(MBEDTLS_CIPHER_MODE_CBC)
unsigned char prv[16]; unsigned char prv[16];
#endif #endif

View File

@ -100,7 +100,7 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
asm( "movdqu (%3), %%xmm0 \n\t" // load input asm( "movdqu (%3), %%xmm0 \n\t" // load input
"movdqu (%1), %%xmm1 \n\t" // load round key 0 "movdqu (%1), %%xmm1 \n\t" // load round key 0
"pxor %%xmm1, %%xmm0 \n\t" // round 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 "subl $1, %0 \n\t" // normal rounds = nr - 1
"test %2, %2 \n\t" // mode? "test %2, %2 \n\t" // mode?
"jz 2f \n\t" // 0 = decrypt "jz 2f \n\t" // 0 = decrypt
@ -108,7 +108,7 @@ int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx,
"1: \n\t" // encryption loop "1: \n\t" // encryption loop
"movdqu (%1), %%xmm1 \n\t" // load round key "movdqu (%1), %%xmm1 \n\t" // load round key
AESENC xmm1_xmm0 "\n\t" // do round 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 "subl $1, %0 \n\t" // loop
"jnz 1b \n\t" "jnz 1b \n\t"
"movdqu (%1), %%xmm1 \n\t" // load round key "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 "2: \n\t" // decryption loop
"movdqu (%1), %%xmm1 \n\t" "movdqu (%1), %%xmm1 \n\t"
AESDEC xmm1_xmm0 "\n\t" // do round AESDEC xmm1_xmm0 "\n\t" // do round
"addq $16, %1 \n\t" "add $16, %1 \n\t"
"subl $1, %0 \n\t" "subl $1, %0 \n\t"
"jnz 2b \n\t" "jnz 2b \n\t"
"movdqu (%1), %%xmm1 \n\t" // load round key "movdqu (%1), %%xmm1 \n\t" // load round key

View File

@ -49,7 +49,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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 ) void mbedtls_arc4_init( mbedtls_arc4_context *ctx )

View File

@ -45,7 +45,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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 ) if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 )
return( ret ); return( ret );
if( len > sizeof( int ) || ( **p & 0x80 ) != 0 ) if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 )
return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); return( MBEDTLS_ERR_ASN1_INVALID_LENGTH );
*val = 0; *val = 0;
@ -269,7 +269,8 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p,
/* Allocate and assign next pointer */ /* Allocate and assign next pointer */
if( *p < end ) 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 ) if( cur->next == NULL )
return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); return( MBEDTLS_ERR_ASN1_ALLOC_FAILED );

View File

@ -60,16 +60,43 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len
return( 2 ); return( 2 );
} }
if( *p - start < 3 ) if( len <= 0xFFFF )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); {
if( *p - start < 3 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
// We assume we never have lengths larger than 65535 bytes *--(*p) = ( len ) & 0xFF;
// *--(*p) = ( len >> 8 ) & 0xFF;
*--(*p) = len % 256; *--(*p) = 0x82;
*--(*p) = ( len / 256 ) % 256; return( 3 );
*--(*p) = 0x82; }
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 ) int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag )
@ -87,7 +114,7 @@ int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start,
{ {
size_t len = 0; size_t len = 0;
if( *p - start < (int) size ) if( *p < start || (size_t)( *p - start ) < size )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
len = size; len = size;
@ -107,7 +134,7 @@ int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedt
// //
len = mbedtls_mpi_size( X ); len = mbedtls_mpi_size( X );
if( *p - start < (int) len ) if( *p < start || (size_t)( *p - start ) < len )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
(*p) -= len; (*p) -= len;
@ -191,7 +218,7 @@ int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolea
if( *p - start < 1 ) if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = (boolean) ? 1 : 0; *--(*p) = (boolean) ? 255 : 0;
len++; len++;
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
@ -270,7 +297,7 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start,
// Calculate byte length // Calculate byte length
// //
if( *p - start < (int) size + 1 ) if( *p < start || (size_t)( *p - start ) < size + 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
len = size + 1; len = size + 1;
@ -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 // 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 ); return( NULL );
cur->oid.len = oid_len; cur->oid.len = oid_len;
@ -339,19 +368,18 @@ mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data
} }
else if( cur->val.len < val_len ) else if( cur->val.len < val_len )
{ {
// Enlarge existing value buffer if needed /*
// * Enlarge existing value buffer if needed
mbedtls_free( cur->val.p ); * Preserve old data until the allocation succeeded, to leave list in
cur->val.p = NULL; * a consistent state in case allocation fails.
*/
cur->val.len = val_len; void *p = mbedtls_calloc( 1, val_len );
cur->val.p = mbedtls_calloc( 1, val_len ); if( p == NULL )
if( cur->val.p == NULL )
{
mbedtls_free( cur->oid.p );
mbedtls_free( cur );
return( NULL ); return( NULL );
}
mbedtls_free( cur->val.p );
cur->val.p = p;
cur->val.len = val_len;
} }
if( val != NULL ) if( val != NULL )

View File

@ -69,6 +69,8 @@ static const unsigned char base64_dec_map[128] =
49, 50, 51, 127, 127, 127, 127, 127 49, 50, 51, 127, 127, 127, 127, 127
}; };
#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
/* /*
* Encode a buffer into base64 format * Encode a buffer into base64 format
*/ */
@ -85,16 +87,17 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen,
return( 0 ); return( 0 );
} }
n = ( slen << 3 ) / 6; n = slen / 3 + ( slen % 3 != 0 );
switch( ( slen << 3 ) - ( n * 6 ) ) if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 )
{ {
case 2: n += 3; break; *olen = BASE64_SIZE_T_MAX;
case 4: n += 2; break; return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
default: break;
} }
if( dlen < n + 1 ) n *= 4;
if( ( dlen < n + 1 ) || ( NULL == dst ) )
{ {
*olen = n + 1; *olen = n + 1;
return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL );
@ -184,7 +187,10 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen,
} }
if( n == 0 ) if( n == 0 )
{
*olen = 0;
return( 0 ); return( 0 );
}
n = ( ( n * 6 ) + 7 ) >> 3; n = ( ( n * 6 ) + 7 ) >> 3;
n -= j; n -= j;

View File

@ -18,12 +18,21 @@
* *
* This file is part of mbed TLS (https://tls.mbed.org) * This file is part of mbed TLS (https://tls.mbed.org)
*/ */
/* /*
* This MPI implementation is based on: * The following sources were referenced in the design of this Multi-precision
* Integer library:
*
* [1] Handbook of Applied Cryptography - 1997
* Menezes, van Oorschot and Vanstone
*
* [2] Multi-Precision Math
* Tom St Denis
* https://github.com/libtom/libtommath/blob/develop/tommath.pdf
*
* [3] GNU Multi-Precision Arithmetic Library
* https://gmplib.org/manual/index.html
* *
* http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
* http://www.stillhq.com/extracted/gnupg-api/mbedtls_mpi/
* http://math.libtomcrypt.com/files/tommath.pdf
*/ */
#if !defined(MBEDTLS_CONFIG_FILE) #if !defined(MBEDTLS_CONFIG_FILE)
@ -50,19 +59,22 @@
#endif #endif
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0; volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0;
} }
#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
#define biL (ciL << 3) /* bits in limb */ #define biL (ciL << 3) /* bits in limb */
#define biH (ciL << 2) /* half limb size */ #define biH (ciL << 2) /* half limb size */
#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
/* /*
* Convert between bits/chars and number of limbs * Convert between bits/chars and number of limbs
* Divide first in order to avoid potential overflows
*/ */
#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) #define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
/* /*
* Initialize one MPI * Initialize one MPI
@ -87,7 +99,7 @@ void mbedtls_mpi_free( mbedtls_mpi *X )
if( X->p != NULL ) if( X->p != NULL )
{ {
mbedtls_zeroize( X->p, X->n * ciL ); mbedtls_mpi_zeroize( X->p, X->n );
mbedtls_free( X->p ); mbedtls_free( X->p );
} }
@ -108,13 +120,13 @@ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
if( X->n < 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 ); return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
if( X->p != NULL ) if( X->p != NULL )
{ {
memcpy( p, X->p, X->n * ciL ); 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 ); mbedtls_free( X->p );
} }
@ -146,13 +158,13 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
if( i < nblimbs ) if( i < nblimbs )
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 ); return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
if( X->p != NULL ) if( X->p != NULL )
{ {
memcpy( p, X->p, i * ciL ); memcpy( p, X->p, i * ciL );
mbedtls_zeroize( X->p, X->n * ciL ); mbedtls_mpi_zeroize( X->p, X->n );
mbedtls_free( X->p ); mbedtls_free( X->p );
} }
@ -344,6 +356,24 @@ size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
return( 0 ); return( 0 );
} }
/*
* Count leading zero bits in a given integer
*/
static size_t mbedtls_clz( const mbedtls_mpi_uint x )
{
size_t j;
mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
for( j = 0; j < biL; j++ )
{
if( x & mask ) break;
mask >>= 1;
}
return j;
}
/* /*
* Return the number of bits * Return the number of bits
*/ */
@ -358,9 +388,7 @@ size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
if( X->p[i] != 0 ) if( X->p[i] != 0 )
break; break;
for( j = biL; j > 0; j-- ) j = biL - mbedtls_clz( X->p[i] );
if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
break;
return( ( i * biL ) + j ); return( ( i * biL ) + j );
} }
@ -409,6 +437,9 @@ int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
if( radix == 16 ) if( radix == 16 )
{ {
if( slen > MPI_SIZE_T_MAX >> 2 )
return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
n = BITS_TO_LIMBS( slen << 2 ); n = BITS_TO_LIMBS( slen << 2 );
MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
@ -852,7 +883,7 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
{ {
int ret; int ret;
size_t i, j; size_t i, j;
mbedtls_mpi_uint *o, *p, c; mbedtls_mpi_uint *o, *p, c, tmp;
if( X == B ) if( X == B )
{ {
@ -875,10 +906,14 @@ int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
o = B->p; p = X->p; c = 0; 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++ ) for( i = 0; i < j; i++, o++, p++ )
{ {
tmp= *o;
*p += c; c = ( *p < c ); *p += c; c = ( *p < c );
*p += *o; c += ( *p < *o ); *p += tmp; c += ( *p < tmp );
} }
while( c != 0 ) while( c != 0 )
@ -1180,6 +1215,102 @@ int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint
return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
} }
/*
* Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
* mbedtls_mpi_uint divisor, d
*/
static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
{
#if defined(MBEDTLS_HAVE_UDBL)
mbedtls_t_udbl dividend, quotient;
#else
const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
mbedtls_mpi_uint u0_msw, u0_lsw;
size_t s;
#endif
/*
* Check for overflow
*/
if( 0 == d || u1 >= d )
{
if (r != NULL) *r = ~0;
return ( ~0 );
}
#if defined(MBEDTLS_HAVE_UDBL)
dividend = (mbedtls_t_udbl) u1 << biL;
dividend |= (mbedtls_t_udbl) u0;
quotient = dividend / d;
if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
if( r != NULL )
*r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
return (mbedtls_mpi_uint) quotient;
#else
/*
* Algorithm D, Section 4.3.1 - The Art of Computer Programming
* Vol. 2 - Seminumerical Algorithms, Knuth
*/
/*
* Normalize the divisor, d, and dividend, u0, u1
*/
s = mbedtls_clz( d );
d = d << s;
u1 = u1 << s;
u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
u0 = u0 << s;
d1 = d >> biH;
d0 = d & uint_halfword_mask;
u0_msw = u0 >> biH;
u0_lsw = u0 & uint_halfword_mask;
/*
* Find the first quotient and remainder
*/
q1 = u1 / d1;
r0 = u1 - d1 * q1;
while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
{
q1 -= 1;
r0 += d1;
if ( r0 >= radix ) break;
}
rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
q0 = rAX / d1;
r0 = rAX - q0 * d1;
while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
{
q0 -= 1;
r0 += d1;
if ( r0 >= radix ) break;
}
if (r != NULL)
*r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
quotient = q1 * radix + q0;
return quotient;
#endif
}
/* /*
* Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
*/ */
@ -1237,57 +1368,8 @@ int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, c
Z.p[i - t - 1] = ~0; Z.p[i - t - 1] = ~0;
else else
{ {
#if defined(MBEDTLS_HAVE_UDBL) Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
mbedtls_t_udbl r; Y.p[t], NULL);
r = (mbedtls_t_udbl) X.p[i] << biL;
r |= (mbedtls_t_udbl) X.p[i - 1];
r /= Y.p[t];
if( r > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
r = ( (mbedtls_t_udbl) 1 << biL ) - 1;
Z.p[i - t - 1] = (mbedtls_mpi_uint) r;
#else
/*
* __udiv_qrnnd_c, from gmp/longlong.h
*/
mbedtls_mpi_uint q0, q1, r0, r1;
mbedtls_mpi_uint d0, d1, d, m;
d = Y.p[t];
d0 = ( d << biH ) >> biH;
d1 = ( d >> biH );
q1 = X.p[i] / d1;
r1 = X.p[i] - d1 * q1;
r1 <<= biH;
r1 |= ( X.p[i - 1] >> biH );
m = q1 * d0;
if( r1 < m )
{
q1--, r1 += d;
while( r1 >= d && r1 < m )
q1--, r1 += d;
}
r1 -= m;
q0 = r1 / d1;
r0 = r1 - d1 * q0;
r0 <<= biH;
r0 |= ( X.p[i - 1] << biH ) >> biH;
m = q0 * d0;
if( r0 < m )
{
q0--, r0 += d;
while( r0 >= d && r0 < m )
q0--, r0 += d;
}
r0 -= m;
Z.p[i - t - 1] = ( q1 << biH ) | q0;
#endif /* MBEDTLS_HAVE_UDBL && !64-bit Apple with Clang 5.0 */
} }
Z.p[i - t - 1]++; Z.p[i - t - 1]++;
@ -1460,12 +1542,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) * 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 ) const mbedtls_mpi *T )
{ {
size_t i, n, m; size_t i, n, m;
mbedtls_mpi_uint u0, u1, *d; 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 ); memset( T->p, 0, T->n * ciL );
d = T->p; d = T->p;
@ -1493,12 +1578,14 @@ static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi
else else
/* prevent timing attacks */ /* prevent timing attacks */
mpi_sub_hlp( n, A->p, T->p ); mpi_sub_hlp( n, A->p, T->p );
return( 0 );
} }
/* /*
* Montgomery reduction: A = A * R^-1 mod N * 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_uint z = 1;
mbedtls_mpi U; mbedtls_mpi U;
@ -1506,7 +1593,7 @@ static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint
U.n = U.s = (int) z; U.n = U.s = (int) z;
U.p = &z; U.p = &z;
mpi_montmul( A, &U, N, mm, T ); return( mpi_montmul( A, &U, N, mm, T ) );
} }
/* /*
@ -1583,13 +1670,13 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
else else
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); 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 * X = R^2 * R^-1 mod N = R mod N
*/ */
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); 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 ) if( wsize > 1 )
{ {
@ -1602,7 +1689,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] ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
for( i = 0; i < wsize - 1; i++ ) 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] * W[i] = W[i - 1] * W[1]
@ -1612,7 +1699,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_grow( &W[i], N->n + 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 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 ) );
} }
} }
@ -1649,7 +1736,7 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
/* /*
* out of window, square X * out of window, square X
*/ */
mpi_montmul( X, X, N, mm, &T ); MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
continue; continue;
} }
@ -1667,12 +1754,12 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
* X = X^wsize R^-1 mod N * X = X^wsize R^-1 mod N
*/ */
for( i = 0; i < wsize; i++ ) 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 * 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--; state--;
nbits = 0; nbits = 0;
@ -1685,18 +1772,18 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi
*/ */
for( i = 0; i < nbits; i++ ) 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; wbits <<= 1;
if( ( wbits & ( one << wsize ) ) != 0 ) 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 * 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 )
{ {

View File

@ -41,7 +41,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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;
} }
/* /*

View File

@ -50,7 +50,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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, mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64,
( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" );
memcpy( src, camellia_test_cbc_iv, 16 ); memcpy( src, camellia_test_cbc_iv, 16 );
memcpy( dst, camellia_test_cbc_iv, 16 ); memcpy( dst, camellia_test_cbc_iv, 16 );
memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); 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++ ) {
if( v == MBEDTLS_CAMELLIA_DECRYPT ) { if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
memcpy( iv , src, 16 ); mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 );
memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); } else {
memcpy( dst, camellia_test_cbc_plain[i], 16 ); mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 );
} 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_crypt_cbc( &ctx, v, 16, iv, src, buf ); for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) {
if( memcmp( buf, dst, 16 ) != 0 ) if( v == MBEDTLS_CAMELLIA_DECRYPT ) {
{ memcpy( iv , src, 16 );
if( verbose != 0 ) memcpy( src, camellia_test_cbc_cipher[u][i], 16 );
mbedtls_printf( "failed\n" ); 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 ) if( verbose != 0 )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );

View File

@ -51,7 +51,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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 #define CCM_ENCRYPT 0

View File

@ -45,13 +45,24 @@
#include "mbedtls/ccm.h" #include "mbedtls/ccm.h"
#endif #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) #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER)
#define MBEDTLS_CIPHER_MODE_STREAM #define MBEDTLS_CIPHER_MODE_STREAM
#endif #endif
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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; static int supported_init = 0;
@ -127,6 +138,14 @@ void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx )
if( ctx == NULL ) if( ctx == NULL )
return; 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 ) if( ctx->cipher_ctx )
ctx->cipher_info->base->ctx_free_func( 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 ) size_t ilen, unsigned char *output, size_t *olen )
{ {
int ret; int ret;
size_t block_size = 0;
if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) 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; *olen = 0;
block_size = mbedtls_cipher_get_block_size( ctx );
if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) 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 ); return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED );
*olen = ilen; *olen = ilen;
@ -285,8 +306,13 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
} }
#endif #endif
if ( 0 == block_size )
{
return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
}
if( input == output && 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 ); 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 there is not enough data for a full block, cache it.
*/ */
if( ( ctx->operation == MBEDTLS_DECRYPT && if( ( ctx->operation == MBEDTLS_DECRYPT &&
ilen + ctx->unprocessed_len <= mbedtls_cipher_get_block_size( ctx ) ) || ilen + ctx->unprocessed_len <= block_size ) ||
( ctx->operation == MBEDTLS_ENCRYPT && ( ctx->operation == MBEDTLS_ENCRYPT &&
ilen + ctx->unprocessed_len < mbedtls_cipher_get_block_size( ctx ) ) ) ilen + ctx->unprocessed_len < block_size ) )
{ {
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
ilen ); ilen );
@ -314,22 +340,22 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
/* /*
* Process cached data first * 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, memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
copy_len ); copy_len );
if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, 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 ) ) ) ctx->unprocessed_data, output ) ) )
{ {
return( ret ); return( ret );
} }
*olen += mbedtls_cipher_get_block_size( ctx ); *olen += block_size;
output += mbedtls_cipher_get_block_size( ctx ); output += block_size;
ctx->unprocessed_len = 0; ctx->unprocessed_len = 0;
input += copy_len; input += copy_len;
@ -341,9 +367,14 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i
*/ */
if( 0 != ilen ) 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 ) 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] ), memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
copy_len ); copy_len );

1073
Externals/mbedtls/library/cmac.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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 * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow
* tests to succeed (which require known length fixed entropy) * NIST tests to succeed (which require known length fixed entropy)
*/ */
int mbedtls_ctr_drbg_seed_entropy_len( int mbedtls_ctr_drbg_seed_entropy_len(
mbedtls_ctr_drbg_context *ctx, mbedtls_ctr_drbg_context *ctx,

View File

@ -27,22 +27,24 @@
#if defined(MBEDTLS_DEBUG_C) #if defined(MBEDTLS_DEBUG_C)
#include "mbedtls/debug.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#include <stdlib.h> #include <stdlib.h>
#define mbedtls_calloc calloc #define mbedtls_calloc calloc
#define mbedtls_free free #define mbedtls_free free
#define mbedtls_time_t time_t
#define mbedtls_snprintf snprintf #define mbedtls_snprintf snprintf
#endif #endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) #include "mbedtls/debug.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
#endif #endif
@ -84,7 +86,7 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level,
char str[DEBUG_BUF_SIZE]; char str[DEBUG_BUF_SIZE];
int ret; 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; return;
va_start( argp, format ); va_start( argp, format );

View File

@ -50,7 +50,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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;
} }
/* /*

View File

@ -19,9 +19,12 @@
* This file is part of mbed TLS (https://tls.mbed.org) * 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) #if !defined(MBEDTLS_CONFIG_FILE)

1103
Externals/mbedtls/library/ecjpake.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,8 @@
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
#endif #endif
@ -402,6 +403,22 @@ int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt )
return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 );
} }
/*
* Compare two points lazyly
*/
int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P,
const mbedtls_ecp_point *Q )
{
if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 &&
mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 &&
mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 )
{
return( 0 );
}
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
}
/* /*
* Import a non-zero point from ASCII strings * Import a non-zero point from ASCII strings
*/ */
@ -1666,8 +1683,39 @@ cleanup:
} }
#endif /* ECP_SHORTWEIERSTRASS */ #endif /* ECP_SHORTWEIERSTRASS */
/*
* R = m * P with shortcuts for m == 1 and m == -1
* NOT constant-time - ONLY for short Weierstrass!
*/
static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
mbedtls_ecp_point *R,
const mbedtls_mpi *m,
const mbedtls_ecp_point *P )
{
int ret;
if( mbedtls_mpi_cmp_int( m, 1 ) == 0 )
{
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
}
else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 )
{
MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) );
if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 )
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) );
}
else
{
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
}
cleanup:
return( ret );
}
/* /*
* Linear combination * Linear combination
* NOT constant-time
*/ */
int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
const mbedtls_mpi *m, const mbedtls_ecp_point *P, const mbedtls_mpi *m, const mbedtls_ecp_point *P,
@ -1681,8 +1729,9 @@ int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_ecp_point_init( &mP ); mbedtls_ecp_point_init( &mP );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &mP, m, P, NULL, NULL ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) );
MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, n, Q, NULL, NULL ) ); MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) );
MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) );
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
@ -1761,9 +1810,11 @@ int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *
} }
/* /*
* Generate a keypair * Generate a keypair with configurable base point
*/ */
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t), int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng ) void *p_rng )
{ {
@ -1776,7 +1827,9 @@ int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp
/* [M225] page 5 */ /* [M225] page 5 */
size_t b; 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 */ /* Make sure the most significant bit is nbits */
b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */ b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
@ -1835,7 +1888,18 @@ cleanup:
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
return( mbedtls_ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) ); return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
}
/*
* Generate key pair, wrapper for conventional base point
*/
int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
} }
/* /*

View File

@ -31,7 +31,8 @@
#include <string.h> #include <string.h>
#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && !defined(inline) #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \
!defined(inline) && !defined(__cplusplus)
#define inline __inline #define inline __inline
#endif #endif

View File

@ -1,7 +1,7 @@
/* /*
* Entropy accumulator implementation * 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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -27,6 +27,12 @@
#if defined(MBEDTLS_ENTROPY_C) #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.h"
#include "mbedtls/entropy_poll.h" #include "mbedtls/entropy_poll.h"
@ -36,6 +42,10 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#include "mbedtls/platform.h"
#endif
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
@ -73,6 +83,11 @@ void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
mbedtls_havege_init( &ctx->havege_data ); mbedtls_havege_init( &ctx->havege_data );
#endif #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_DEFAULT_ENTROPY_SOURCES)
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, 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_MIN_HARDWARE,
MBEDTLS_ENTROPY_SOURCE_STRONG ); MBEDTLS_ENTROPY_SOURCE_STRONG );
#endif #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 */ #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
} }
@ -272,6 +292,18 @@ int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 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 defined(MBEDTLS_THREADING_C)
if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
return( ret ); return( ret );
@ -346,6 +378,27 @@ exit:
return( ret ); 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) #if defined(MBEDTLS_FS_IO)
int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) 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 */ #endif /* MBEDTLS_FS_IO */
#if defined(MBEDTLS_SELF_TEST) #if defined(MBEDTLS_SELF_TEST)
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
/* /*
* Dummy source function * Dummy source function
*/ */
@ -416,6 +470,105 @@ static int entropy_dummy_source( void *data, unsigned char *output,
return( 0 ); 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 * 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 mbedtls_entropy_self_test( int verbose )
{ {
int ret = 0; int ret = 1;
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
mbedtls_entropy_context ctx; mbedtls_entropy_context ctx;
unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
size_t i, j; size_t i, j;
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( " ENTROPY test: " ); mbedtls_printf( " ENTROPY test: " );
#if !defined(MBEDTLS_TEST_NULL_ENTROPY)
mbedtls_entropy_init( &ctx ); mbedtls_entropy_init( &ctx );
/* First do a gather to make sure we have default sources */ /* 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: cleanup:
mbedtls_entropy_free( &ctx ); mbedtls_entropy_free( &ctx );
#endif /* !MBEDTLS_TEST_NULL_ENTROPY */
if( verbose != 0 ) if( verbose != 0 )
{ {

View File

@ -1,7 +1,7 @@
/* /*
* Platform-specific and custom entropy polling functions * 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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -37,8 +37,17 @@
#if defined(MBEDTLS_HAVEGE_C) #if defined(MBEDTLS_HAVEGE_C)
#include "mbedtls/havege.h" #include "mbedtls/havege.h"
#endif #endif
#if defined(MBEDTLS_ENTROPY_NV_SEED)
#include "mbedtls/platform.h"
#endif
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) #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) && !defined(EFIX64) && !defined(EFI32)
#if !defined(_WIN32_WINNT) #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 ) if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
{
CryptReleaseContext( provider, 0 );
return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
}
CryptReleaseContext( provider, 0 ); CryptReleaseContext( provider, 0 );
*olen = len; *olen = len;
@ -179,6 +191,23 @@ int mbedtls_platform_entropy_poll( void *data,
#endif /* _WIN32 && !EFIX64 && !EFI32 */ #endif /* _WIN32 && !EFIX64 && !EFI32 */
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ #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) #if defined(MBEDTLS_TIMING_C)
int mbedtls_hardclock_poll( void *data, int mbedtls_hardclock_poll( void *data,
unsigned char *output, size_t len, size_t *olen ) unsigned char *output, size_t len, size_t *olen )
@ -213,4 +242,27 @@ int mbedtls_havege_poll( void *data,
} }
#endif /* MBEDTLS_HAVEGE_C */ #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 */ #endif /* MBEDTLS_ENTROPY_C */

View File

@ -34,6 +34,7 @@
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#define mbedtls_snprintf snprintf #define mbedtls_snprintf snprintf
#define mbedtls_time_t time_t
#endif #endif
#if defined(MBEDTLS_ERROR_C) #if defined(MBEDTLS_ERROR_C)
@ -101,7 +102,7 @@
#endif #endif
#if defined(MBEDTLS_NET_C) #if defined(MBEDTLS_NET_C)
#include "mbedtls/net.h" #include "mbedtls/net_sockets.h"
#endif #endif
#if defined(MBEDTLS_OID_C) #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" ); mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); 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 */ #endif /* MBEDTLS_CIPHER_C */
#if defined(MBEDTLS_DHM_C) #if defined(MBEDTLS_DHM_C)
@ -430,6 +433,12 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); 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 */ #endif /* MBEDTLS_SSL_TLS_C */
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) #if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)

View File

@ -362,7 +362,7 @@ int mbedtls_gcm_update( mbedtls_gcm_context *ctx,
/* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes
* Also check for possible overflow */ * Also check for possible overflow */
if( ctx->len + length < ctx->len || if( ctx->len + length < ctx->len ||
(uint64_t) ctx->len + length > 0x03FFFFE0ull ) (uint64_t) ctx->len + length > 0xFFFFFFFE0ull )
{ {
return( MBEDTLS_ERR_GCM_BAD_INPUT ); return( MBEDTLS_ERR_GCM_BAD_INPUT );
} }
@ -415,8 +415,7 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx,
if( tag_len > 16 || tag_len < 4 ) if( tag_len > 16 || tag_len < 4 )
return( MBEDTLS_ERR_GCM_BAD_INPUT ); 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 ) if( orig_len || orig_add_len )
{ {

View File

@ -174,6 +174,8 @@ static void havege_fill( mbedtls_havege_state *hs )
PTX = U1 = 0; PTX = U1 = 0;
PTY = U2 = 0; PTY = U2 = 0;
(void)PTX;
memset( RES, 0, sizeof( RES ) ); memset( RES, 0, sizeof( RES ) );
while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 )

View File

@ -417,6 +417,12 @@ static void buffer_alloc_free( void *ptr )
heap.total_used -= hdr->size; heap.total_used -= hdr->size;
#endif #endif
#if defined(MBEDTLS_MEMORY_BACKTRACE)
free( hdr->trace );
hdr->trace = NULL;
hdr->trace_count = 0;
#endif
// Regroup with block before // Regroup with block before
// //
if( hdr->prev != NULL && hdr->prev->alloc == 0 ) if( hdr->prev != NULL && hdr->prev->alloc == 0 )
@ -432,9 +438,6 @@ static void buffer_alloc_free( void *ptr )
if( hdr->next != NULL ) if( hdr->next != NULL )
hdr->next->prev = hdr; hdr->next->prev = hdr;
#if defined(MBEDTLS_MEMORY_BACKTRACE)
free( old->trace );
#endif
memset( old, 0, sizeof(memory_header) ); memset( old, 0, sizeof(memory_header) );
} }
@ -474,9 +477,6 @@ static void buffer_alloc_free( void *ptr )
if( hdr->next != NULL ) if( hdr->next != NULL )
hdr->next->prev = hdr; hdr->next->prev = hdr;
#if defined(MBEDTLS_MEMORY_BACKTRACE)
free( old->trace );
#endif
memset( old, 0, sizeof(memory_header) ); memset( old, 0, sizeof(memory_header) );
} }
@ -491,11 +491,6 @@ static void buffer_alloc_free( void *ptr )
heap.first_free = hdr; 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 ) if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 )
mbedtls_exit( 1 ); mbedtls_exit( 1 );
} }

View File

@ -27,7 +27,18 @@
#if defined(MBEDTLS_NET_C) #if defined(MBEDTLS_NET_C)
#include "mbedtls/net.h" #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
!defined(__APPLE__) && !defined(_WIN32)
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
#endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#endif
#include "mbedtls/net_sockets.h"
#include <string.h> #include <string.h>
@ -81,7 +92,6 @@ static int wsa_init_done = 0;
#define MSVC_INT_CAST #define MSVC_INT_CAST
#endif #endif
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@ -292,7 +302,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
struct sockaddr_storage client_addr; struct sockaddr_storage client_addr;
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
defined(_SOCKLEN_T_DECLARED) defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t n = (socklen_t) sizeof( client_addr );
socklen_t type_len = (socklen_t) sizeof( type ); socklen_t type_len = (socklen_t) sizeof( type );
#else #else

View File

@ -152,6 +152,7 @@ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \
return( MBEDTLS_ERR_OID_NOT_FOUND ); \ return( MBEDTLS_ERR_OID_NOT_FOUND ); \
} }
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
/* /*
* For X520 attribute types * For X520 attribute types
*/ */
@ -247,7 +248,6 @@ static const oid_x520_attr_t oid_x520_attr_type[] =
FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) 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) 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 * For X509 extensions
*/ */
@ -267,7 +267,7 @@ static const oid_x509_ext_t oid_x509_ext[] =
MBEDTLS_X509_EXT_KEY_USAGE, MBEDTLS_X509_EXT_KEY_USAGE,
}, },
{ {
{ ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-keyUsage", "Extended Key Usage" }, { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" },
MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE, MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE,
}, },
{ {
@ -314,22 +314,32 @@ typedef struct {
static const oid_sig_alg_t oid_sig_alg[] = 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" }, { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" },
MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, 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" }, { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" },
MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, 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" }, { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" },
MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, 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" }, { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" },
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, 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" }, { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" },
MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA,
@ -338,6 +348,8 @@ static const oid_sig_alg_t oid_sig_alg[] =
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" },
MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, 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" }, { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" },
MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA,
@ -346,14 +358,22 @@ static const oid_sig_alg_t oid_sig_alg[] =
{ ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" },
MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, 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" }, { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" },
MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA,
}, },
#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" }, { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" },
MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, 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" }, { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" },
MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA,
@ -362,6 +382,8 @@ static const oid_sig_alg_t oid_sig_alg[] =
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" },
MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, 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" }, { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" },
MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA,
@ -370,10 +392,14 @@ static const oid_sig_alg_t oid_sig_alg[] =
{ ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" },
MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, 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" }, { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" },
MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS,
}, },
#endif /* MBEDTLS_RSA_C */
{ {
{ NULL, 0, NULL, NULL }, { NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, MBEDTLS_MD_NONE, MBEDTLS_PK_NONE,
@ -429,50 +455,72 @@ typedef struct {
static const oid_ecp_grp_t oid_ecp_grp[] = 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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" },
MBEDTLS_ECP_DP_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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" },
MBEDTLS_ECP_DP_BP256R1, 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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" },
MBEDTLS_ECP_DP_BP384R1, 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" }, { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" },
MBEDTLS_ECP_DP_BP512R1, MBEDTLS_ECP_DP_BP512R1,
}, },
#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */
{ {
{ NULL, 0, NULL, NULL }, { NULL, 0, NULL, NULL },
MBEDTLS_ECP_DP_NONE, MBEDTLS_ECP_DP_NONE,
@ -524,22 +572,31 @@ typedef struct {
static const oid_md_alg_t oid_md_alg[] = static const oid_md_alg_t oid_md_alg[] =
{ {
#if defined(MBEDTLS_MD2_C)
{ {
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" },
MBEDTLS_MD_MD2, MBEDTLS_MD_MD2,
}, },
#endif /* MBEDTLS_MD2_C */
#if defined(MBEDTLS_MD4_C)
{ {
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" },
MBEDTLS_MD_MD4, MBEDTLS_MD_MD4,
}, },
#endif /* MBEDTLS_MD4_C */
#if defined(MBEDTLS_MD5_C)
{ {
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" },
MBEDTLS_MD_MD5, MBEDTLS_MD_MD5,
}, },
#endif /* MBEDTLS_MD5_C */
#if defined(MBEDTLS_SHA1_C)
{ {
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" },
MBEDTLS_MD_SHA1, MBEDTLS_MD_SHA1,
}, },
#endif /* MBEDTLS_SHA1_C */
#if defined(MBEDTLS_SHA256_C)
{ {
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" },
MBEDTLS_MD_SHA224, MBEDTLS_MD_SHA224,
@ -548,6 +605,8 @@ static const oid_md_alg_t oid_md_alg[] =
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" },
MBEDTLS_MD_SHA256, MBEDTLS_MD_SHA256,
}, },
#endif /* MBEDTLS_SHA256_C */
#if defined(MBEDTLS_SHA512_C)
{ {
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" },
MBEDTLS_MD_SHA384, MBEDTLS_MD_SHA384,
@ -556,6 +615,7 @@ static const oid_md_alg_t oid_md_alg[] =
{ ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" },
MBEDTLS_MD_SHA512, MBEDTLS_MD_SHA512,
}, },
#endif /* MBEDTLS_SHA512_C */
{ {
{ NULL, 0, NULL, NULL }, { NULL, 0, NULL, NULL },
MBEDTLS_MD_NONE, MBEDTLS_MD_NONE,

View File

@ -316,6 +316,9 @@ int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const
( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */
} }
if( s1 == s2 )
return( MBEDTLS_ERR_PEM_INVALID_DATA );
ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 );
if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER )

View File

@ -86,15 +86,20 @@ static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params,
return( 0 ); return( 0 );
} }
#define PKCS12_MAX_PWDLEN 128
static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type,
const unsigned char *pwd, size_t pwdlen, const unsigned char *pwd, size_t pwdlen,
unsigned char *key, size_t keylen, unsigned char *key, size_t keylen,
unsigned char *iv, size_t ivlen ) unsigned char *iv, size_t ivlen )
{ {
int ret, iterations; int ret, iterations = 0;
mbedtls_asn1_buf salt; mbedtls_asn1_buf salt;
size_t i; size_t i;
unsigned char unipwd[258]; unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2];
if( pwdlen > PKCS12_MAX_PWDLEN )
return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA );
memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); memset( &salt, 0, sizeof(mbedtls_asn1_buf) );
memset( &unipwd, 0, sizeof(unipwd) ); memset( &unipwd, 0, sizeof(unipwd) );
@ -125,6 +130,8 @@ static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_ty
return( 0 ); return( 0 );
} }
#undef PKCS12_MAX_PWDLEN
int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode,
const unsigned char *pwd, size_t pwdlen, const unsigned char *pwd, size_t pwdlen,
const unsigned char *data, size_t len, const unsigned char *data, size_t len,

View File

@ -391,7 +391,8 @@ int mbedtls_pkcs5_self_test( int verbose )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
} }
mbedtls_printf( "\n" ); if( verbose != 0 )
mbedtls_printf( "\n" );
exit: exit:
mbedtls_md_free( &sha1_ctx ); mbedtls_md_free( &sha1_ctx );

View File

@ -1181,6 +1181,7 @@ int mbedtls_pk_parse_key( mbedtls_pk_context *pk,
return( ret ); return( ret );
#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ #endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */
#else #else
((void) ret);
((void) pwd); ((void) pwd);
((void) pwdlen); ((void) pwdlen);
#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_PEM_PARSE_C */

View File

@ -96,7 +96,7 @@ static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
return( ret ); return( ret );
} }
if( *p - start < (int) len ) if( *p < start || (size_t)( *p - start ) < len )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*p -= len; *p -= len;

View File

@ -1,7 +1,7 @@
/* /*
* Platform abstraction layer * 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 * SPDX-License-Identifier: Apache-2.0
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may * Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -190,4 +190,118 @@ int mbedtls_platform_set_exit( void (*exit_func)( int status ) )
} }
#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ #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( 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( 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 */
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */

View File

@ -456,6 +456,9 @@ int mbedtls_ripemd160_self_test( int verbose )
mbedtls_printf( "passed\n" ); mbedtls_printf( "passed\n" );
} }
if( verbose != 0 )
mbedtls_printf( "\n" );
return( 0 ); return( 0 );
} }

View File

@ -19,10 +19,16 @@
* This file is part of mbed TLS (https://tls.mbed.org) * 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
* *
* http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
* http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
*/ */
#if !defined(MBEDTLS_CONFIG_FILE) #if !defined(MBEDTLS_CONFIG_FILE)
@ -96,7 +102,11 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
if( f_rng == NULL || nbits < 128 || exponent < 3 ) if( f_rng == NULL || nbits < 128 || exponent < 3 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 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: * find primes P and Q with Q < P so that:
@ -106,15 +116,12 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
do 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 ) ); 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 ) ); 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 ) if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
continue; continue;
@ -122,6 +129,9 @@ int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx,
if( mbedtls_mpi_bitlen( &ctx->N ) != nbits ) if( mbedtls_mpi_bitlen( &ctx->N ) != nbits )
continue; 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( &P1, &ctx->P, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) );
@ -359,6 +369,10 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
size_t olen; size_t olen;
mbedtls_mpi T, T1, T2; mbedtls_mpi T, T1, T2;
/* 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( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
@ -461,8 +475,7 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src,
hlen = mbedtls_md_get_size( md_ctx->md_info ); hlen = mbedtls_md_get_size( md_ctx->md_info );
// Generate and apply dbMask /* Generate and apply dbMask */
//
p = dst; p = dst;
while( dlen > 0 ) while( dlen > 0 )
@ -519,22 +532,21 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
olen = ctx->len; olen = ctx->len;
hlen = mbedtls_md_get_size( md_info ); 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 ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
memset( output, 0, olen ); memset( output, 0, olen );
*p++ = 0; *p++ = 0;
// Generate a random octet string seed /* Generate a random octet string seed */
//
if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
p += hlen; p += hlen;
// Construct DB /* Construct DB */
//
mbedtls_md( md_info, label, label_len, p ); mbedtls_md( md_info, label, label_len, p );
p += hlen; p += hlen;
p += olen - 2 * hlen - 2 - ilen; p += olen - 2 * hlen - 2 - ilen;
@ -542,15 +554,17 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
memcpy( p, input, ilen ); memcpy( p, input, ilen );
mbedtls_md_init( &md_ctx ); 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, mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
&md_ctx ); &md_ctx );
// maskedSeed: Apply seedMask to seed /* maskedSeed: Apply seedMask to seed */
//
mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
&md_ctx ); &md_ctx );
@ -580,12 +594,14 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 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 ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
olen = ctx->len; 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 ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
nb_pad = olen - 3 - ilen; nb_pad = olen - 3 - ilen;
@ -603,8 +619,7 @@ int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
ret = f_rng( p_rng, p, 1 ); ret = f_rng( p_rng, p, 1 );
} while( *p == 0 && --rng_dl && ret == 0 ); } 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 ) if( rng_dl == 0 || ret != 0 )
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );
@ -695,6 +710,12 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
if( md_info == NULL ) if( md_info == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); 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 * RSA operation
*/ */
@ -708,10 +729,13 @@ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
/* /*
* Unmask data and generate lHash * Unmask data and generate lHash
*/ */
hlen = mbedtls_md_get_size( md_info );
mbedtls_md_init( &md_ctx ); 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 );
}
/* Generate lHash */ /* Generate lHash */
mbedtls_md( md_info, label, label_len, lhash ); mbedtls_md( md_info, label, label_len, lhash );
@ -844,6 +868,8 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
bad |= *p++; /* Must be zero */ bad |= *p++; /* Must be zero */
} }
bad |= ( pad_count < 8 );
if( bad ) if( bad )
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); return( MBEDTLS_ERR_RSA_INVALID_PADDING );
@ -920,8 +946,7 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
if( md_alg != MBEDTLS_MD_NONE ) 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 ); md_info = mbedtls_md_info_from_type( md_alg );
if( md_info == NULL ) if( md_info == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -941,13 +966,11 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
memset( sig, 0, olen ); memset( sig, 0, olen );
// Generate salt of length slen /* Generate salt of length slen */
//
if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); 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; msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;
p += olen - hlen * 2 - 2; p += olen - hlen * 2 - 2;
*p++ = 0x01; *p++ = 0x01;
@ -955,23 +978,24 @@ int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
p += slen; p += slen;
mbedtls_md_init( &md_ctx ); 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 );
}
// Generate H = Hash( M' ) /* Generate H = Hash( M' ) */
//
mbedtls_md_starts( &md_ctx ); mbedtls_md_starts( &md_ctx );
mbedtls_md_update( &md_ctx, p, 8 ); mbedtls_md_update( &md_ctx, p, 8 );
mbedtls_md_update( &md_ctx, hash, hashlen ); mbedtls_md_update( &md_ctx, hash, hashlen );
mbedtls_md_update( &md_ctx, salt, slen ); mbedtls_md_update( &md_ctx, salt, slen );
mbedtls_md_finish( &md_ctx, p ); mbedtls_md_finish( &md_ctx, p );
// Compensate for boundary condition when applying mask /* Compensate for boundary condition when applying mask */
//
if( msb % 8 == 0 ) if( msb % 8 == 0 )
offset = 1; offset = 1;
// maskedDB: Apply dbMask to DB /* maskedDB: Apply dbMask to DB */
//
mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx ); mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
mbedtls_md_free( &md_ctx ); mbedtls_md_free( &md_ctx );
@ -1082,10 +1106,16 @@ int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
* temporary buffer and check it before returning it. * temporary buffer and check it before returning it.
*/ */
sig_try = mbedtls_calloc( 1, ctx->len ); sig_try = mbedtls_calloc( 1, ctx->len );
verif = mbedtls_calloc( 1, ctx->len ); if( sig_try == NULL )
if( sig_try == NULL || verif == NULL )
return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
verif = mbedtls_calloc( 1, ctx->len );
if( verif == NULL )
{
mbedtls_free( sig_try );
return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
}
MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) ); MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) );
MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) ); MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) );
@ -1159,13 +1189,13 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
int ret; int ret;
size_t siglen; size_t siglen;
unsigned char *p; unsigned char *p;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
unsigned char result[MBEDTLS_MD_MAX_SIZE]; unsigned char result[MBEDTLS_MD_MAX_SIZE];
unsigned char zeros[8]; unsigned char zeros[8];
unsigned int hlen; unsigned int hlen;
size_t slen, msb; size_t slen, msb;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_md_context_t md_ctx; mbedtls_md_context_t md_ctx;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1189,8 +1219,7 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
if( md_alg != MBEDTLS_MD_NONE ) 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 ); md_info = mbedtls_md_info_from_type( md_alg );
if( md_info == NULL ) if( md_info == NULL )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1207,12 +1236,12 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
memset( zeros, 0, 8 ); 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; 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 ) if( msb % 8 == 0 )
{ {
p++; p++;
@ -1222,7 +1251,11 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
mbedtls_md_init( &md_ctx ); 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 ); mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );
@ -1248,8 +1281,9 @@ int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
return( MBEDTLS_ERR_RSA_INVALID_PADDING ); return( MBEDTLS_ERR_RSA_INVALID_PADDING );
} }
// Generate H = Hash( M' ) /*
// * Generate H = Hash( M' )
*/
mbedtls_md_starts( &md_ctx ); mbedtls_md_starts( &md_ctx );
mbedtls_md_update( &md_ctx, zeros, 8 ); mbedtls_md_update( &md_ctx, zeros, 8 );
mbedtls_md_update( &md_ctx, hash, hashlen ); mbedtls_md_update( &md_ctx, hash, hashlen );
@ -1304,10 +1338,10 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
int ret; int ret;
size_t len, siglen, asn1_len; size_t len, siglen, asn1_len;
unsigned char *p, *end; unsigned char *p, *end;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
mbedtls_md_type_t msg_md_alg; mbedtls_md_type_t msg_md_alg;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
mbedtls_asn1_buf oid; mbedtls_asn1_buf oid;
unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 )
return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
@ -1354,8 +1388,9 @@ int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
end = p + len; 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
*/
if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); return( MBEDTLS_ERR_RSA_VERIFY_FAILED );
@ -1650,7 +1685,7 @@ int mbedtls_rsa_self_test( int verbose )
#if defined(MBEDTLS_SHA1_C) #if defined(MBEDTLS_SHA1_C)
if( verbose != 0 ) if( verbose != 0 )
mbedtls_printf( "PKCS#1 data sign : " ); mbedtls_printf( " PKCS#1 data sign : " );
mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum ); mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum );

View File

@ -49,7 +49,7 @@
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { 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;
} }
/* /*

View File

@ -41,7 +41,10 @@
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#define mbedtls_printf printf #define mbedtls_printf printf
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
@ -389,10 +392,19 @@ static const unsigned char sha256_test_sum[6][32] =
int mbedtls_sha256_self_test( int verbose ) int mbedtls_sha256_self_test( int verbose )
{ {
int i, j, k, buflen, ret = 0; int i, j, k, buflen, ret = 0;
unsigned char buf[1024]; unsigned char *buf;
unsigned char sha256sum[32]; unsigned char sha256sum[32];
mbedtls_sha256_context ctx; 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 ); mbedtls_sha256_init( &ctx );
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
@ -436,6 +448,7 @@ int mbedtls_sha256_self_test( int verbose )
exit: exit:
mbedtls_sha256_free( &ctx ); mbedtls_sha256_free( &ctx );
mbedtls_free( buf );
return( ret ); return( ret );
} }

View File

@ -47,7 +47,10 @@
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#define mbedtls_printf printf #define mbedtls_printf printf
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif /* MBEDTLS_PLATFORM_C */ #endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_SELF_TEST */
@ -89,53 +92,6 @@ static void mbedtls_zeroize( void *v, size_t n ) {
} }
#endif /* PUT_UINT64_BE */ #endif /* PUT_UINT64_BE */
/*
* 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_init( mbedtls_sha512_context *ctx ) void mbedtls_sha512_init( mbedtls_sha512_context *ctx )
{ {
memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); memset( ctx, 0, sizeof( mbedtls_sha512_context ) );
@ -192,6 +148,54 @@ void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 )
} }
#if !defined(MBEDTLS_SHA512_PROCESS_ALT) #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] ) void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
{ {
int i; int i;
@ -444,10 +448,19 @@ static const unsigned char sha512_test_sum[6][64] =
int mbedtls_sha512_self_test( int verbose ) int mbedtls_sha512_self_test( int verbose )
{ {
int i, j, k, buflen, ret = 0; int i, j, k, buflen, ret = 0;
unsigned char buf[1024]; unsigned char *buf;
unsigned char sha512sum[64]; unsigned char sha512sum[64];
mbedtls_sha512_context ctx; 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 ); mbedtls_sha512_init( &ctx );
for( i = 0; i < 6; i++ ) for( i = 0; i < 6; i++ )
@ -491,6 +504,7 @@ int mbedtls_sha512_self_test( int verbose )
exit: exit:
mbedtls_sha512_free( &ctx ); mbedtls_sha512_free( &ctx );
mbedtls_free( buf );
return( ret ); return( ret );
} }

View File

@ -31,18 +31,18 @@
#if defined(MBEDTLS_SSL_CACHE_C) #if defined(MBEDTLS_SSL_CACHE_C)
#include "mbedtls/ssl_cache.h"
#include <string.h>
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#include <stdlib.h> #include <stdlib.h>
#define mbedtls_calloc calloc #define mbedtls_calloc calloc
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#include "mbedtls/ssl_cache.h"
#include <string.h>
void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
{ {
memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); 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; int ret = 1;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
time_t t = time( NULL ); mbedtls_time_t t = mbedtls_time( NULL );
#endif #endif
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
mbedtls_ssl_cache_entry *cur, *entry; 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; int ret = 1;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
time_t t = time( NULL ), oldest = 0; mbedtls_time_t t = time( NULL ), oldest = 0;
mbedtls_ssl_cache_entry *old = NULL; mbedtls_ssl_cache_entry *old = NULL;
#endif #endif
mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;

View File

@ -29,10 +29,15 @@
#if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_TLS_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#endif
#include "mbedtls/ssl_ciphersuites.h" #include "mbedtls/ssl_ciphersuites.h"
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
// #include <stdlib.h>
#include <string.h> #include <string.h>
/* /*
@ -40,7 +45,7 @@
* *
* Current rule (except rc4, weak and null which come last): * Current rule (except rc4, weak and null which come last):
* 1. By key exchange: * 1. By key exchange:
* Forward-secure non-PSK > forward-secure PSK > other non-PSK > other PSK * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK
* 2. By key length and cipher: * 2. By key length and cipher:
* AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES
* 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8
@ -131,6 +136,9 @@ static const int ciphersuite_preference[] =
MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
/* The ECJPAKE suite */
MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
/* All AES-256 suites */ /* All AES-256 suites */
MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384,
MBEDTLS_TLS_RSA_WITH_AES_256_CCM, MBEDTLS_TLS_RSA_WITH_AES_256_CCM,
@ -1510,6 +1518,18 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
#endif /* MBEDTLS_ARC4_C */ #endif /* MBEDTLS_ARC4_C */
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_CCM_C)
{ MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8",
MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
MBEDTLS_CIPHERSUITE_SHORT_TAG },
#endif /* MBEDTLS_CCM_C */
#endif /* MBEDTLS_AES_C */
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) #if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES)
#if defined(MBEDTLS_CIPHER_NULL_CIPHER) #if defined(MBEDTLS_CIPHER_NULL_CIPHER)
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED)

View File

@ -27,24 +27,24 @@
#if defined(MBEDTLS_SSL_CLI_C) #if defined(MBEDTLS_SSL_CLI_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include "mbedtls/debug.h" #include "mbedtls/debug.h"
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_internal.h"
#include <string.h> #include <string.h>
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include <stdint.h> #include <stdint.h>
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
#include <time.h> #include "mbedtls/platform_time.h"
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -60,6 +60,7 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t hostname_len; size_t hostname_len;
*olen = 0; *olen = 0;
@ -72,6 +73,12 @@ static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl,
hostname_len = strlen( ssl->hostname ); hostname_len = strlen( ssl->hostname );
if( end < p || (size_t)( end - p ) < hostname_len + 9 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
/* /*
* struct { * struct {
* NameType name_type; * NameType name_type;
@ -115,6 +122,7 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0; *olen = 0;
@ -123,6 +131,12 @@ static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) );
if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
/* /*
* Secure renegotiation * Secure renegotiation
*/ */
@ -149,6 +163,7 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t sig_alg_len = 0; size_t sig_alg_len = 0;
const int *md; const int *md;
#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C)
@ -162,9 +177,27 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) );
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
{
#if defined(MBEDTLS_ECDSA_C)
sig_alg_len += 2;
#endif
#if defined(MBEDTLS_RSA_C)
sig_alg_len += 2;
#endif
}
if( end < p || (size_t)( end - p ) < sig_alg_len + 6 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
/* /*
* Prepare signature_algorithms extension (TLS 1.2) * Prepare signature_algorithms extension (TLS 1.2)
*/ */
sig_alg_len = 0;
for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ )
{ {
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
@ -208,12 +241,14 @@ static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
unsigned char *elliptic_curve_list = p + 6; unsigned char *elliptic_curve_list = p + 6;
size_t elliptic_curve_len = 0; size_t elliptic_curve_len = 0;
const mbedtls_ecp_curve_info *info; const mbedtls_ecp_curve_info *info;
@ -235,7 +270,31 @@ static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl,
for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ )
{ {
#endif #endif
if( info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) );
return;
}
elliptic_curve_len += 2;
}
if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
elliptic_curve_len = 0;
#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
elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8;
elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF;
} }
@ -260,12 +319,18 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
((void) ssl); const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0; *olen = 0;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
if( end < p || (size_t)( end - p ) < 6 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
@ -277,7 +342,86 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
*olen = 6; *olen = 6;
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
int ret;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t kkpp_len;
*olen = 0;
/* Skip costly extension if we can't use EC J-PAKE anyway */
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
return;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) );
if( end - p < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
/*
* We may need to send ClientHello multiple times for Hello verification.
* We don't want to compute fresh values every time (both for performance
* and consistency reasons), so cache the extension content.
*/
if( ssl->handshake->ecjpake_cache == NULL ||
ssl->handshake->ecjpake_cache_len == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) );
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
return;
}
ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len );
if( ssl->handshake->ecjpake_cache == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) );
return;
}
memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len );
ssl->handshake->ecjpake_cache_len = kkpp_len;
}
else
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) );
kkpp_len = ssl->handshake->ecjpake_cache_len;
if( (size_t)( end - p - 2 ) < kkpp_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len );
}
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
*olen = kkpp_len + 4;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
@ -285,14 +429,22 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
size_t *olen ) size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) {
*olen = 0;
return; return;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) );
if( end < p || (size_t)( end - p ) < 5 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF );
@ -310,15 +462,23 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED )
{ {
*olen = 0;
return; return;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) );
if( end < p || (size_t)( end - p ) < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF );
@ -334,17 +494,25 @@ static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED ||
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
*olen = 0;
return; return;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac "
"extension" ) ); "extension" ) );
if( end < p || (size_t)( end - p ) < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF );
@ -360,17 +528,25 @@ static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
*olen = 0;
if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED ||
ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 )
{ {
*olen = 0;
return; return;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret "
"extension" ) ); "extension" ) );
if( end < p || (size_t)( end - p ) < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF );
@ -386,16 +562,24 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t tlen = ssl->session_negotiate->ticket_len; size_t tlen = ssl->session_negotiate->ticket_len;
*olen = 0;
if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED )
{ {
*olen = 0;
return; return;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) );
if( end < p || (size_t)( end - p ) < 4 + tlen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF );
@ -404,8 +588,7 @@ static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl,
*olen = 4; *olen = 4;
if( ssl->session_negotiate->ticket == NULL || if( ssl->session_negotiate->ticket == NULL || tlen == 0 )
ssl->session_negotiate->ticket_len == 0 )
{ {
return; return;
} }
@ -423,16 +606,28 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, size_t *olen ) unsigned char *buf, size_t *olen )
{ {
unsigned char *p = buf; unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t alpnlen = 0;
const char **cur; const char **cur;
*olen = 0;
if( ssl->conf->alpn_list == NULL ) if( ssl->conf->alpn_list == NULL )
{ {
*olen = 0;
return; return;
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) );
for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ )
alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1;
if( end < p || (size_t)( end - p ) < 6 + alpnlen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF );
@ -474,7 +669,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
int ret; int ret;
unsigned char *p = ssl->handshake->randbytes; unsigned char *p = ssl->handshake->randbytes;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
time_t t; mbedtls_time_t t;
#endif #endif
/* /*
@ -489,7 +684,7 @@ static int ssl_generate_random( mbedtls_ssl_context *ssl )
#endif #endif
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
t = time( NULL ); t = mbedtls_time( NULL );
*p++ = (unsigned char)( t >> 24 ); *p++ = (unsigned char)( t >> 24 );
*p++ = (unsigned char)( t >> 16 ); *p++ = (unsigned char)( t >> 16 );
*p++ = (unsigned char)( t >> 8 ); *p++ = (unsigned char)( t >> 8 );
@ -680,8 +875,14 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
continue; continue;
#endif #endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d", #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ciphersuites[i] ) ); if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
continue;
#endif
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x",
ciphersuites[i] ) );
n++; n++;
*p++ = (unsigned char)( ciphersuites[i] >> 8 ); *p++ = (unsigned char)( ciphersuites[i] >> 8 );
@ -771,7 +972,8 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#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)
ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
@ -779,6 +981,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
@ -799,13 +1006,13 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_ALPN)
ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#endif #endif
@ -986,7 +1193,8 @@ static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
@ -1007,7 +1215,12 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
p[0] == MBEDTLS_ECP_PF_COMPRESSED ) p[0] == MBEDTLS_ECP_PF_COMPRESSED )
{ {
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
ssl->handshake->ecdh_ctx.point_format = p[0]; ssl->handshake->ecdh_ctx.point_format = p[0];
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl->handshake->ecjpake_ctx.point_format = p[0];
#endif
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 ); return( 0 );
} }
@ -1019,7 +1232,38 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
int ret;
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 0 );
}
/* If we got here, we no longer need our cached extension */
mbedtls_free( ssl->handshake->ecjpake_cache );
ssl->handshake->ecjpake_cache = NULL;
ssl->handshake->ecjpake_cache_len = 0;
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
return( ret );
}
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
@ -1111,6 +1355,15 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
cookie_len = *p++; cookie_len = *p++;
MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); 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 ); mbedtls_free( ssl->handshake->verify_cookie );
ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len ); ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len );
@ -1348,7 +1601,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
ssl->state++; ssl->state++;
ssl->handshake->resume = 0; ssl->handshake->resume = 0;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = time( NULL ); ssl->session_negotiate->start = mbedtls_time( NULL );
#endif #endif
ssl->session_negotiate->ciphersuite = i; ssl->session_negotiate->ciphersuite = i;
ssl->session_negotiate->compression = comp; ssl->session_negotiate->compression = comp;
@ -1369,7 +1622,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed",
ssl->handshake->resume ? "a" : "no" ) ); ssl->handshake->resume ? "a" : "no" ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) );
suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite );
@ -1384,6 +1637,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
} }
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) );
i = 0; i = 0;
while( 1 ) while( 1 )
{ {
@ -1507,7 +1762,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
break; break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) );
@ -1518,7 +1774,21 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
} }
break; break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #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" ) );
if( ( ret = ssl_parse_ecjpake_kkpp( ssl,
ext + 4, ext_size ) ) != 0 )
{
return( ret );
}
break;
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN: case MBEDTLS_TLS_EXT_ALPN:
@ -1725,8 +1995,11 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); 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; *p += len;
ret = 0; ret = 0;
@ -1813,7 +2086,9 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
unsigned char **p, unsigned char **p,
unsigned char *end, unsigned char *end,
@ -1838,7 +2113,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
*/ */
if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE ) if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used unsupported " MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported "
"HashAlgorithm %d", *(p)[0] ) ); "HashAlgorithm %d", *(p)[0] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -1848,7 +2123,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
*/ */
if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE ) if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used unsupported " MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported "
"SignatureAlgorithm %d", (*p)[1] ) ); "SignatureAlgorithm %d", (*p)[1] ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -1858,7 +2133,7 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
*/ */
if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "server used HashAlgorithm " MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm "
"that was not offered" ) ); "that was not offered" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -1869,7 +2144,9 @@ static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl,
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
@ -2037,6 +2314,19 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -2230,7 +2520,9 @@ exit:
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{ {
@ -2241,7 +2533,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 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_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++; ssl->state++;
@ -2255,8 +2548,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{ {
int ret; int ret;
unsigned char *buf, *p; unsigned char *buf;
size_t n = 0, m = 0; size_t n = 0;
size_t cert_type_len = 0, dn_len = 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;
@ -2265,7 +2558,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 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_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
ssl->state++; ssl->state++;
@ -2303,9 +2597,6 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
ssl->record_read = 0; ssl->record_read = 0;
// TODO: handshake_failure alert for an anonymous server to request
// client authentication
/* /*
* struct { * struct {
* ClientCertificateType certificate_types<1..2^8-1>; * ClientCertificateType certificate_types<1..2^8-1>;
@ -2313,11 +2604,26 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
* supported_signature_algorithms<2^16-1>; -- TLS 1.2 only * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only
* DistinguishedName certificate_authorities<0..2^16-1>; * DistinguishedName certificate_authorities<0..2^16-1>;
* } CertificateRequest; * } 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; buf = ssl->in_msg;
// Retrieve cert types /* certificate_types */
//
cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )];
n = cert_type_len; n = cert_type_len;
@ -2327,45 +2633,23 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
} }
p = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 1; /* supported_signature_algorithms */
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++;
}
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) #if defined(MBEDTLS_SSL_PROTO_TLS1_2)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) 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 ) size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); | ( 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; for( i = 0; i < sig_alg_len; i += 2 )
n += sig_alg_len; {
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 ) if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n )
{ {
@ -2375,13 +2659,12 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
/* Ignore certificate_authorities, we only have one cert anyway */ /* certificate_authorities */
// TODO: should not send cert if no CA matches dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 )
dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + m + n] << 8 ) | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) );
| ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + m + n] ) );
n += dn_len; 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_DEBUG_MSG( 1, ( "bad certificate request message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST );
@ -2394,7 +2677,9 @@ exit:
} }
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl )
@ -2645,6 +2930,31 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
i = 4;
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
{ {
((void) ciphersuite_info); ((void) ciphersuite_info);
@ -2671,7 +2981,9 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{ {
@ -2689,7 +3001,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 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_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++; ssl->state++;
@ -2721,7 +3034,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 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_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++; ssl->state++;
@ -2849,7 +3163,10 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
} }
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_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) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )

View File

@ -31,16 +31,16 @@
#if defined(MBEDTLS_SSL_COOKIE_C) #if defined(MBEDTLS_SSL_COOKIE_C)
#include "mbedtls/ssl_cookie.h"
#include "mbedtls/ssl_internal.h"
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#define mbedtls_calloc calloc #define mbedtls_calloc calloc
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#include "mbedtls/ssl_cookie.h"
#include "mbedtls/ssl_internal.h"
#include <string.h> #include <string.h>
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
@ -172,7 +172,7 @@ int mbedtls_ssl_cookie_write( void *p_ctx,
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
t = (unsigned long) time( NULL ); t = (unsigned long) mbedtls_time( NULL );
#else #else
t = ctx->serial++; t = ctx->serial++;
#endif #endif
@ -242,7 +242,7 @@ int mbedtls_ssl_cookie_check( void *p_ctx,
return( -1 ); return( -1 );
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
cur_time = (unsigned long) time( NULL ); cur_time = (unsigned long) mbedtls_time( NULL );
#else #else
cur_time = ctx->serial; cur_time = ctx->serial;
#endif #endif

View File

@ -27,6 +27,14 @@
#if defined(MBEDTLS_SSL_SRV_C) #if defined(MBEDTLS_SSL_SRV_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include "mbedtls/debug.h" #include "mbedtls/debug.h"
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_internal.h"
@ -37,16 +45,8 @@
#include "mbedtls/ecp.h" #include "mbedtls/ecp.h"
#endif #endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
#include <time.h> #include "mbedtls/platform_time.h"
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -232,7 +232,8 @@ have_sig_alg:
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl,
const unsigned char *buf, const unsigned char *buf,
size_t len ) size_t len )
@ -305,7 +306,12 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED ||
p[0] == MBEDTLS_ECP_PF_COMPRESSED ) p[0] == MBEDTLS_ECP_PF_COMPRESSED )
{ {
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
ssl->handshake->ecdh_ctx.point_format = p[0]; ssl->handshake->ecdh_ctx.point_format = p[0];
#endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl->handshake->ecjpake_ctx.point_format = p[0];
#endif
MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) );
return( 0 ); return( 0 );
} }
@ -316,7 +322,35 @@ static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl,
return( 0 ); return( 0 );
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C ||
MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
int ret;
if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
return( 0 );
}
if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx,
buf, len ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret );
return( ret );
}
/* Only mark the extension as OK when we're sure it is */
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK;
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl,
@ -707,6 +741,17 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id,
} }
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE &&
( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake "
"not configured or ext missing" ) );
return( 0 );
}
#endif
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C)
if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) &&
( ssl->handshake->curves == NULL || ( ssl->handshake->curves == NULL ||
@ -998,7 +1043,6 @@ have_ciphersuite_v2:
ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
/* /*
* SSLv2 Client Hello relevant renegotiation security checks * SSLv2 Client Hello relevant renegotiation security checks
@ -1460,180 +1504,200 @@ read_record_header:
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
#endif #endif
/* /* Do not parse the extensions if the protocol is SSLv3 */
* Check the extension length #if defined(MBEDTLS_SSL_PROTO_SSL3)
*/ if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) )
ext_offset = comp_offset + 1 + comp_len;
if( msg_len > ext_offset )
{ {
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" ) ); if( msg_len < ext_offset + 2 )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
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" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
} }
else
ext_len = 0;
ext_len = ( buf[ext_offset + 0] << 8 ) ext = buf + ext_offset + 2;
| ( buf[ext_offset + 1] ); MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len );
if( ( ext_len > 0 && ext_len < 4 ) || while( ext_len != 0 )
msg_len != ext_offset + 2 + ext_len )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); unsigned int ext_id = ( ( ext[0] << 8 )
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); | ( ext[1] ) );
} unsigned int ext_size = ( ( ext[2] << 8 )
} | ( ext[3] ) );
else
ext_len = 0;
ext = buf + ext_offset + 2; if( ext_size + 4 > ext_len )
MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
while( ext_len != 0 ) return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
{ }
unsigned int ext_id = ( ( ext[0] << 8 ) switch( ext_id )
| ( 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 defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
case MBEDTLS_TLS_EXT_SERVERNAME: case MBEDTLS_TLS_EXT_SERVERNAME:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) );
if( ssl->conf->f_sni == NULL ) if( ssl->conf->f_sni == NULL )
break; break;
ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) );
#if defined(MBEDTLS_SSL_RENEGOTIATION) #if defined(MBEDTLS_SSL_RENEGOTIATION)
renegotiation_info_seen = 1; renegotiation_info_seen = 1;
#endif #endif
ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \
defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
case MBEDTLS_TLS_EXT_SIG_ALG: case MBEDTLS_TLS_EXT_SIG_ALG:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) );
#if defined(MBEDTLS_SSL_RENEGOTIATION) #if defined(MBEDTLS_SSL_RENEGOTIATION)
if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
break; break;
#endif #endif
ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && #endif /* MBEDTLS_SSL_PROTO_TLS1_2 &&
MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
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 ); ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT;
ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #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" ) );
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) #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) );
ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) #if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: case MBEDTLS_TLS_EXT_TRUNCATED_HMAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) );
ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) );
ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ #endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) );
ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ #endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
case MBEDTLS_TLS_EXT_SESSION_TICKET: case MBEDTLS_TLS_EXT_SESSION_TICKET:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) );
ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
case MBEDTLS_TLS_EXT_ALPN: case MBEDTLS_TLS_EXT_ALPN:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) );
ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
break; break;
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
default: default:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
ext_id ) ); ext_id ) );
} }
ext_len -= 4 + ext_size; ext_len -= 4 + ext_size;
ext += 4 + ext_size; ext += 4 + ext_size;
if( ext_len > 0 && ext_len < 4 ) if( ext_len > 0 && ext_len < 4 )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
} }
#if defined(MBEDTLS_SSL_PROTO_SSL3)
} }
#endif
#if defined(MBEDTLS_SSL_FALLBACK_SCSV) #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 + 41 + sess_len; i < ciph_len; i += 2, p += 2 )
@ -1775,7 +1839,6 @@ have_ciphersuite:
ssl->session_negotiate->ciphersuite = ciphersuites[i]; ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
ssl->state++; ssl->state++;
@ -1976,7 +2039,8 @@ static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
unsigned char *buf, unsigned char *buf,
size_t *olen ) size_t *olen )
@ -2004,7 +2068,51 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl,
*olen = 6; *olen = 6;
} }
#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
unsigned char *buf,
size_t *olen )
{
int ret;
unsigned char *p = buf;
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
size_t kkpp_len;
*olen = 0;
/* Skip costly computation if not needed */
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
return;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) );
if( end - p < 4 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) );
return;
}
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF );
ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx,
p + 2, end - p - 2, &kkpp_len,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret );
return;
}
*p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( kkpp_len ) & 0xFF );
*olen = kkpp_len + 4;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_SSL_ALPN ) #if defined(MBEDTLS_SSL_ALPN )
static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
@ -2108,7 +2216,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
{ {
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
time_t t; mbedtls_time_t t;
#endif #endif
int ret; int ret;
size_t olen, ext_len = 0, n; size_t olen, ext_len = 0, n;
@ -2151,7 +2259,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
buf[4], buf[5] ) ); buf[4], buf[5] ) );
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
t = time( NULL ); t = mbedtls_time( NULL );
*p++ = (unsigned char)( t >> 24 ); *p++ = (unsigned char)( t >> 24 );
*p++ = (unsigned char)( t >> 16 ); *p++ = (unsigned char)( t >> 16 );
*p++ = (unsigned char)( t >> 8 ); *p++ = (unsigned char)( t >> 8 );
@ -2200,7 +2308,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ssl->state++; ssl->state++;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
ssl->session_negotiate->start = time( NULL ); ssl->session_negotiate->start = mbedtls_time( NULL );
#endif #endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
@ -2259,6 +2367,12 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X",
ssl->session_negotiate->compression ) ); 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 * First write extensions, then the total length
*/ */
@ -2290,11 +2404,17 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
ext_len += olen; ext_len += olen;
#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)
ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen;
#endif
#if defined(MBEDTLS_SSL_ALPN) #if defined(MBEDTLS_SSL_ALPN)
ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen );
ext_len += olen; ext_len += olen;
@ -2309,6 +2429,10 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
p += ext_len; p += ext_len;
} }
#if defined(MBEDTLS_SSL_PROTO_SSL3)
}
#endif
ssl->out_msglen = p - buf; ssl->out_msglen = p - buf;
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO;
@ -2322,7 +2446,9 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{ {
@ -2333,7 +2459,8 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 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_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
ssl->state++; ssl->state++;
@ -2351,6 +2478,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
size_t dn_size, total_dn_size; /* excluding length bytes */ size_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */ size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p; unsigned char *buf, *p;
const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
const mbedtls_x509_crt *crt; const mbedtls_x509_crt *crt;
int authmode; int authmode;
@ -2369,6 +2497,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_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_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
authmode == MBEDTLS_SSL_VERIFY_NONE ) authmode == MBEDTLS_SSL_VERIFY_NONE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
@ -2425,29 +2554,27 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
*/ */
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{ {
/* const int *cur;
* 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;
}
/* /*
* Supported signature algorithms * 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) #if defined(MBEDTLS_RSA_C)
p[2 + sa_len++] = ssl->handshake->verify_sig_alg; p[2 + sa_len++] = hash;
p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA;
#endif #endif
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
p[2 + sa_len++] = ssl->handshake->verify_sig_alg; p[2 + sa_len++] = hash;
p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA;
#endif #endif
}
p[0] = (unsigned char)( sa_len >> 8 ); p[0] = (unsigned char)( sa_len >> 8 );
p[1] = (unsigned char)( sa_len ); p[1] = (unsigned char)( sa_len );
@ -2471,10 +2598,16 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
total_dn_size = 0; total_dn_size = 0;
while( crt != NULL && crt->version != 0 ) while( crt != NULL && crt->version != 0 )
{ {
if( p - buf > 4096 )
break;
dn_size = crt->subject_raw.len; 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 >> 8 );
*p++ = (unsigned char)( dn_size ); *p++ = (unsigned char)( dn_size );
memcpy( p, crt->subject_raw.p, dn_size ); memcpy( p, crt->subject_raw.p, dn_size );
@ -2500,7 +2633,9 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
} }
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
@ -2539,12 +2674,14 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
unsigned char *p = ssl->out_msg + 4; unsigned char *p = ssl->out_msg + 4;
unsigned char *dig_signed = p; unsigned char *dig_signed = p;
size_t dig_signed_len = 0, len; size_t dig_signed_len = 0, len;
((void) dig_signed); ((void) dig_signed);
((void) dig_signed_len); ((void) dig_signed_len);
((void) len);
#endif #endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
@ -2575,12 +2712,32 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
} }
#endif #endif
#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 );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
return( ret );
}
p += jlen;
n += jlen;
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ #if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || if( 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_ECDHE_PSK )
{ {
/* TODO: Support identity hints */ /* Note: we don't support identity hints, until someone asks
* for them. */
*(p++) = 0x00; *(p++) = 0x00;
*(p++) = 0x00; *(p++) = 0x00;
@ -3326,6 +3483,28 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
} }
else else
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx,
p, end - p );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx,
ssl->handshake->premaster, 32, &ssl->handshake->pmslen,
ssl->conf->f_rng, ssl->conf->p_rng );
if( ret != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret );
return( ret );
}
}
else
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@ -3346,7 +3525,9 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ #if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{ {
@ -3357,7 +3538,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || 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_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++; ssl->state++;
@ -3387,6 +3569,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
ssl->session_negotiate->peer_cert == NULL ) ssl->session_negotiate->peer_cert == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
@ -3394,17 +3577,28 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( 0 ); return( 0 );
} }
/* Needs to be done before read_record() to exclude current message */ /* Read the message without adding it to the checksum */
ssl->handshake->calc_verify( ssl, hash ); 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 ); return( ret );
} }
ssl->state++; ssl->state++;
/* Process the message contents */
if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ||
ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY )
{ {
@ -3451,14 +3645,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
/* /*
* Hash * 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" MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
" for verify message" ) ); " for verify message" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); 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 */ /* Info from md_alg will be used instead */
hashlen = 0; hashlen = 0;
@ -3509,6 +3708,9 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); 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, if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
md_alg, hash_start, hashlen, md_alg, hash_start, hashlen,
ssl->in_msg + i, sig_len ) ) != 0 ) ssl->in_msg + i, sig_len ) ) != 0 )
@ -3517,13 +3719,18 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( ret ); return( ret );
} }
mbedtls_ssl_update_handshake_status( ssl );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) );
return( ret ); return( ret );
} }
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && #endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_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) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )

View File

@ -27,16 +27,16 @@
#if defined(MBEDTLS_SSL_TICKET_C) #if defined(MBEDTLS_SSL_TICKET_C)
#include "mbedtls/ssl_ticket.h"
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#else #else
#include <stdlib.h> #include <stdlib.h>
#define mbedtls_calloc calloc #define mbedtls_calloc calloc
#define mbedtls_free free #define mbedtls_free free
#endif #endif
#include "mbedtls/ssl_ticket.h"
#include <string.h> #include <string.h>
/* Implementation that should never be optimized out by the compiler */ /* 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; mbedtls_ssl_ticket_key *key = ctx->keys + index;
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
key->generation_time = (uint32_t) time( NULL ); key->generation_time = (uint32_t) mbedtls_time( NULL );
#endif #endif
if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) 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 #else
if( ctx->ticket_lifetime != 0 ) 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; uint32_t key_time = ctx->keys[ctx->active].generation_time;
if( current_time > key_time && if( current_time > key_time &&
@ -451,7 +451,7 @@ int mbedtls_ssl_ticket_parse( void *p_ticket,
#if defined(MBEDTLS_HAVE_TIME) #if defined(MBEDTLS_HAVE_TIME)
{ {
/* Check for expiration */ /* Check for expiration */
time_t current_time = time( NULL ); mbedtls_time_t current_time = mbedtls_time( NULL );
if( current_time < session->start || if( current_time < session->start ||
(uint32_t)( current_time - session->start ) > ctx->ticket_lifetime ) (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime )

View File

@ -35,25 +35,24 @@
#if defined(MBEDTLS_SSL_TLS_C) #if defined(MBEDTLS_SSL_TLS_C)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
#include "mbedtls/debug.h" #include "mbedtls/debug.h"
#include "mbedtls/ssl.h" #include "mbedtls/ssl.h"
#include "mbedtls/ssl_internal.h" #include "mbedtls/ssl_internal.h"
#include <string.h> #include <string.h>
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ #if defined(MBEDTLS_X509_CRT_PARSE_C)
defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
#include "mbedtls/oid.h" #include "mbedtls/oid.h"
#endif #endif
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#endif
/* Implementation that should never be optimized out by the compiler */ /* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) { static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0; volatile unsigned char *p = v; while( n-- ) *p++ = 0;
@ -862,6 +861,16 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ #endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
if( ssl->conf->f_export_keys != NULL )
{
ssl->conf->f_export_keys( ssl->conf->p_export_keys,
session->master, keyblk,
transform->maclen, transform->keylen,
iv_copy_len );
}
#endif
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
cipher_info ) ) != 0 ) cipher_info ) ) != 0 )
{ {
@ -1095,11 +1104,16 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK ) if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK )
{ {
if( end - p < 2 + (int) psk_len ) if( end - p < 2 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
*(p++) = (unsigned char)( psk_len >> 8 ); *(p++) = (unsigned char)( psk_len >> 8 );
*(p++) = (unsigned char)( psk_len ); *(p++) = (unsigned char)( psk_len );
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
memset( p, 0, psk_len );
p += psk_len; p += psk_len;
} }
else else
@ -1167,11 +1181,15 @@ int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exch
} }
/* opaque psk<0..2^16-1>; */ /* opaque psk<0..2^16-1>; */
if( end - p < 2 + (int) psk_len ) if( end - p < 2 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
*(p++) = (unsigned char)( psk_len >> 8 ); *(p++) = (unsigned char)( psk_len >> 8 );
*(p++) = (unsigned char)( psk_len ); *(p++) = (unsigned char)( psk_len );
if( end < p || (size_t)( end - p ) < psk_len )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
memcpy( p, psk, psk_len ); memcpy( p, psk, psk_len );
p += psk_len; p += psk_len;
@ -1355,17 +1373,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
/* /*
* Generate IV * 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 ) if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 )
{ {
/* Reminder if we ever add an AEAD mode with a different size */ /* Reminder if we ever add an AEAD mode with a different size */
@ -1376,7 +1383,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen,
ssl->out_ctr, 8 ); ssl->out_ctr, 8 );
memcpy( ssl->out_iv, ssl->out_ctr, 8 ); memcpy( ssl->out_iv, ssl->out_ctr, 8 );
#endif
MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv,
ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen );
@ -2689,7 +2695,7 @@ void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl )
*/ */
int mbedtls_ssl_write_record( 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; size_t len = ssl->out_msglen;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) );
@ -2705,7 +2711,9 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
#endif #endif
if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 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 ) ssl->handshake == NULL )
{ {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
@ -2732,7 +2740,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
len += 8; len += 8;
/* Write message_seq and update it, except for HelloRequest */ /* 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[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF;
ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF;
@ -2750,7 +2758,7 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #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 ); ssl->handshake->update_checksum( ssl, ssl->out_msg, len );
} }
@ -3062,7 +3070,7 @@ static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl )
} }
#endif /* MBEDTLS_SSL_PROTO_DTLS */ #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 ) ) if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) )
{ {
@ -3144,6 +3152,12 @@ static int ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); 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 && if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER &&
ssl->handshake != NULL ) ssl->handshake != NULL )
{ {
@ -3158,8 +3172,6 @@ static int ssl_prepare_handshake_record( mbedtls_ssl_context *ssl )
ssl->handshake->in_msg_seq++; ssl->handshake->in_msg_seq++;
} }
#endif #endif
return( 0 );
} }
/* /*
@ -3446,6 +3458,18 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
* uint16 epoch; // DTLS only * uint16 epoch; // DTLS only
* uint48 sequence_number; // DTLS only * uint48 sequence_number; // DTLS only
* uint16 length; * uint16 length;
*
* Return 0 if header looks sane (and, for DTLS, the record is expected)
* MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad,
* MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected.
*
* With DTLS, mbedtls_ssl_read_record() will:
* 1. proceed with the record if this function returns 0
* 2. drop only the current record if this function returns UNEXPECTED_RECORD
* 3. return CLIENT_RECONNECT if this function return that value
* 4. drop the whole datagram if this function returns anything else.
* Point 2 is needed when the peer is resending, and we have already received
* the first record from a datagram but are still waiting for the others.
*/ */
static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
{ {
@ -3481,34 +3505,6 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
/* Drop unexpected ChangeCipherSpec messages */
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
/* Drop unexpected ApplicationData records,
* except at the beginning of renegotiations */
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
#if defined(MBEDTLS_SSL_RENEGOTIATION)
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
ssl->state == MBEDTLS_SSL_SERVER_HELLO )
#endif
)
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
}
#endif
/* Check version */ /* Check version */
if( major_ver != ssl->major_ver ) if( major_ver != ssl->major_ver )
{ {
@ -3522,53 +3518,6 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INVALID_RECORD ); return( MBEDTLS_ERR_SSL_INVALID_RECORD );
} }
/* Check epoch (and sequence number) with DTLS */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
if( rec_epoch != ssl->in_epoch )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
"expected %d, received %d",
ssl->in_epoch, rec_epoch ) );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
/*
* Check for an epoch 0 ClientHello. We can't use in_msg here to
* access the first byte of record content (handshake type), as we
* have an active transform (possibly iv_len != 0), so use the
* fact that the record header len is 13 instead.
*/
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
rec_epoch == 0 &&
ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
ssl->in_left > 13 &&
ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
"from the same port" ) );
return( ssl_handle_possible_reconnect( ssl ) );
}
else
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
/* Replay detection only works for the current epoch */
if( rec_epoch == ssl->in_epoch &&
mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
#endif
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
/* Check length against the size of our buffer */ /* Check length against the size of our buffer */
if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN
- (size_t)( ssl->in_msg - ssl->in_buf ) ) - (size_t)( ssl->in_msg - ssl->in_buf ) )
@ -3618,6 +3567,82 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl )
#endif #endif
} }
/*
* DTLS-related tests done last, because most of them may result in
* silently dropping the record (but not the whole datagram), and we only
* want to consider that after ensuring that the "basic" fields (type,
* version, length) are sane.
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
{
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
/* Drop unexpected ChangeCipherSpec messages */
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC &&
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
}
/* Drop unexpected ApplicationData records,
* except at the beginning of renegotiations */
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA &&
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER
#if defined(MBEDTLS_SSL_RENEGOTIATION)
&& ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS &&
ssl->state == MBEDTLS_SSL_SERVER_HELLO )
#endif
)
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
}
/* Check epoch (and sequence number) with DTLS */
if( rec_epoch != ssl->in_epoch )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: "
"expected %d, received %d",
ssl->in_epoch, rec_epoch ) );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
/*
* Check for an epoch 0 ClientHello. We can't use in_msg here to
* access the first byte of record content (handshake type), as we
* have an active transform (possibly iv_len != 0), so use the
* fact that the record header len is 13 instead.
*/
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER &&
rec_epoch == 0 &&
ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
ssl->in_left > 13 &&
ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect "
"from the same port" ) );
return( ssl_handle_possible_reconnect( ssl ) );
}
else
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
}
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
/* Replay detection only works for the current epoch */
if( rec_epoch == ssl->in_epoch &&
mbedtls_ssl_dtls_replay_check( ssl ) != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD );
}
#endif
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
return( 0 ); return( 0 );
} }
@ -3674,10 +3699,6 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret );
return( 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 */ #endif /* MBEDTLS_ZLIB_SUPPORT */
@ -3696,8 +3717,9 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl );
/* /*
* Read a record. * Read a record.
* *
* For DTLS, silently ignore invalid records (RFC 4.1.2.7.) * Silently ignore non-fatal alert (and for DTLS, invalid records as well,
* and continue reading until a valid record is found. * RFC 6347 4.1.2.7) and continue reading until a valid record is found.
*
*/ */
int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ) int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
{ {
@ -3705,6 +3727,38 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) );
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_handle_message_type" ), ret );
return( ret );
}
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE )
{
mbedtls_ssl_update_handshake_status( ssl );
}
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) );
return( 0 );
}
int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl )
{
int ret;
if( ssl->in_hslen != 0 && ssl->in_hslen < ssl->in_msglen ) if( ssl->in_hslen != 0 && ssl->in_hslen < ssl->in_msglen )
{ {
/* /*
@ -3718,9 +3772,6 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record",
ssl->in_msg, ssl->in_msglen ); ssl->in_msg, ssl->in_msglen );
if( ( ret = ssl_prepare_handshake_record( ssl ) ) != 0 )
return( ret );
return( 0 ); return( 0 );
} }
@ -3732,6 +3783,7 @@ int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_PROTO_DTLS) #if defined(MBEDTLS_SSL_PROTO_DTLS)
read_record_header: read_record_header:
#endif #endif
if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret );
@ -3744,13 +3796,26 @@ read_record_header:
if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
{ {
/* Ignore bad record and get next one; drop the whole datagram if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD )
* since current header cannot be trusted to find the next record {
* in current datagram */ /* Skip unexpected record (but not whole datagram) */
ssl->next_record_offset = 0; ssl->next_record_offset = ssl->in_msglen
ssl->in_left = 0; + mbedtls_ssl_hdr_len( ssl );
MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (header)" ) ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record "
"(header)" ) );
}
else
{
/* Skip invalid record and the rest of the datagram */
ssl->next_record_offset = 0;
ssl->in_left = 0;
MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record "
"(header)" ) );
}
/* Get next record */
goto read_record_header; goto read_record_header;
} }
#endif #endif
@ -3872,13 +3937,22 @@ read_record_header:
} }
#endif #endif
return( 0 );
}
int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl )
{
int ret;
/* /*
* Handle particular types of records * Handle particular types of records
*/ */
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) 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 ); return( ret );
}
} }
if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT )
@ -3887,7 +3961,7 @@ read_record_header:
ssl->in_msg[0], ssl->in_msg[1] ) ); ssl->in_msg[0], ssl->in_msg[1] ) );
/* /*
* Ignore non-fatal alerts, except close_notify * Ignore non-fatal alerts, except close_notify and no_renegotiation
*/ */
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL )
{ {
@ -3902,9 +3976,32 @@ read_record_header:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) );
return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY );
} }
}
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); #if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED)
if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
/* Will be handled when trying to parse ServerHello */
return( 0 );
}
#endif
#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 &&
ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER &&
ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING &&
ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) );
/* Will be handled in mbedtls_ssl_parse_certificate() */
return( 0 );
}
#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */
/* Silently ignore: fetch new message */
return MBEDTLS_ERR_SSL_NON_FATAL;
}
return( 0 ); return( 0 );
} }
@ -3968,7 +4065,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++; ssl->state++;
@ -3987,7 +4085,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++; ssl->state++;
@ -4009,7 +4108,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++; ssl->state++;
@ -4124,7 +4224,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_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_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{ {
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++; ssl->state++;
@ -4276,7 +4377,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
ssl->in_msg + i, n ); ssl->in_msg + i, n );
if( ret != 0 ) if( 0 != ret && ( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND ) != ret )
{ {
MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
return( ret ); return( ret );
@ -4942,7 +5043,12 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); 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; hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12;
#if defined(MBEDTLS_SSL_RENEGOTIATION) #if defined(MBEDTLS_SSL_RENEGOTIATION)
@ -5146,6 +5252,13 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_init( &handshake->ecdh_ctx ); mbedtls_ecdh_init( &handshake->ecdh_ctx );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_init( &handshake->ecjpake_ctx );
#if defined(MBEDTLS_SSL_CLI_C)
handshake->ecjpake_cache = NULL;
handshake->ecjpake_cache_len = 0;
#endif
#endif
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET;
@ -5517,9 +5630,9 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl,
void *p_bio, void *p_bio,
int (*f_send)(void *, const unsigned char *, size_t), mbedtls_ssl_send_t *f_send,
int (*f_recv)(void *, unsigned char *, size_t), mbedtls_ssl_recv_t *f_recv,
int (*f_recv_timeout)(void *, unsigned char *, size_t, uint32_t) ) mbedtls_ssl_recv_timeout_t *f_recv_timeout )
{ {
ssl->p_bio = p_bio; ssl->p_bio = p_bio;
ssl->f_send = f_send; ssl->f_send = f_send;
@ -5534,8 +5647,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 mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl,
void *p_timer, void *p_timer,
void (*f_set_timer)(void *, uint32_t int_ms, uint32_t fin_ms), mbedtls_ssl_set_timer_t *f_set_timer,
int (*f_get_timer)(void *) ) mbedtls_ssl_get_timer_t *f_get_timer )
{ {
ssl->p_timer = p_timer; ssl->p_timer = p_timer;
ssl->f_set_timer = f_set_timer; ssl->f_set_timer = f_set_timer;
@ -5679,6 +5792,32 @@ void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
} }
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
/*
* Set EC J-PAKE password for current handshake
*/
int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl,
const unsigned char *pw,
size_t pw_len )
{
mbedtls_ecjpake_role role;
if( ssl->handshake == NULL || ssl->conf == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
role = MBEDTLS_ECJPAKE_SERVER;
else
role = MBEDTLS_ECJPAKE_CLIENT;
return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx,
role,
MBEDTLS_MD_SHA256,
MBEDTLS_ECP_DP_SECP256R1,
pw, pw_len ) );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
const unsigned char *psk, size_t psk_len, const unsigned char *psk, size_t psk_len,
@ -5701,13 +5840,17 @@ int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf,
{ {
mbedtls_free( conf->psk ); mbedtls_free( conf->psk );
mbedtls_free( conf->psk_identity ); mbedtls_free( conf->psk_identity );
conf->psk = NULL;
conf->psk_identity = NULL;
} }
if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL || if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ||
( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL ) ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL )
{ {
mbedtls_free( conf->psk ); mbedtls_free( conf->psk );
mbedtls_free( conf->psk_identity );
conf->psk = NULL; conf->psk = NULL;
conf->psk_identity = NULL;
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
} }
@ -5730,14 +5873,10 @@ int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl,
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( ssl->handshake->psk != NULL ) if( ssl->handshake->psk != NULL )
mbedtls_free( ssl->conf->psk ); mbedtls_free( ssl->handshake->psk );
if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL )
{
mbedtls_free( ssl->handshake->psk );
ssl->handshake->psk = NULL;
return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
}
ssl->handshake->psk_len = psk_len; ssl->handshake->psk_len = psk_len;
memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len );
@ -5798,7 +5937,7 @@ void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf,
} }
#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ #endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/* /*
* Set allowed/preferred hashes for handshake signatures * Set allowed/preferred hashes for handshake signatures
*/ */
@ -5833,6 +5972,9 @@ int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
if( hostname_len + 1 == 0 ) if( hostname_len + 1 == 0 )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 );
if( ssl->hostname == NULL ) if( ssl->hostname == NULL )
@ -6001,6 +6143,16 @@ void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf,
#endif #endif
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys )
{
conf->f_export_keys = f_export_keys;
conf->p_export_keys = p_export_keys;
}
#endif
/* /*
* SSL get accessors * SSL get accessors
*/ */
@ -6821,8 +6973,17 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake )
#if defined(MBEDTLS_ECDH_C) #if defined(MBEDTLS_ECDH_C)
mbedtls_ecdh_free( &handshake->ecdh_ctx ); mbedtls_ecdh_free( &handshake->ecdh_ctx );
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
mbedtls_ecjpake_free( &handshake->ecjpake_ctx );
#if defined(MBEDTLS_SSL_CLI_C)
mbedtls_free( handshake->ecjpake_cache );
handshake->ecjpake_cache = NULL;
handshake->ecjpake_cache_len = 0;
#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 */ /* explicit void pointer cast for buggy MS compiler */
mbedtls_free( (void *) handshake->curves ); mbedtls_free( (void *) handshake->curves );
#endif #endif
@ -6970,13 +7131,30 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
memset( conf, 0, sizeof( mbedtls_ssl_config ) ); memset( conf, 0, sizeof( mbedtls_ssl_config ) );
} }
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
static int ssl_preset_default_hashes[] = {
#if defined(MBEDTLS_SHA512_C)
MBEDTLS_MD_SHA512,
MBEDTLS_MD_SHA384,
#endif
#if defined(MBEDTLS_SHA256_C)
MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA224,
#endif
#if defined(MBEDTLS_SHA1_C)
MBEDTLS_MD_SHA1,
#endif
MBEDTLS_MD_NONE
};
#endif
static int ssl_preset_suiteb_ciphersuites[] = { static int ssl_preset_suiteb_ciphersuites[] = {
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
0 0
}; };
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
static int ssl_preset_suiteb_hashes[] = { static int ssl_preset_suiteb_hashes[] = {
MBEDTLS_MD_SHA256, MBEDTLS_MD_SHA256,
MBEDTLS_MD_SHA384, MBEDTLS_MD_SHA384,
@ -6993,7 +7171,7 @@ static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = {
#endif #endif
/* /*
* Load default in mbetls_ssl_config * Load default in mbedtls_ssl_config
*/ */
int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
int endpoint, int transport, int preset ) int endpoint, int transport, int preset )
@ -7092,7 +7270,7 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; conf->cert_profile = &mbedtls_x509_crt_profile_suiteb;
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
conf->sig_hashes = ssl_preset_suiteb_hashes; conf->sig_hashes = ssl_preset_suiteb_hashes;
#endif #endif
@ -7125,8 +7303,8 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
conf->cert_profile = &mbedtls_x509_crt_profile_default; conf->cert_profile = &mbedtls_x509_crt_profile_default;
#endif #endif
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
conf->sig_hashes = mbedtls_md_list(); conf->sig_hashes = ssl_preset_default_hashes;
#endif #endif
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
@ -7170,7 +7348,8 @@ void mbedtls_ssl_config_free( mbedtls_ssl_config *conf )
mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) ); mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) );
} }
#if defined(MBEDTLS_PK_C) #if defined(MBEDTLS_PK_C) && \
( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) )
/* /*
* Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX
*/ */
@ -7203,7 +7382,7 @@ mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig )
return( MBEDTLS_PK_NONE ); return( MBEDTLS_PK_NONE );
} }
} }
#endif /* MBEDTLS_PK_C */ #endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */
/* /*
* Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX
@ -7289,7 +7468,7 @@ int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_i
} }
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
/* /*
* Check if a hash proposed by the peer is in our list. * Check if a hash proposed by the peer is in our list.
* Return 0 if we're willing to use it, -1 otherwise. * Return 0 if we're willing to use it, -1 otherwise.
@ -7308,7 +7487,7 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
return( -1 ); return( -1 );
} }
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__SIGNATURE_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */
#if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_X509_CRT_PARSE_C)
int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
@ -7359,6 +7538,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
case MBEDTLS_KEY_EXCHANGE_PSK: case MBEDTLS_KEY_EXCHANGE_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_PSK: case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
usage = 0; usage = 0;
} }
} }
@ -7453,4 +7633,47 @@ 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:
ssl->handshake->calc_verify = ssl_calc_verify_tls;
break;
#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 */ #endif /* MBEDTLS_SSL_TLS_C */

View File

@ -32,7 +32,7 @@
#if defined(MBEDTLS_THREADING_PTHREAD) #if defined(MBEDTLS_THREADING_PTHREAD)
static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex )
{ {
if( mutex == NULL ) if( mutex == NULL || mutex->is_valid )
return; return;
mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
@ -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 ) static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex )
{ {
if( mutex == NULL ) if( mutex == NULL || !mutex->is_valid )
return; return;
(void) pthread_mutex_destroy( &mutex->mutex ); (void) pthread_mutex_destroy( &mutex->mutex );
mutex->is_valid = 0;
} }
static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex )

View File

@ -38,6 +38,11 @@
#if !defined(MBEDTLS_TIMING_ALT) #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 #ifndef asm
#define asm __asm #define asm __asm
#endif #endif

View File

@ -54,6 +54,9 @@ static const char *features[] = {
#if defined(MBEDTLS_PLATFORM_EXIT_ALT) #if defined(MBEDTLS_PLATFORM_EXIT_ALT)
"MBEDTLS_PLATFORM_EXIT_ALT", "MBEDTLS_PLATFORM_EXIT_ALT",
#endif /* 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) #if defined(MBEDTLS_PLATFORM_FPRINTF_ALT)
"MBEDTLS_PLATFORM_FPRINTF_ALT", "MBEDTLS_PLATFORM_FPRINTF_ALT",
#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ #endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */
@ -63,6 +66,9 @@ static const char *features[] = {
#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) #if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT)
"MBEDTLS_PLATFORM_SNPRINTF_ALT", "MBEDTLS_PLATFORM_SNPRINTF_ALT",
#endif /* 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_DEPRECATED_WARNING) #if defined(MBEDTLS_DEPRECATED_WARNING)
"MBEDTLS_DEPRECATED_WARNING", "MBEDTLS_DEPRECATED_WARNING",
#endif /* MBEDTLS_DEPRECATED_WARNING */ #endif /* MBEDTLS_DEPRECATED_WARNING */
@ -153,6 +159,9 @@ static const char *features[] = {
#if defined(MBEDTLS_AES_DECRYPT_ALT) #if defined(MBEDTLS_AES_DECRYPT_ALT)
"MBEDTLS_AES_DECRYPT_ALT", "MBEDTLS_AES_DECRYPT_ALT",
#endif /* MBEDTLS_AES_DECRYPT_ALT */ #endif /* MBEDTLS_AES_DECRYPT_ALT */
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
"MBEDTLS_TEST_NULL_ENTROPY",
#endif /* MBEDTLS_TEST_NULL_ENTROPY */
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
"MBEDTLS_ENTROPY_HARDWARE_ALT", "MBEDTLS_ENTROPY_HARDWARE_ALT",
#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
@ -264,6 +273,9 @@ static const char *features[] = {
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)
"MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED",
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ #endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
"MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED",
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) #if defined(MBEDTLS_PK_PARSE_EC_EXTENDED)
"MBEDTLS_PK_PARSE_EC_EXTENDED", "MBEDTLS_PK_PARSE_EC_EXTENDED",
#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ #endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */
@ -285,6 +297,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ENTROPY_FORCE_SHA256) #if defined(MBEDTLS_ENTROPY_FORCE_SHA256)
"MBEDTLS_ENTROPY_FORCE_SHA256", "MBEDTLS_ENTROPY_FORCE_SHA256",
#endif /* 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) #if defined(MBEDTLS_MEMORY_DEBUG)
"MBEDTLS_MEMORY_DEBUG", "MBEDTLS_MEMORY_DEBUG",
#endif /* MBEDTLS_MEMORY_DEBUG */ #endif /* MBEDTLS_MEMORY_DEBUG */
@ -309,9 +324,6 @@ static const char *features[] = {
#if defined(MBEDTLS_SHA256_SMALLER) #if defined(MBEDTLS_SHA256_SMALLER)
"MBEDTLS_SHA256_SMALLER", "MBEDTLS_SHA256_SMALLER",
#endif /* 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) #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
"MBEDTLS_SSL_ALL_ALERT_MESSAGES", "MBEDTLS_SSL_ALL_ALERT_MESSAGES",
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
@ -378,6 +390,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_SESSION_TICKETS) #if defined(MBEDTLS_SSL_SESSION_TICKETS)
"MBEDTLS_SSL_SESSION_TICKETS", "MBEDTLS_SSL_SESSION_TICKETS",
#endif /* MBEDTLS_SSL_SESSION_TICKETS */ #endif /* MBEDTLS_SSL_SESSION_TICKETS */
#if defined(MBEDTLS_SSL_EXPORT_KEYS)
"MBEDTLS_SSL_EXPORT_KEYS",
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
"MBEDTLS_SSL_SERVER_NAME_INDICATION", "MBEDTLS_SSL_SERVER_NAME_INDICATION",
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
@ -447,6 +462,9 @@ static const char *features[] = {
#if defined(MBEDTLS_CIPHER_C) #if defined(MBEDTLS_CIPHER_C)
"MBEDTLS_CIPHER_C", "MBEDTLS_CIPHER_C",
#endif /* 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) #if defined(MBEDTLS_CTR_DRBG_C)
"MBEDTLS_CTR_DRBG_C", "MBEDTLS_CTR_DRBG_C",
#endif /* MBEDTLS_CTR_DRBG_C */ #endif /* MBEDTLS_CTR_DRBG_C */
@ -465,6 +483,9 @@ static const char *features[] = {
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECDSA_C)
"MBEDTLS_ECDSA_C", "MBEDTLS_ECDSA_C",
#endif /* MBEDTLS_ECDSA_C */ #endif /* MBEDTLS_ECDSA_C */
#if defined(MBEDTLS_ECJPAKE_C)
"MBEDTLS_ECJPAKE_C",
#endif /* MBEDTLS_ECJPAKE_C */
#if defined(MBEDTLS_ECP_C) #if defined(MBEDTLS_ECP_C)
"MBEDTLS_ECP_C", "MBEDTLS_ECP_C",
#endif /* MBEDTLS_ECP_C */ #endif /* MBEDTLS_ECP_C */

View File

@ -53,10 +53,15 @@
#else #else
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define mbedtls_free free #define mbedtls_free free
#define mbedtls_calloc calloc #define mbedtls_calloc calloc
#define mbedtls_printf printf #define mbedtls_printf printf
#define mbedtls_snprintf snprintf #define mbedtls_snprintf snprintf
#endif
#if defined(MBEDTLS_HAVE_TIME)
#include "mbedtls/platform_time.h"
#endif #endif
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
@ -75,6 +80,7 @@
#endif #endif
#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } #define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); }
#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); }
/* /*
* CertificateSerialNumber ::= INTEGER * CertificateSerialNumber ::= INTEGER
@ -484,6 +490,33 @@ static int x509_parse_int(unsigned char **p, unsigned n, int *res){
return 0; return 0;
} }
static int x509_date_is_valid(const mbedtls_x509_time *time)
{
int ret = MBEDTLS_ERR_X509_INVALID_DATE;
CHECK_RANGE( 0, 9999, time->year );
CHECK_RANGE( 0, 23, time->hour );
CHECK_RANGE( 0, 59, time->min );
CHECK_RANGE( 0, 59, time->sec );
switch( time->mon )
{
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
CHECK_RANGE( 1, 31, time->day );
break;
case 4: case 6: case 9: case 11:
CHECK_RANGE( 1, 30, time->day );
break;
case 2:
CHECK_RANGE( 1, 28 + (time->year % 4 == 0), time->day );
break;
default:
return( ret );
}
return( 0 );
}
/* /*
* Time ::= CHOICE { * Time ::= CHOICE {
* utcTime UTCTime, * utcTime UTCTime,
@ -523,6 +556,8 @@ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
time->year += 100 * ( time->year < 50 ); time->year += 100 * ( time->year < 50 );
time->year += 1900; time->year += 1900;
CHECK( x509_date_is_valid( time ) );
return( 0 ); return( 0 );
} }
else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
@ -543,6 +578,8 @@ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
if( len > 14 && *(*p)++ != 'Z' ) if( len > 14 && *(*p)++ != 'Z' )
return( MBEDTLS_ERR_X509_INVALID_DATE ); return( MBEDTLS_ERR_X509_INVALID_DATE );
CHECK( x509_date_is_valid( time ) );
return( 0 ); return( 0 );
} }
else else
@ -554,16 +591,18 @@ int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x
{ {
int ret; int ret;
size_t len; size_t len;
int tag_type;
if( ( end - *p ) < 1 ) if( ( end - *p ) < 1 )
return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
MBEDTLS_ERR_ASN1_OUT_OF_DATA ); MBEDTLS_ERR_ASN1_OUT_OF_DATA );
sig->tag = **p; tag_type = **p;
if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
sig->tag = tag_type;
sig->len = len; sig->len = len;
sig->p = *p; sig->p = *p;
@ -843,7 +882,7 @@ static int x509_get_current_time( mbedtls_x509_time *now )
static int x509_get_current_time( mbedtls_x509_time *now ) static int x509_get_current_time( mbedtls_x509_time *now )
{ {
struct tm *lt; struct tm *lt;
time_t tt; mbedtls_time_t tt;
int ret = 0; int ret = 0;
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
@ -851,7 +890,7 @@ static int x509_get_current_time( mbedtls_x509_time *now )
return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
#endif #endif
tt = time( NULL ); tt = mbedtls_time( NULL );
lt = gmtime( &tt ); lt = gmtime( &tt );
if( lt == NULL ) if( lt == NULL )

View File

@ -259,13 +259,16 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
int ret; int ret;
size_t len = 0; size_t len = 0;
if( *p - start < (int) size + 1 ) if( *p < start || (size_t)( *p - start ) < size )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
len = size; len = size;
(*p) -= len; (*p) -= len;
memcpy( *p, sig, len ); memcpy( *p, sig, len );
if( *p - start < 1 )
return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
*--(*p) = 0; *--(*p) = 0;
len += 1; len += 1;

View File

@ -502,14 +502,15 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s
{ {
mbedtls_pem_init( &pem ); mbedtls_pem_init( &pem );
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated
if( buflen == 0 || buf[buflen - 1] != '\0' ) // string
ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; if( buflen == 0 || buf[buflen - 1] != '\0' )
else ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
ret = mbedtls_pem_read_buffer( &pem, else
"-----BEGIN X509 CRL-----", ret = mbedtls_pem_read_buffer( &pem,
"-----END X509 CRL-----", "-----BEGIN X509 CRL-----",
buf, NULL, 0, &use_len ); "-----END X509 CRL-----",
buf, NULL, 0, &use_len );
if( ret == 0 ) if( ret == 0 )
{ {

View File

@ -186,8 +186,10 @@ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
} }
#endif #endif
#if defined(MBEDTLS_ECDSA_C) #if defined(MBEDTLS_ECP_C)
if( pk_alg == MBEDTLS_PK_ECDSA ) if( pk_alg == MBEDTLS_PK_ECDSA ||
pk_alg == MBEDTLS_PK_ECKEY ||
pk_alg == MBEDTLS_PK_ECKEY_DH )
{ {
mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
@ -514,9 +516,6 @@ static int x509_get_subject_alt_name( unsigned char **p,
/* /*
* X.509 v3 extensions * 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, static int x509_get_crt_ext( unsigned char **p,
const unsigned char *end, const unsigned char *end,
@ -678,14 +677,9 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
if( crt == NULL || buf == NULL ) if( crt == NULL || buf == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
p = mbedtls_calloc( 1, len = buflen ); // Use the original buffer until we figure out actual length
if( p == NULL ) p = (unsigned char*) buf;
return( MBEDTLS_ERR_X509_ALLOC_FAILED ); len = buflen;
memcpy( p, buf, buflen );
crt->raw.p = p;
crt->raw.len = len;
end = p + len; end = p + len;
/* /*
@ -709,6 +703,18 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *
} }
crt_end = p + len; 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 { * TBSCertificate ::= SEQUENCE {
*/ */
@ -964,7 +970,9 @@ 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 ) int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
{ {
int success = 0, first_error = 0, total_failed = 0; int success = 0, first_error = 0, total_failed = 0;
#if defined(MBEDTLS_PEM_PARSE_C)
int buf_format = MBEDTLS_X509_FORMAT_DER; int buf_format = MBEDTLS_X509_FORMAT_DER;
#endif
/* /*
* Check for valid input * Check for valid input
@ -982,10 +990,12 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
{ {
buf_format = MBEDTLS_X509_FORMAT_PEM; buf_format = MBEDTLS_X509_FORMAT_PEM;
} }
#endif
if( buf_format == MBEDTLS_X509_FORMAT_DER ) if( buf_format == MBEDTLS_X509_FORMAT_DER )
return mbedtls_x509_crt_parse_der( chain, buf, buflen ); 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 defined(MBEDTLS_PEM_PARSE_C)
if( buf_format == MBEDTLS_X509_FORMAT_PEM ) if( buf_format == MBEDTLS_X509_FORMAT_PEM )
@ -1058,7 +1068,6 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
success = 1; success = 1;
} }
} }
#endif /* MBEDTLS_PEM_PARSE_C */
if( success ) if( success )
return( total_failed ); return( total_failed );
@ -1066,6 +1075,7 @@ int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, s
return( first_error ); return( first_error );
else else
return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
#endif /* MBEDTLS_PEM_PARSE_C */
} }
#if defined(MBEDTLS_FS_IO) #if defined(MBEDTLS_FS_IO)
@ -1097,7 +1107,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
WCHAR szDir[MAX_PATH]; WCHAR szDir[MAX_PATH];
char filename[MAX_PATH]; char filename[MAX_PATH];
char *p; char *p;
int len = (int) strlen( path ); size_t len = strlen( path );
WIN32_FIND_DATAW file_data; WIN32_FIND_DATAW file_data;
HANDLE hFind; HANDLE hFind;
@ -1131,7 +1141,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
lstrlenW( file_data.cFileName ), lstrlenW( file_data.cFileName ),
p, len - 1, p, (int) len - 1,
NULL, NULL ); NULL, NULL );
if( w_ret == 0 ) if( w_ret == 0 )
return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
@ -1150,9 +1160,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
FindClose( hFind ); FindClose( hFind );
#else /* _WIN32 */ #else /* _WIN32 */
int t_ret; int t_ret;
int snp_ret;
struct stat sb; struct stat sb;
struct dirent *entry; struct dirent *entry;
char entry_name[255]; char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
DIR *dir = opendir( path ); DIR *dir = opendir( path );
if( dir == NULL ) if( dir == NULL )
@ -1168,11 +1179,16 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
while( ( entry = readdir( dir ) ) != NULL ) 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; ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
goto cleanup; goto cleanup;
} }
@ -1188,9 +1204,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
else else
ret += t_ret; ret += t_ret;
} }
closedir( dir );
cleanup: cleanup:
closedir( dir );
#if defined(MBEDTLS_THREADING_PTHREAD) #if defined(MBEDTLS_THREADING_PTHREAD)
if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
@ -1347,6 +1364,14 @@ int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
p = buf; p = buf;
n = size; 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", ret = mbedtls_snprintf( p, n, "%scert. version : %d\n",
prefix, crt->version ); prefix, crt->version );
MBEDTLS_X509_SAFE_SNPRINTF; MBEDTLS_X509_SAFE_SNPRINTF;
@ -1598,7 +1623,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, static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
mbedtls_x509_crl *crl_list, mbedtls_x509_crl *crl_list,
@ -1611,12 +1637,6 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
if( ca == NULL ) if( ca == NULL )
return( flags ); 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 ) while( crl_list != NULL )
{ {
if( crl_list->version == 0 || if( crl_list->version == 0 ||
@ -1875,7 +1895,7 @@ static int x509_crt_verify_top(
mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca, mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl, mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile, const mbedtls_x509_crt_profile *profile,
int path_cnt, uint32_t *flags, int path_cnt, int self_cnt, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy ) void *p_vrfy )
{ {
@ -1931,8 +1951,19 @@ static int x509_crt_verify_top(
check_path_cnt--; check_path_cnt--;
} }
/* Self signed certificates do not count towards the limit */
if( trust_ca->max_pathlen > 0 && if( trust_ca->max_pathlen > 0 &&
trust_ca->max_pathlen < check_path_cnt ) trust_ca->max_pathlen < check_path_cnt - self_cnt )
{
continue;
}
if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
{
continue;
}
if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
{ {
continue; continue;
} }
@ -1972,12 +2003,6 @@ static int x509_crt_verify_top(
((void) ca_crl); ((void) ca_crl);
#endif #endif
if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED;
if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
ca_flags |= MBEDTLS_X509_BADCERT_FUTURE;
if( NULL != f_vrfy ) if( NULL != f_vrfy )
{ {
if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
@ -2004,7 +2029,7 @@ static int x509_crt_verify_child(
mbedtls_x509_crt *child, mbedtls_x509_crt *parent, mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile, const mbedtls_x509_crt_profile *profile,
int path_cnt, uint32_t *flags, int path_cnt, int self_cnt, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy ) void *p_vrfy )
{ {
@ -2014,6 +2039,10 @@ static int x509_crt_verify_child(
mbedtls_x509_crt *grandparent; mbedtls_x509_crt *grandparent;
const mbedtls_md_info_t *md_info; const mbedtls_md_info_t *md_info;
/* Counting intermediate self signed certificates */
if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 )
self_cnt++;
/* path_cnt is 0 for the first intermediate CA */ /* path_cnt is 0 for the first intermediate CA */
if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
{ {
@ -2074,7 +2103,7 @@ static int x509_crt_verify_child(
if( grandparent != NULL ) if( grandparent != NULL )
{ {
ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile, ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
} }
@ -2085,6 +2114,15 @@ static int x509_crt_verify_child(
grandparent != NULL; grandparent != NULL;
grandparent = grandparent->next ) grandparent = grandparent->next )
{ {
/* +2 because the current step is not yet accounted for
* and because max_pathlen is one higher than it should be.
* Also self signed certificates do not count to the limit. */
if( grandparent->max_pathlen > 0 &&
grandparent->max_pathlen < 2 + path_cnt - self_cnt )
{
continue;
}
if( x509_crt_check_parent( parent, grandparent, if( x509_crt_check_parent( parent, grandparent,
0, path_cnt == 0 ) == 0 ) 0, path_cnt == 0 ) == 0 )
break; break;
@ -2094,7 +2132,7 @@ static int x509_crt_verify_child(
if( grandparent != NULL ) if( grandparent != NULL )
{ {
ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
profile, path_cnt + 1, &parent_flags, profile, path_cnt + 1, self_cnt, &parent_flags,
f_vrfy, p_vrfy ); f_vrfy, p_vrfy );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
@ -2102,7 +2140,7 @@ static int x509_crt_verify_child(
else else
{ {
ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile, ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
path_cnt + 1, &parent_flags, path_cnt + 1, self_cnt, &parent_flags,
f_vrfy, p_vrfy ); f_vrfy, p_vrfy );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
@ -2147,10 +2185,11 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
{ {
size_t cn_len; size_t cn_len;
int ret; int ret;
int pathlen = 0; int pathlen = 0, selfsigned = 0;
mbedtls_x509_crt *parent; mbedtls_x509_crt *parent;
mbedtls_x509_name *name; mbedtls_x509_name *name;
mbedtls_x509_sequence *cur = NULL; mbedtls_x509_sequence *cur = NULL;
mbedtls_pk_type_t pk_type;
if( profile == NULL ) if( profile == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
@ -2209,6 +2248,15 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
} }
} }
/* Check the type and size of the key */
pk_type = mbedtls_pk_get_type( &crt->pk );
if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
*flags |= MBEDTLS_X509_BADCERT_BAD_PK;
if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
*flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
/* Look for a parent in trusted CAs */ /* Look for a parent in trusted CAs */
for( parent = trust_ca; parent != NULL; parent = parent->next ) for( parent = trust_ca; parent != NULL; parent = parent->next )
{ {
@ -2219,7 +2267,7 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
if( parent != NULL ) if( parent != NULL )
{ {
ret = x509_crt_verify_top( crt, parent, ca_crl, profile, ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
pathlen, flags, f_vrfy, p_vrfy ); pathlen, selfsigned, flags, f_vrfy, p_vrfy );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
} }
@ -2227,23 +2275,21 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
{ {
/* Look for a parent upwards the chain */ /* Look for a parent upwards the chain */
for( parent = crt->next; parent != NULL; parent = parent->next ) for( parent = crt->next; parent != NULL; parent = parent->next )
{
if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
break; break;
}
/* Are we part of the chain or at the top? */ /* Are we part of the chain or at the top? */
if( parent != NULL ) if( parent != NULL )
{ {
ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile, ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
pathlen, flags, f_vrfy, p_vrfy ); pathlen, selfsigned, flags, f_vrfy, p_vrfy );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
} }
else else
{ {
ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile, ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
pathlen, flags, f_vrfy, p_vrfy ); pathlen, selfsigned, flags, f_vrfy, p_vrfy );
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
} }

View File

@ -104,7 +104,7 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
/* /*
* Check for valid input * Check for valid input
*/ */
if( csr == NULL || buf == NULL ) if( csr == NULL || buf == NULL || buflen == 0 )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
mbedtls_x509_csr_init( csr ); mbedtls_x509_csr_init( csr );
@ -207,6 +207,13 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
/* /*
* attributes [0] Attributes * 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, if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) 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 ); mbedtls_x509_csr_free( csr );
return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
} }
// TODO Parse Attributes / extension requests
p += len; p += len;
@ -268,14 +274,14 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz
/* /*
* Check for valid input * Check for valid input
*/ */
if( csr == NULL || buf == NULL ) if( csr == NULL || buf == NULL || buflen == 0 )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
#if defined(MBEDTLS_PEM_PARSE_C) #if defined(MBEDTLS_PEM_PARSE_C)
mbedtls_pem_init( &pem ); mbedtls_pem_init( &pem );
/* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ /* 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; ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
else else
ret = mbedtls_pem_read_buffer( &pem, ret = mbedtls_pem_read_buffer( &pem,

Some files were not shown because too many files have changed in this diff Show More