aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/baremetal.h20
-rw-r--r--include/mbedtls/aes.h6
-rw-r--r--include/mbedtls/check_config.h31
-rw-r--r--include/mbedtls/config.h143
-rw-r--r--include/mbedtls/platform_util.h16
-rw-r--r--include/mbedtls/ssl.h377
-rw-r--r--include/mbedtls/ssl_internal.h106
-rw-r--r--include/tinycrypt/ecc.h6
-rw-r--r--include/tinycrypt/ecc_dsa.h2
-rw-r--r--library/aes.c439
-rw-r--r--library/ccm.c187
-rw-r--r--library/cipher.c12
-rw-r--r--library/ecp.c8
-rw-r--r--library/platform_util.c131
-rw-r--r--library/sha256.c13
-rw-r--r--library/ssl_cli.c95
-rw-r--r--library/ssl_srv.c51
-rw-r--r--library/ssl_tls.c942
-rw-r--r--library/version_features.c33
-rw-r--r--library/x509_crt.c2
-rw-r--r--programs/ssl/query_config.c96
-rw-r--r--programs/ssl/ssl_client2.c6
-rw-r--r--programs/ssl/ssl_server2.c205
-rwxr-xr-xscripts/baremetal.sh8
-rwxr-xr-xscripts/config.pl18
-rwxr-xr-xtests/scripts/all.sh90
-rwxr-xr-xtests/ssl-opt.sh402
-rw-r--r--tests/suites/test_suite_ssl.function38
-rw-r--r--tests/suites/test_suite_tinycrypt.data165
-rw-r--r--tests/suites/test_suite_tinycrypt.function63
-rw-r--r--tinycrypt/ecc.c723
-rw-r--r--tinycrypt/ecc_dh.c2
-rw-r--r--tinycrypt/ecc_dsa.c2
33 files changed, 3730 insertions, 708 deletions
diff --git a/configs/baremetal.h b/configs/baremetal.h
index 465664279..a0fb744e6 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -42,6 +42,7 @@
#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
#define MBEDTLS_AES_ONLY_ENCRYPT
#define MBEDTLS_AES_SCA_COUNTERMEASURES
+#define MBEDTLS_AES_128_BIT_MASKED
#define MBEDTLS_CCM_C
/* Asymmetric crypto: Single-curve ECC only. */
@@ -86,8 +87,10 @@
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
#define MBEDTLS_SSL_DTLS_CONNECTION_ID
+#define MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
/* Compile-time fixed parts of the SSL configuration */
+#define MBEDTLS_SSL_CONF_TRANSPORT MBEDTLS_SSL_TRANSPORT_DATAGRAM
#define MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED
#define MBEDTLS_SSL_CONF_READ_TIMEOUT 0
#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN 1000
@@ -114,8 +117,14 @@
#define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET \
MBEDTLS_SSL_EXTENDED_MS_ENFORCE_ENABLED
-#define MBEDTLS_USE_TINYCRYPT
+#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+#define MBEDTLS_USE_TINYCRYPT
+#define MBEDTLS_HAVE_ASM
+#if !( defined(__STRICT_ANSI__) && defined(__CC_ARM) )
+ #define MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+#endif
/* X.509 CRT parsing */
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
@@ -137,6 +146,7 @@
#define MBEDTLS_OID_C
#define MBEDTLS_PLATFORM_C
+#define MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
#define MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY
/* I/O buffer configuration */
@@ -149,6 +159,14 @@
/* Fault Injection Countermeasures */
#define MBEDTLS_FI_COUNTERMEASURES
+#define MBEDTLS_CCM_SHUFFLING_MASKING
+
+/* Further optimizations */
+#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
+#define MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION
+#define MBEDTLS_SSL_FREE_SERVER_CERTIFICATE
+#define MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
+#define MBEDTLS_SSL_EARLY_KEY_COMPUTATION
#if defined(MBEDTLS_USER_CONFIG_FILE)
#include MBEDTLS_USER_CONFIG_FILE
diff --git a/include/mbedtls/aes.h b/include/mbedtls/aes.h
index b410b5ad4..0a02642ee 100644
--- a/include/mbedtls/aes.h
+++ b/include/mbedtls/aes.h
@@ -83,6 +83,10 @@ extern "C" {
/**
* \brief The AES context-type definition.
*/
+
+#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
+#define MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS 44
+#endif
typedef struct mbedtls_aes_context
{
int nr; /*!< The number of rounds. */
@@ -94,7 +98,7 @@ typedef struct mbedtls_aes_context
uint32_t hash; /*!< hash of the set key */
#endif
#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) && !defined(MBEDTLS_PADLOCK_C)
- uint32_t buf[44]; /*!< Unaligned data buffer */
+ uint32_t buf[MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS]; /*!< Unaligned data buffer for expanded key only */
#else /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
uint32_t buf[68]; /*!< Unaligned data buffer. This buffer can
hold 32 extra Bytes, which can be used for
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 7239557a0..4c92954e9 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -78,6 +78,12 @@
#error "MBEDTLS_CTR_DRBG_C and MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH defined, but MBEDTLS_CTR_DRBG_USE_128_BIT_KEY is not defined"
#endif
+#if defined(MBEDTLS_AES_128_BIT_MASKED) && ( !defined(MBEDTLS_AES_SCA_COUNTERMEASURES) || \
+ !defined(MBEDTLS_AES_ONLY_ENCRYPT) || \
+ !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH) )
+#error "MBEDTLS_AES_128_BIT_MASKED defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_DHM_C) && !defined(MBEDTLS_BIGNUM_C)
#error "MBEDTLS_DHM_C defined, but not all prerequisites"
#endif
@@ -130,6 +136,12 @@
#error "MBEDTLS_USE_TINYCRYPT defined, but not all prerequesites"
#endif
+#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM) && \
+ ( !defined(MBEDTLS_HAVE_ASM) || \
+ !defined(MBEDTLS_USE_TINYCRYPT) )
+#error "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM defined, but not all prerequesites"
+#endif
+
#if defined(MBEDTLS_NIST_KW_C) && \
( !defined(MBEDTLS_AES_C) || !defined(MBEDTLS_CIPHER_C) )
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
@@ -672,6 +684,16 @@
#error "MBEDTLS_SSL_TLS_C defined, but neither TLS or DTLS is active"
#endif
+#if defined(MBEDTLS_SSL_TLS_C) && defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \
+ defined(MBEDTLS_ARC4_C)
+#error "MBEDTLS_ARC4_C cannot be defined with MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS on"
+#endif
+
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY) && !defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS) && \
+ defined(MBEDTLS_ARC4_C)
+#error "MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY requires MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS to be defined."
+#endif
+
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
defined(MBEDTLS_SSL_PROTO_TLS1_1) && !defined(MBEDTLS_SSL_PROTO_TLS1))
#error "Illegal protocol selection"
@@ -888,6 +910,15 @@
#undef MBEDTLS_HASHES_ENABLED
#endif /* MBEDTLS_MD_SINGLE_HASH */
+#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION) && !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+#error "MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION can only be used with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
+#endif
+
+
+#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) && !defined(MBEDTLS_USE_TINYCRYPT)
+#error "MBEDTLS_SSL_EARLY_KEY_COMPUTATION can only be used with MBEDTLS_USE_TINYCRYPT"
+#endif
+
/*
* Note: the dependency on TinyCrypt is reflected in several ways in the code:
*
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index c4d98e42f..b2e732942 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -41,6 +41,15 @@
*/
/**
+ * \def MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION
+ *
+ * Enable the delayed verification of server
+ * certificates on the client side.
+ *
+ */
+//#define MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION
+
+/**
* \def MBEDTLS_HAVE_ASM
*
* The compiler has support for asm().
@@ -655,6 +664,29 @@
//#define MBEDTLS_AES_SCA_COUNTERMEASURES
/**
+ * \def MBEDTLS_AES_128_BIT_MASKED
+ *
+ * Requires MBEDTLS_AES_SCA_COUNTERMEASURES
+ * MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
+ * MBEDTLS_AES_ONLY_ENCRYPT
+ *
+ * Add boolean masking against possible combined side-channel-attack
+ * fault injection attacks.
+ *
+ * Uncommenting this macro adds data, key and Sbox masking additionally
+ * to dummy rounds.
+ *
+ * Tradeoff:
+ * Uncommenting this macro does not increase codesize in MBEDTLS_AES_ROM_TABLES
+ * configuration.
+ * Uncommenting this macro increases codesize in AES RAM tables configuration
+ * by ~600 bytes.
+ * The performance loss is ~50% with 128 bit AES encrypt.
+ *
+ */
+//#define MBEDTLS_AES_128_BIT_MASKED
+
+/**
* \def MBEDTLS_FI_COUNTERMEASURES
*
* Add countermeasures against a possible FI attack.
@@ -665,6 +697,15 @@
//#define MBEDTLS_FI_COUNTERMEASURES
/**
+ * \def MBEDTLS_CCM_SHUFFLING_MASKING
+ *
+ * Add shuffling and masking to the CCM module as an additional security
+ * measure.
+ *
+ */
+//#define MBEDTLS_CCM_SHUFFLING_MASKING
+
+/**
* \def MBEDTLS_CAMELLIA_SMALL_MEMORY
*
* Use less ROM for the Camellia implementation (saves about 768 bytes).
@@ -1561,6 +1602,39 @@
#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
/**
+ * \def MBEDTLS_SSL_FREE_SERVER_CERTIFICATE
+ *
+ * This option controls determines whether the server certificate is discarded
+ * after a handshake when the MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is enabled.
+ *
+ * Use of this option is useful in combined with the delayed certificate verification
+ * when the server certificate has to be kept for the duration of the handshake
+ * but not afterwards.
+ *
+ */
+//#define MBEDTLS_SSL_FREE_SERVER_CERTIFICATE
+
+
+/**
+ * \def MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
+ *
+ * Force stack to immediately transmit messages.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+//#define MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
+
+/**
+ * \def MBEDTLS_SSL_EARLY_KEY_COMPUTATION
+ *
+ * Create ephemeral Diffie-Hellman key pair after
+ * the ClientHello has been successfully transmitted.
+ *
+ * Requires:
+ */
+//#define MBEDTLS_SSL_EARLY_KEY_COMPUTATION
+
+/**
* \def MBEDTLS_SSL_HW_RECORD_ACCEL
*
* Enable hooking functions in SSL module for hardware acceleration of
@@ -1910,6 +1984,17 @@
//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
/**
+ * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ *
+ * Enable modifying the maximum I/O buffer size in runtime.
+ *
+ * If the library runs out of memory during the resizing of an I/O buffer,
+ * there is no error returned. The operation continues as usual on an
+ * unchanged buffer without any negative impact on the flow.
+ */
+//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+
+/**
* \def MBEDTLS_THREADING_ALT
*
* Provide your own alternate threading implementation.
@@ -2703,6 +2788,21 @@
//#define MBEDTLS_USE_TINYCRYPT
/**
+ * \def MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+ *
+ * Optimize TinyCrypt operations using assembly.
+ * Add T32/A32 assembly for core tinycrypt/microecc routines, for ARMC5 and GCC;
+ * Use fast integer types to avoid frequent narrowing instructions;
+ * Use __builtin_clz and avoid boolean ops.
+ *
+ * Requires: MBEDTLS_USE_TINYCRYPT
+ * MBEDTLS_HAVE_ASM
+ *
+ * Module: tinycrypt/ecc.c
+ */
+//#define MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+
+/**
* \def MBEDTLS_ENTROPY_C
*
* Enable the platform-specific entropy code.
@@ -2740,6 +2840,18 @@
//#define MBEDTLS_CRC_C
/**
+ * \def MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+ *
+ * Enable validation of ssl keys by checking their hash
+ * during every encryption/decryption.
+ *
+ * Module: library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+ */
+//#define MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+
+/**
* \def MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY
*
* Enable validation of AES keys by checking their hash
@@ -2914,6 +3026,20 @@
//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
/**
+ * \def MBEDTLS_PLATFORM_FAULT_CALLBACKS
+ *
+ * Uncomment to provide your own alternate implementation for
+ * mbedtls_platform_fault(), used in library/platform_util.c and
+ * tinycrypt/ecc.c to signal a fault injection in either
+ * mbedtls_platform_memcpy, mbedtls_platform_memset, mbedtls_platform_random_buf,
+ * or uECC_vli_mmod.
+ *
+ * You will need to provide a header "platform_fault.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_PLATFORM_FAULT_CALLBACKS
+
+/**
* \def MBEDTLS_NET_C
*
* Enable the TCP and UDP over IPv6/IPv4 networking routines.
@@ -3285,6 +3411,20 @@
#define MBEDTLS_SSL_TLS_C
/**
+ * \def MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+ * Use one cipher context for both decryption and encryption in ssl transforms.
+ *
+ * This change saves some RAM, but makes the operations last longer:
+ * before every encryption and decryption a key is set on the context.
+ *
+ * This change will not work with MBEDTLS_ARC4_C, since it requires an
+ * additional table and offsets to be saved between cipher calls, and this
+ * contradicts key resetting before each use.
+ *
+ */
+//#define MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+
+/**
* \def MBEDTLS_THREADING_C
*
* Enable the threading abstraction layer.
@@ -3808,6 +3948,9 @@
/* Endpoint (Client/Server) */
//#define MBEDTLS_SSL_CONF_ENDPOINT MBEDTLS_SSL_IS_CLIENT
+/* Transport (Stream/Datagram) */
+//#define MBEDTLS_SSL_CONF_TRANSPORT MBEDTLS_SSL_TRANSPORT_STREAM
+
//#define MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED
/* DTLS-specific settings */
diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h
index b44be2317..4999500ce 100644
--- a/include/mbedtls/platform_util.h
+++ b/include/mbedtls/platform_util.h
@@ -276,9 +276,9 @@ uint32_t mbedtls_platform_random_uint32( void );
* cryptographically secure RNG, but provide an RNG for utility
* functions.
*
- * \note If the given range is [0, 0), 0 is returned.
- *
* \param num Max-value for the generated random number, exclusive.
+ * Must be greater than zero, otherwise an undefined behavior
+ * will occur on "num % 0".
* The generated number will be on range [0, num).
*
* \return The generated random number.
@@ -340,6 +340,18 @@ struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
struct tm *tm_buf );
#endif /* MBEDTLS_HAVE_TIME_DATE */
+#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) || defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+/**
+ * \brief Calculate a hash from the given data.
+ *
+ * \param data Data from which the hash is calculated.
+ * \param data_len_bytes Length of the data in bytes.
+ *
+ * \return A hash calculated from the provided data.
+ */
+uint32_t mbedtls_hash( const void *data, size_t data_len_bytes );
+#endif
+
/**
* \brief Convert a 32-bit number to the big endian format and write it to
* the given buffer.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index ee231a599..c0a4a5504 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -971,8 +971,6 @@ struct mbedtls_ssl_session
int compression; /*!< chosen compression */
#endif /* MBEDTLS_ZLIB_SUPPORT */
size_t id_len; /*!< session id length */
- unsigned char id[32]; /*!< session identifier */
- unsigned char master[48]; /*!< the master secret */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
@@ -1004,6 +1002,9 @@ struct mbedtls_ssl_session
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
int encrypt_then_mac; /*!< flag for EtM activation */
#endif
+
+ unsigned char id[32]; /*!< session identifier */
+ unsigned char master[48]; /*!< the master secret */
};
/**
@@ -1011,7 +1012,124 @@ struct mbedtls_ssl_session
*/
struct mbedtls_ssl_config
{
- /* Group items by size (largest first) to minimize padding overhead */
+ /* Group items by size (smallest first) to minimize padding overhead */
+
+ /*
+ * Flags (bytes)
+ */
+
+#if !defined(MBEDTLS_SSL_CONF_ENDPOINT)
+ uint8_t endpoint; /*!< 0: client, 1: server */
+#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */
+#if !defined(MBEDTLS_SSL_CONF_TRANSPORT)
+ uint8_t transport; /*!< stream (TLS) or datagram (DTLS) */
+#endif /* !MBEDTLS_SSL_CONF_TRANSPORT */
+#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
+ uint8_t authmode; /*!< MBEDTLS_SSL_VERIFY_XXX */
+#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
+#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION)
+ /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */
+ uint8_t allow_legacy_renegotiation; /*!< MBEDTLS_LEGACY_XXX */
+#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */
+#if defined(MBEDTLS_ARC4_C)
+ uint8_t arc4_disabled; /*!< blacklist RC4 ciphersuites? */
+#endif
+#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
+ uint8_t mfl_code; /*!< desired fragment length */
+#endif
+#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
+ uint8_t encrypt_then_mac; /*!< negotiate encrypt-then-mac? */
+#endif
+#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
+#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
+ uint8_t extended_ms; /*!< negotiate extended master secret? */
+#endif /* !MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
+#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
+ uint8_t enforce_extended_master_secret; /*!< enforce the usage of
+ * extended master secret */
+#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
+#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY)
+ uint8_t anti_replay; /*!< detect and prevent replay? */
+#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */
+#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
+#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
+ uint8_t cbc_record_splitting; /*!< do cbc record splitting */
+#endif
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ uint8_t disable_renegotiation; /*!< disable renegotiation? */
+#endif
+#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
+ uint8_t trunc_hmac; /*!< negotiate truncated hmac? */
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ uint8_t session_tickets; /*!< use session tickets? */
+#endif
+#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
+ uint8_t fallback; /*!< is this a fallback? */
+#endif
+#if defined(MBEDTLS_SSL_SRV_C)
+#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST)
+ uint8_t cert_req_ca_list; /*!< enable sending CA list in
+ Certificate Request messages? */
+#endif /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */
+#endif
+#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#if !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID)
+ uint8_t ignore_unexpected_cid; /*!< Determines whether DTLS record
+ * with unexpected CID should
+ * lead to failure. */
+#endif /* !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */
+#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+
+ /*
+ * Numerical settings
+ */
+
+#if !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER)
+ unsigned char min_major_ver; /*!< min. major version used */
+#endif /* !MBEDTLS_SSL_CONF_MIN_MAJOR_VER */
+#if !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER)
+ unsigned char max_major_ver; /*!< max. major version used */
+#endif /* !MBEDTLS_SSL_CONF_MAX_MAJOR_VER */
+#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER)
+ uint16_t min_minor_ver; /*!< min. minor version used */
+#endif /* !MBEDTLS_SSL_CONF_MIN_MINOR_VER */
+#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER)
+ uint16_t max_minor_ver; /*!< max. minor version used */
+#endif /* !MBEDTLS_SSL_CONF_MAX_MINOR_VER */
+
+#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT)
+ uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */
+#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN)
+ uint32_t hs_timeout_min; /*!< initial value of the handshake
+ retransmission timeout (ms) */
+#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */
+#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX)
+ uint32_t hs_timeout_max; /*!< maximum value of the handshake
+ retransmission timeout (ms) */
+#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+ int renego_max_records; /*!< grace period for renegotiation */
+ unsigned char renego_period[8]; /*!< value of the record counters
+ that triggers renegotiation */
+#endif
+
+#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
+#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT)
+ unsigned int badmac_limit; /*!< limit of records with a bad MAC */
+#endif /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */
+#endif
+
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
+ unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */
+#endif
/*
* Pointers
@@ -1145,121 +1263,6 @@ struct mbedtls_ssl_config
const char **alpn_list; /*!< ordered list of protocols */
#endif
- /*
- * Numerical settings (int then char)
- */
-
-#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT)
- uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */
-#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */
-
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
-#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN)
- uint32_t hs_timeout_min; /*!< initial value of the handshake
- retransmission timeout (ms) */
-#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */
-#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX)
- uint32_t hs_timeout_max; /*!< maximum value of the handshake
- retransmission timeout (ms) */
-#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
-
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- int renego_max_records; /*!< grace period for renegotiation */
- unsigned char renego_period[8]; /*!< value of the record counters
- that triggers renegotiation */
-#endif
-
-#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT)
-#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT)
- unsigned int badmac_limit; /*!< limit of records with a bad MAC */
-#endif /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */
-#endif
-
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
- unsigned int dhm_min_bitlen; /*!< min. bit length of the DHM prime */
-#endif
-
-#if !defined(MBEDTLS_SSL_CONF_MIN_MAJOR_VER)
- unsigned char min_major_ver; /*!< min. major version used */
-#endif /* !MBEDTLS_SSL_CONF_MIN_MAJOR_VER */
-#if !defined(MBEDTLS_SSL_CONF_MAX_MAJOR_VER)
- unsigned char max_major_ver; /*!< max. major version used */
-#endif /* !MBEDTLS_SSL_CONF_MAX_MAJOR_VER */
-#if !defined(MBEDTLS_SSL_CONF_MIN_MINOR_VER)
- uint16_t min_minor_ver; /*!< min. minor version used */
-#endif /* !MBEDTLS_SSL_CONF_MIN_MINOR_VER */
-#if !defined(MBEDTLS_SSL_CONF_MAX_MINOR_VER)
- uint16_t max_minor_ver; /*!< max. minor version used */
-#endif /* !MBEDTLS_SSL_CONF_MAX_MINOR_VER */
-
- /*
- * Flags (bitfields)
- */
-
-#if !defined(MBEDTLS_SSL_CONF_ENDPOINT)
- unsigned int endpoint : 1; /*!< 0: client, 1: server */
-#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */
- unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */
-#if !defined(MBEDTLS_SSL_CONF_AUTHMODE)
- unsigned int authmode : 6; /*!< MBEDTLS_SSL_VERIFY_XXX */
-#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */
-#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION)
- /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */
- unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */
-#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */
-#if defined(MBEDTLS_ARC4_C)
- unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */
-#endif
-#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- unsigned int mfl_code : 3; /*!< desired fragment length */
-#endif
-#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
- unsigned int encrypt_then_mac : 1 ; /*!< negotiate encrypt-then-mac? */
-#endif
-#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
-#if !defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET)
- unsigned int extended_ms : 1; /*!< negotiate extended master secret? */
-#endif /* !MBEDTLS_SSL_EXTENDED_MASTER_SECRET */
-#if !defined(MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET)
- unsigned int enforce_extended_master_secret : 1; /*!< enforce the usage
- * of extended master
- * secret */
-#endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */
-#endif
-#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
-#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY)
- unsigned int anti_replay : 1; /*!< detect and prevent replay? */
-#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */
-#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */
-#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */
-#endif
-#if defined(MBEDTLS_SSL_RENEGOTIATION)
- unsigned int disable_renegotiation : 1; /*!< disable renegotiation? */
-#endif
-#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
- unsigned int trunc_hmac : 1; /*!< negotiate truncated hmac? */
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- unsigned int session_tickets : 1; /*!< use session tickets? */
-#endif
-#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C)
- unsigned int fallback : 1; /*!< is this a fallback? */
-#endif
-#if defined(MBEDTLS_SSL_SRV_C)
-#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST)
- unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in
- Certificate Request messages? */
-#endif /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */
-#endif
-#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
-#if !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID)
- unsigned int ignore_unexpected_cid : 1; /*!< Determines whether DTLS
- * record with unexpected CID
- * should lead to failure. */
-#endif /* !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */
-#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
};
struct mbedtls_ssl_context
@@ -1307,19 +1310,6 @@ struct mbedtls_ssl_context
unsigned badmac_seen; /*!< records with a bad MAC received */
#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */
-#if !defined(MBEDTLS_SSL_CONF_SEND)
- mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
-#endif /* !MBEDTLS_SSL_CONF_SEND */
-#if !defined(MBEDTLS_SSL_CONF_RECV)
- mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
-#endif /* !MBEDTLS_SSL_CONF_RECV */
-#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
- mbedtls_ssl_recv_timeout_t *f_recv_timeout;
-#endif /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */
- /*!< Callback for network receive with timeout */
-
- void *p_bio; /*!< context for I/O operations */
-
/*
* Session layer
*/
@@ -1332,26 +1322,6 @@ struct mbedtls_ssl_context
the handshake process */
/*
- * Record layer transformations
- */
- mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */
- mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */
- mbedtls_ssl_transform *transform; /*!< negotiated transform params */
- mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */
-
- /*
- * Timers
- */
- void *p_timer; /*!< context for the timer callbacks */
-
-#if !defined(MBEDTLS_SSL_CONF_SET_TIMER)
- mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */
-#endif /* !MBEDTLS_SSL_CONF_SET_TIMER */
-#if !defined(MBEDTLS_SSL_CONF_GET_TIMER)
- mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */
-#endif /* !MBEDTLS_SSL_CONF_GET_TIMER */
-
- /*
* Record layer (incoming data)
*/
unsigned char *in_buf; /*!< input buffer */
@@ -1370,6 +1340,10 @@ struct mbedtls_ssl_context
int in_msgtype; /*!< record header: message type */
size_t in_msglen; /*!< record header: message length */
size_t in_left; /*!< amount of data read so far */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len; /*!< length of input buffer */
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
size_t next_record_offset; /*!< offset of the next record in datagram
(equal to in_left if none) */
@@ -1399,6 +1373,9 @@ struct mbedtls_ssl_context
int out_msgtype; /*!< record header: message type */
size_t out_msglen; /*!< record header: message length */
size_t out_left; /*!< amount of data not yet written */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len; /*!< length of output buffer */
+#endif
#if defined(MBEDTLS_ZLIB_SUPPORT)
unsigned char *compress_buf; /*!< zlib data buffer */
@@ -1408,6 +1385,39 @@ struct mbedtls_ssl_context
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
/*
+ * Record layer transformations
+ */
+ mbedtls_ssl_transform *transform_in; /*!< current transform params (in) */
+ mbedtls_ssl_transform *transform_out; /*!< current transform params (in) */
+ mbedtls_ssl_transform *transform; /*!< negotiated transform params */
+ mbedtls_ssl_transform *transform_negotiate; /*!< transform params in negotiation */
+
+#if !defined(MBEDTLS_SSL_CONF_SEND)
+ mbedtls_ssl_send_t *f_send; /*!< Callback for network send */
+#endif /* !MBEDTLS_SSL_CONF_SEND */
+#if !defined(MBEDTLS_SSL_CONF_RECV)
+ mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */
+#endif /* !MBEDTLS_SSL_CONF_RECV */
+#if !defined(MBEDTLS_SSL_CONF_RECV_TIMEOUT)
+ mbedtls_ssl_recv_timeout_t *f_recv_timeout;
+#endif /* !MBEDTLS_SSL_CONF_RECV_TIMEOUT */
+ /*!< Callback for network receive with timeout */
+
+ void *p_bio; /*!< context for I/O operations */
+
+ /*
+ * Timers
+ */
+ void *p_timer; /*!< context for the timer callbacks */
+
+#if !defined(MBEDTLS_SSL_CONF_SET_TIMER)
+ mbedtls_ssl_set_timer_t *f_set_timer; /*!< set timer callback */
+#endif /* !MBEDTLS_SSL_CONF_SET_TIMER */
+#if !defined(MBEDTLS_SSL_CONF_GET_TIMER)
+ mbedtls_ssl_get_timer_t *f_get_timer; /*!< get timer callback */
+#endif /* !MBEDTLS_SSL_CONF_GET_TIMER */
+
+ /*
* PKI layer
*/
int client_auth; /*!< flag for client auth. */
@@ -1562,6 +1572,7 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl );
void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint );
#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */
+#if !defined(MBEDTLS_SSL_CONF_TRANSPORT)
/**
* \brief Set the transport type (TLS or DTLS).
* Default: TLS unless #MBEDTLS_SSL_PROTO_NO_TLS is defined,
@@ -1572,12 +1583,16 @@ void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint );
* \c mbedtls_ssl_set_bio(). You also need to provide timer
* callbacks with \c mbedtls_ssl_set_timer_cb().
*
+ * \note On constrained systems, this can also be configured
+ * at compile-time via MBEDTLS_SSL_CONF_TRANSPORT.
+ *
* \param conf SSL configuration
* \param transport transport type:
* MBEDTLS_SSL_TRANSPORT_STREAM for TLS,
* MBEDTLS_SSL_TRANSPORT_DATAGRAM for DTLS.
*/
void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport );
+#endif /* !MBEDTLS_SSL_CONF_TRANSPORT */
/**
* \brief Set the certificate verification mode
@@ -3597,18 +3612,61 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
/**
- * \brief Return the maximum fragment length (payload, in bytes).
- * This is the value negotiated with peer if any,
- * or the locally configured value.
+ * \brief Return the maximum fragment length (payload, in bytes) for
+ * the output buffer. For the client, this is the configured
+ * value. For the server, it is the minimum of two - the
+ * configured value and the negotiated one.
*
* \sa mbedtls_ssl_conf_max_frag_len()
* \sa mbedtls_ssl_get_max_record_payload()
*
* \param ssl SSL context
*
- * \return Current maximum fragment length.
+ * \return Current maximum fragment length for the output buffer.
*/
-size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
+size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl );
+
+/**
+ * \brief Return the maximum fragment length (payload, in bytes) for
+ * the input buffer. This is the negotiated maximum fragment
+ * length, or, if there is none, MBEDTLS_SSL_MAX_CONTENT_LEN.
+ * If it is not defined either, the value is 2^14. This function
+ * works as its predecessor, \c mbedtls_ssl_get_max_frag_len().
+ *
+ * \sa mbedtls_ssl_conf_max_frag_len()
+ * \sa mbedtls_ssl_get_max_record_payload()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum fragment length for the output buffer.
+ */
+size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl );
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+
+#if defined(MBEDTLS_DEPRECATED_WARNING)
+#define MBEDTLS_DEPRECATED __attribute__((deprecated))
+#else
+#define MBEDTLS_DEPRECATED
+#endif
+
+/**
+ * \brief This function is a deprecated approach to getting the max
+ * fragment length. Its an alias for
+ * \c mbedtls_ssl_get_output_max_frag_len(), as the behaviour
+ * is the same. See \c mbedtls_ssl_get_output_max_frag_len() for
+ * more detail.
+ *
+ * \sa mbedtls_ssl_get_input_max_frag_len()
+ * \sa mbedtls_ssl_get_output_max_frag_len()
+ *
+ * \param ssl SSL context
+ *
+ * \return Current maximum fragment length for the output buffer.
+ */
+MBEDTLS_DEPRECATED size_t mbedtls_ssl_get_max_frag_len(
+ const mbedtls_ssl_context *ssl );
+#endif /* MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
/**
@@ -3629,7 +3687,8 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl );
* when record compression is enabled.
*
* \sa mbedtls_ssl_set_mtu()
- * \sa mbedtls_ssl_get_max_frag_len()
+ * \sa mbedtls_ssl_get_output_max_frag_len()
+ * \sa mbedtls_ssl_get_input_max_frag_len()
* \sa mbedtls_ssl_get_record_expansion()
*
* \param ssl SSL context
@@ -3930,8 +3989,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
* or negotiated with the peer), then:
* - with TLS, less bytes than requested are written.
* - with DTLS, MBEDTLS_ERR_SSL_BAD_INPUT_DATA is returned.
- * \c mbedtls_ssl_get_max_frag_len() may be used to query the
- * active maximum fragment length.
+ * \c mbedtls_ssl_get_output_max_frag_len() may be used to
+ * query the active maximum fragment length.
*
* \note Attempting to write 0 bytes will result in an empty TLS
* application record being sent.
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 19328d88f..441109dd4 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -260,7 +260,7 @@
implicit sequence number. */
#define MBEDTLS_SSL_HEADER_LEN 13
-#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#define MBEDTLS_SSL_IN_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) )
#else
@@ -269,7 +269,7 @@
+ ( MBEDTLS_SSL_CID_IN_LEN_MAX ) )
#endif
-#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
+#if !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
#define MBEDTLS_SSL_OUT_BUFFER_LEN \
( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) )
#else
@@ -278,6 +278,32 @@
+ ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) )
#endif
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+static inline uint32_t mbedtls_ssl_get_output_buflen( const mbedtls_ssl_context *ctx )
+{
+#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ + MBEDTLS_SSL_CID_OUT_LEN_MAX;
+#else
+ return (uint32_t) mbedtls_ssl_get_output_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
+#endif
+}
+
+static inline uint32_t mbedtls_ssl_get_input_buflen( const mbedtls_ssl_context *ctx )
+{
+#if defined (MBEDTLS_SSL_DTLS_CONNECTION_ID)
+ return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD
+ + MBEDTLS_SSL_CID_IN_LEN_MAX;
+#else
+ return (uint32_t) mbedtls_ssl_get_input_max_frag_len( ctx )
+ + MBEDTLS_SSL_HEADER_LEN + MBEDTLS_SSL_PAYLOAD_OVERHEAD;
+#endif
+}
+#endif
+
#ifdef MBEDTLS_ZLIB_SUPPORT
/* Compression buffer holds both IN and OUT buffers, so should be size of the larger */
#define MBEDTLS_SSL_COMPRESS_BUFFER_LEN ( \
@@ -435,19 +461,6 @@ struct mbedtls_ssl_handshake_params
unsigned char *psk; /*!< PSK from the callback */
size_t psk_len; /*!< Length of PSK from callback */
#endif
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */
-#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
- mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */
-#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
-
-#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
- int sni_authmode; /*!< authmode from SNI callback */
- mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */
- mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */
- mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
-#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
-#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
int ecrs_enabled; /*!< Handshake supports EC restart? */
mbedtls_x509_crt_restart_ctx ecrs_ctx; /*!< restart context */
@@ -492,9 +505,9 @@ struct mbedtls_ssl_handshake_params
struct mbedtls_ssl_hs_buffer
{
- unsigned is_valid : 1;
- unsigned is_fragmented : 1;
- unsigned is_complete : 1;
+ uint8_t is_valid;
+ uint8_t is_fragmented;
+ uint8_t is_complete;
unsigned char *data;
size_t data_len;
} hs[MBEDTLS_SSL_MAX_BUFFERED_HS];
@@ -504,6 +517,19 @@ struct mbedtls_ssl_handshake_params
unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; /*! The peer's CID */
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */
+#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */
+#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+
+#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ int sni_authmode; /*!< authmode from SNI callback */
+ mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */
+ mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */
+ mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
+#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
+#endif /* MBEDTLS_X509_CRT_PARSE_C */
unsigned char randbytes[64]; /*!< random bytes */
unsigned char premaster[MBEDTLS_PREMASTER_SIZE];
/*!< premaster secret */
@@ -533,7 +559,7 @@ struct mbedtls_ssl_handshake_params
#endif
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
- unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
+ uint8_t async_in_progress; /*!< an asynchronous operation is in progress */
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
@@ -547,6 +573,10 @@ struct mbedtls_ssl_handshake_params
#if defined(MBEDTLS_USE_TINYCRYPT)
uint8_t ecdh_privkey[NUM_ECC_BYTES];
+#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION)
+ uint8_t ecdhe_computed;
+ uint8_t ecdh_publickey[2*NUM_ECC_BYTES];
+#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION */
uint8_t ecdh_peerkey[2*NUM_ECC_BYTES];
#endif /* MBEDTLS_USE_TINYCRYPT */
@@ -756,9 +786,19 @@ struct mbedtls_ssl_transform
z_stream ctx_inflate; /*!< decompression context */
#endif
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ unsigned char *key_enc;
+ unsigned char *key_dec;
+ unsigned int key_bitlen;
+ mbedtls_cipher_context_t cipher_ctx; /*!< encryption/decryption context */
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ uint32_t key_enc_hash; /*!< hash of the encryption key */
+ uint32_t key_dec_hash; /*!< hash of the decryption key */
+#endif
+#else
mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */
mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */
-
+#endif
#if defined(MBEDTLS_SSL_CONTEXT_SERIALIZATION)
/* We need the Hello random bytes in order to re-derive keys from the
* Master Secret and other session info, see ssl_populate_transform() */
@@ -1049,6 +1089,14 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
mbedtls_md_type_t md );
#endif
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+int mbedtls_ssl_parse_delayed_certificate_verify( mbedtls_ssl_context *ssl,
+ int authmode,
+ mbedtls_x509_crt *chain,
+ void *rs_ctx );
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED && MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
+
+
static inline int mbedtls_ssl_get_minor_ver( mbedtls_ssl_context const *ssl )
{
#if !defined(MBEDTLS_SSL_CONF_FIXED_MINOR_VER)
@@ -1155,6 +1203,9 @@ void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl );
void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl );
int mbedtls_ssl_resend( mbedtls_ssl_context *ssl );
int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl );
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+void mbedtls_ssl_immediate_flight_done( mbedtls_ssl_context *ssl );
+#endif
#endif
/* Visible for testing purposes only */
@@ -1418,6 +1469,21 @@ static inline unsigned int mbedtls_ssl_conf_get_endpoint(
}
#endif /* MBEDTLS_SSL_CONF_ENDPOINT */
+#if !defined(MBEDTLS_SSL_CONF_TRANSPORT)
+static inline unsigned int mbedtls_ssl_conf_get_transport(
+ mbedtls_ssl_config const *conf )
+{
+ return( conf->transport );
+}
+#else /* !MBEDTLS_SSL_CONF_TRANSPORT */
+static inline unsigned int mbedtls_ssl_conf_get_transport(
+ mbedtls_ssl_config const *conf )
+{
+ ((void) conf);
+ return( MBEDTLS_SSL_CONF_TRANSPORT );
+}
+#endif /* MBEDTLS_SSL_CONF_TRANSPORT */
+
#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT)
static inline uint32_t mbedtls_ssl_conf_get_read_timeout(
mbedtls_ssl_config const *conf )
diff --git a/include/tinycrypt/ecc.h b/include/tinycrypt/ecc.h
index f2a5ad67d..cdb5762a2 100644
--- a/include/tinycrypt/ecc.h
+++ b/include/tinycrypt/ecc.h
@@ -98,10 +98,10 @@ extern "C" {
#endif
/* defining data types to store word and bit counts: */
-typedef int8_t wordcount_t;
-typedef int16_t bitcount_t;
+typedef int_fast8_t wordcount_t;
+typedef int_fast16_t bitcount_t;
/* defining data type for comparison result: */
-typedef int8_t cmpresult_t;
+typedef int_fast8_t cmpresult_t;
/* defining data type to store ECC coordinate/point in 32bits words: */
typedef unsigned int uECC_word_t;
/* defining data type to store an ECC coordinate/point in 64bits words: */
diff --git a/include/tinycrypt/ecc_dsa.h b/include/tinycrypt/ecc_dsa.h
index 0001ecb2d..30cbe5eef 100644
--- a/include/tinycrypt/ecc_dsa.h
+++ b/include/tinycrypt/ecc_dsa.h
@@ -115,7 +115,7 @@ int uECC_sign(const uint8_t *p_private_key, const uint8_t *p_message_hash,
* Refer to uECC_sign() function for real applications.
*/
int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
- unsigned int hash_size, uECC_word_t *k, uint8_t *signature)
+ unsigned int hash_size, uECC_word_t *k, uint8_t *signature);
#endif
/**
diff --git a/library/aes.c b/library/aes.c
index 800517295..72cfc104d 100644
--- a/library/aes.c
+++ b/library/aes.c
@@ -85,30 +85,31 @@
}
#endif
-#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
-static uint32_t mbedtls_hash( const void *data, size_t data_len_bytes )
-{
- uint32_t result = 0;
- size_t i;
- /* data_len_bytes - only multiples of 4 are considered, rest is truncated */
- for( i = 0; i < data_len_bytes >> 2; i++ )
- {
- result ^= ( (uint32_t*) data )[i];
- }
- return result;
-}
-#endif
/*
* Data structure for AES round data
*/
typedef struct {
uint32_t *rk_ptr; /* Round Key */
uint32_t xy_values[8]; /* X0, X1, X2, X3, Y0, Y1, Y2, Y3 */
+#if defined(MBEDTLS_AES_128_BIT_MASKED)
+ uint32_t round;
+#endif
} aes_r_data_t;
#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
/* Number of additional AES dummy rounds added for SCA countermeasures */
#define AES_SCA_CM_ROUNDS 5
+
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+
+#define Nb (4) /* number of columns (32-bit words) comprising the state */
+#define Nk (4) /* number of 32-bit words comprising the key */
+#define Nr (10) /* number of rounds */
+
+// state - array holding the intermediate results during aes operation.
+typedef uint8_t masked_state_t[4][4];
+
+#endif
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
#if defined(MBEDTLS_PADLOCK_C) && \
@@ -156,6 +157,8 @@ static const unsigned char FSb[256] =
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
+
+#if !defined(MBEDTLS_AES_128_BIT_MASKED)
/*
* Forward tables
*/
@@ -247,6 +250,8 @@ static const uint32_t FT3[256] = { FT };
#endif /* !MBEDTLS_AES_FEWER_TABLES */
#undef FT
+#endif //ifndef MBEDTLS_AES_128_BIT_MASKED
+
#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
/*
@@ -287,6 +292,7 @@ static const unsigned char RSb[256] =
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
+
#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
/*
@@ -399,7 +405,9 @@ static const uint32_t RCON[10] =
* Forward S-box & tables
*/
static unsigned char FSb[256];
+#if !defined(MBEDTLS_AES_128_BIT_MASKED)
static uint32_t FT0[256];
+#endif
#if !defined(MBEDTLS_AES_FEWER_TABLES)
static uint32_t FT1[256];
static uint32_t FT2[256];
@@ -411,6 +419,7 @@ static uint32_t FT3[256];
*/
#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
static unsigned char RSb[256];
+
static uint32_t RT0[256];
#if !defined(MBEDTLS_AES_FEWER_TABLES)
static uint32_t RT1[256];
@@ -427,15 +436,20 @@ static uint32_t RCON[10];
/*
* Tables generation code
*/
-#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
+#if !defined(MBEDTLS_AES_128_BIT_MASKED)
+#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
+#endif
static int aes_init_done = 0;
static void aes_gen_tables( void )
{
- int i, x, y, z;
+ int i, x, y;
+#if !defined(MBEDTLS_AES_128_BIT_MASKED)
+ int z;
+#endif
int pow[256];
int log[256];
@@ -481,7 +495,7 @@ static void aes_gen_tables( void )
RSb[x] = (unsigned char) i;
#endif
}
-
+#if !defined(MBEDTLS_AES_128_BIT_MASKED)
/*
* generate the forward and reverse tables
*/
@@ -517,6 +531,8 @@ static void aes_gen_tables( void )
#endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
}
+
+#endif //MBEDTLS_AES_128_BIT_MASKED
}
#undef ROTL8
@@ -560,7 +576,7 @@ static void aes_gen_tables( void )
* |0x10|0x03|0x10|0x10|0x10|0x04|0x00| ... |0x04|0x00|0x04|0x03|0x07|
*/
#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
-static int aes_sca_cm_data_randomize( uint8_t *tbl, uint8_t tbl_len )
+static int aes_sca_cm_data_randomize( uint8_t *tbl, int tbl_len )
{
int i = 0, j, is_even_pos, dummy_rounds, num;
@@ -624,6 +640,7 @@ static int aes_sca_cm_data_randomize( uint8_t *tbl, uint8_t tbl_len )
}
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
+#if !defined(MBEDTLS_AES_128_BIT_MASKED)
#if defined(MBEDTLS_AES_FEWER_TABLES)
#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
@@ -653,6 +670,7 @@ static int aes_sca_cm_data_randomize( uint8_t *tbl, uint8_t tbl_len )
#define AES_FT3(idx) FT3[idx]
#endif /* MBEDTLS_AES_FEWER_TABLES */
+#endif
void mbedtls_aes_init( mbedtls_aes_context *ctx )
{
@@ -713,7 +731,6 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
uint32_t *RK;
uint32_t offset = 0;
-
AES_VALIDATE_RET( ctx != NULL );
AES_VALIDATE_RET( key != NULL );
(void) ret;
@@ -744,6 +761,7 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
else
#endif
+
ctx->rk = RK = ctx->buf;
#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
mbedtls_generate_fake_key( keybits, ctx );
@@ -774,7 +792,6 @@ int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
switch( ctx->nr )
{
case 10:
-
for( i = 0; i < 10; i++, RK += 4 )
{
RK[4] = RK[0] ^ RCON[i] ^
@@ -1039,6 +1056,299 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
+
+#if defined(MBEDTLS_AES_128_BIT_MASKED)
+
+static uint8_t xtime( uint8_t x )
+{
+ return ( ( x << 1 ) ^ ( ( ( x >> 7 ) & 1 ) * 0x1b ) );
+}
+
+static int sub_bytes_masked( uint32_t *data, uint8_t sbox_masked[256] )
+{
+ volatile unsigned int i;
+
+ for ( i = 0; i < 4; i++ )
+ {
+ data[i] = ( (uint32_t)sbox_masked[(data[i]) & 0xFF] ) ^
+ ( (uint32_t)sbox_masked[(data[i] >> 8 ) & 0xFF] << 8 ) ^
+ ( (uint32_t)sbox_masked[(data[i] >> 16 ) & 0xFF] << 16 ) ^
+ ( (uint32_t)sbox_masked[(data[i] >> 24 ) & 0xFF] << 24 );
+ }
+
+ if ( i == 4 )
+ {
+ return 0;
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+static int mix_columns( uint8_t *s )
+{
+ masked_state_t *state = (masked_state_t *)s;
+ volatile unsigned int i = 0;
+ uint8_t Tmp, Tm, t;
+
+ for ( i = 0; i < 4; ++i )
+ {
+ t = (*state)[i][0];
+ Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];
+ Tm = (*state)[i][0] ^ (*state)[i][1];
+ Tm = xtime(Tm);
+ (*state)[i][0] ^= Tm ^ Tmp;
+ Tm = (*state)[i][1] ^ (*state)[i][2];
+ Tm = xtime(Tm);
+ (*state)[i][1] ^= Tm ^ Tmp;
+ Tm = (*state)[i][2] ^ (*state)[i][3];
+ Tm = xtime(Tm);
+ (*state)[i][2] ^= Tm ^ Tmp;
+ Tm = (*state)[i][3] ^ t;
+ Tm = xtime(Tm);
+ (*state)[i][3] ^= Tm ^ Tmp;
+ }
+
+ if ( i == 4 )
+ {
+ return 0;
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+static void shift_rows( uint8_t *s )
+{
+ uint8_t temp;
+ masked_state_t *state = (masked_state_t *)s;
+ // Rotate first row 1 columns to left
+ temp = (*state)[0][1];
+ (*state)[0][1] = (*state)[1][1];
+ (*state)[1][1] = (*state)[2][1];
+ (*state)[2][1] = (*state)[3][1];
+ (*state)[3][1] = temp;
+
+ // Rotate second row 2 columns to left
+ temp = (*state)[0][2];
+ (*state)[0][2] = (*state)[2][2];
+ (*state)[2][2] = temp;
+
+ temp = (*state)[1][2];
+ (*state)[1][2] = (*state)[3][2];
+ (*state)[3][2] = temp;
+
+ // Rotate third row 3 columns to left
+ temp = (*state)[0][3];
+ (*state)[0][3] = (*state)[3][3];
+ (*state)[3][3] = (*state)[2][3];
+ (*state)[2][3] = (*state)[1][3];
+ (*state)[1][3] = temp;
+}
+
+#define mul_02( num ) ( ( num << 1 ) ^ ( 0x11b & - ( num >> 7 ) ) )
+#define mul_03( num ) ( mul_02( num ) ^ num )
+
+static void calc_mix_colmn_mask( uint32_t mask[10] )
+{
+ mask[6] = mul_02( mask[0] ) ^ mul_03( mask[1] ) ^ mask[2] ^ mask[3];
+ mask[7] = mask[0] ^ mul_02( mask[1] ) ^ mul_03( mask[2] ) ^ mask[3];
+ mask[8] = mask[0] ^ mask[1] ^ mul_02( mask[2] ) ^ mul_03( mask[3] );
+ mask[9] = mul_03( mask[0] ) ^ mask[1] ^ mask[2] ^ mul_02( mask[3] );
+}
+
+//Calculate the the invSbox to change from Mask m to Mask m'
+static int calc_sbox_masked( uint32_t mask[10], uint8_t sbox_masked[256] )
+{
+ volatile unsigned int i = 0;
+
+ for ( i = 0; i < 256; i++ )
+ {
+ sbox_masked[i ^ mask[4]] = FSb[i] ^ mask[5];
+ }
+ if ( i == 256 )
+ {
+ return 0;
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+static int remask( uint32_t *data, uint32_t m1, uint32_t m2,
+ uint32_t m3, uint32_t m4, uint32_t m5,
+ uint32_t m6, uint32_t m7, uint32_t m8 )
+{
+ volatile unsigned int i = 0;
+
+ for ( i = 0; i < 4; i++ )
+ {
+ data[i] = data[i] ^ ( ( m1 ^ m5 ) );
+ data[i] = data[i] ^ ( ( m2 ^ m6 ) << 8 );
+ data[i] = data[i] ^ ( ( m3 ^ m7 ) << 16 );
+ data[i] = data[i] ^ ( ( m4 ^ m8 ) << 24 );
+ }
+
+ if ( i == 4 )
+ {
+ return 0;
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+#define MASK_INIT_CONTROL 19
+
+static int init_masking_encrypt( const uint8_t *rk, uint8_t *rk_masked,
+ uint32_t mask[10], uint8_t sbox_masked[256] )
+{
+ volatile int flow_control = 0;
+ unsigned int i = 0;
+
+ mbedtls_platform_memcpy( rk_masked, rk,
+ MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS * 4 );
+
+ //Randomly generate the masks: m1 m2 m3 m4 m m'
+ for ( i = 0; i < 6; i++ )
+ {
+ mask[i] = mbedtls_platform_random_in_range( 0xFF );
+ flow_control++;
+ }
+
+ //Calculate m1',m2',m3',m4'
+ calc_mix_colmn_mask( mask );
+ flow_control++;
+
+ //Calculate the masked Sbox
+ if ( calc_sbox_masked( mask, sbox_masked ) == 0 )
+ {
+ flow_control++;
+ }
+
+ //Init masked key
+ if ( remask( (uint32_t *)&rk_masked[(Nr * Nb * 4)], 0, 0, 0, 0,
+ mask[5], mask[5], mask[5], mask[5]) == 0 )
+ {
+ flow_control++;
+ }
+
+ // Mask change from M1',M2',M3',M4' to M
+ for ( i = 0; i < Nr; i++ )
+ {
+ if ( remask( (uint32_t *)&rk_masked[( i * Nb * 4 )], mask[6],
+ mask[7], mask[8], mask[9], mask[4], mask[4], mask[4], mask[4]) == 0 )
+ {
+ flow_control++;
+ }
+ }
+
+ if ( flow_control == MASK_INIT_CONTROL )
+ {
+ mbedtls_platform_random_delay();
+ if (flow_control == MASK_INIT_CONTROL)
+ {
+ return MASK_INIT_CONTROL;
+ }
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+static int add_rk_masked( uint32_t round, uint32_t *data,
+ const uint32_t * rk_masked )
+{
+ volatile unsigned int i;
+ unsigned int offset = round * 4;
+
+ for ( i = 0; i < 4; i++ )
+ {
+ data[i] ^= rk_masked[offset + i];
+ }
+
+ if ( i == 4 )
+ {
+ return 0;
+ }
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+static int aes_masked_round( uint32_t *data, uint32_t *key, uint32_t round,
+ uint32_t mask[10], uint8_t sbox_masked[256] )
+{
+ volatile uint32_t flow_control = 0;
+
+// Mask changes from M to M'
+ if ( sub_bytes_masked( data, sbox_masked ) == 0 )
+ {
+ flow_control++;
+ }
+
+ //No impact on mask
+ shift_rows((uint8_t *)data);
+
+ //Change mask from M' to
+ // M1 for first row
+ // M2 for second row
+ // M3 for third row
+ // M4 for fourth row
+ if ( remask( data, mask[0], mask[1], mask[2], mask[3],
+ mask[5], mask[5], mask[5], mask[5]) == 0 )
+ {
+ flow_control++;
+ }
+
+ // Masks change from M1,M2,M3,M4 to M1',M2',M3',M4'
+ if ( mix_columns( (uint8_t *)data ) == 0 )
+ {
+ flow_control++;
+ }
+
+ // Add the First round key to the state before starting the rounds.
+ // Masks change from M1',M2',M3',M4' to M
+ if ( add_rk_masked( round, data, key ) == 0 )
+ {
+ flow_control++;
+ }
+
+ if ( flow_control == 4 )
+ {
+ return 0;
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+static int aes_masked_round_final( uint32_t *data, uint32_t *key,
+ uint8_t sbox_masked[256] )
+{
+ volatile uint32_t flow_control = 0;
+
+ if ( sub_bytes_masked(data, sbox_masked) == 0 )
+ {
+ flow_control++;
+ }
+
+ shift_rows( (uint8_t *)data );
+
+ // Mask are removed by the last addroundkey
+ // From M' to 0
+ if( add_rk_masked( Nr, data, key ) == 0 )
+ {
+ flow_control++;
+ }
+
+ if ( flow_control == 2 )
+ {
+ return 0;
+ }
+
+ return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+
+//2 comes from initial data remask of real and fake data
+#define MASKING_FLOW_CONTORL ( MASK_INIT_CONTROL + 2 )
+
+#else // end of MBEDTLS_AES_128_BIT_MASKED
+
+#define MASKING_FLOW_CONTORL 0
+
static uint32_t *aes_fround( uint32_t *R,
uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
@@ -1066,10 +1376,12 @@ static uint32_t *aes_fround( uint32_t *R,
return R;
}
+
static void aes_fround_final( uint32_t *R,
uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
{
+
*X0 = *R++ ^ ( (uint32_t) FSb[ ( (Y0) ) & 0xFF ] ) ^
( (uint32_t) FSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
( (uint32_t) FSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
@@ -1090,6 +1402,8 @@ static void aes_fround_final( uint32_t *R,
( (uint32_t) FSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
( (uint32_t) FSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
}
+#endif // MBEDTLS_AES_128_BIT_MASKED
+
int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
const unsigned char input[16],
@@ -1099,13 +1413,19 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
aes_r_data_t aes_data_real; // real data
aes_r_data_t aes_data_fake; // fake data
aes_r_data_t *aes_data_ptr; // pointer to real or fake data
- aes_r_data_t *aes_data_table[2]; // pointers to real and fake data
+ aes_r_data_t *aes_data_table[2] = {0}; // pointers to real and fake data
int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
- volatile int flow_control;
+ volatile int flow_control = 0;
// control bytes for AES calculation rounds,
// reserve based on max rounds + dummy rounds + 2 (for initial key addition)
uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
+#if defined MBEDTLS_AES_128_BIT_MASKED
+ uint32_t rk_masked[MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS];
+ uint8_t sbox_masked[256];
+ uint32_t mask[10];
+#endif
+
#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
unsigned key_bytes = 0;
uint32_t check_hash = 0;
@@ -1121,7 +1441,17 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
check_hash = mbedtls_hash( ctx->rk, key_bytes );
#endif
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ /* Flow control should be MASK_INIT_CONTROL and it will be checked as
+ a part last flow control verification */
+ flow_control = init_masking_encrypt( (uint8_t *)ctx->rk,
+ (uint8_t *)rk_masked, mask, sbox_masked );
+
+ aes_data_real.rk_ptr = &rk_masked[0];
+#else
aes_data_real.rk_ptr = ctx->rk;
+#endif
+
aes_data_fake.rk_ptr = ctx->frk;
aes_data_table[0] = &aes_data_real;
@@ -1130,7 +1460,7 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
// Get AES calculation control bytes
dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
round_ctrl_table_len );
- flow_control = dummy_rounds;
+ flow_control += dummy_rounds;
// SCA countermeasure, safely clear the aes_data_real.xy_values
mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
@@ -1147,6 +1477,21 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
flow_control++;
} while( ( i = ( i + 1 ) % 4 ) != offset );
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ //Plain text masked with m1',m2',m3',m4'
+ if (remask( &aes_data_real.xy_values[0], mask[6],
+ mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0 )
+ {
+ flow_control++;
+ }
+
+ if (remask( &aes_data_fake.xy_values[0], mask[6],
+ mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0 )
+ {
+ flow_control++;
+ }
+#endif
+
tindex = 0;
do
{
@@ -1155,12 +1500,22 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
stop_mark = round_ctrl_table[tindex] & 0x03;
// initial round key addition
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ if ( add_rk_masked( 0, &aes_data_ptr->xy_values[0],
+ aes_data_ptr->rk_ptr ) == 0 )
+ {
+ flow_control++;
+ }
+ aes_data_ptr->round = 1;
+#else
for( i = 0; i < 4; i++ )
{
aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
}
- tindex++;
flow_control++;
+#endif
+
+ tindex++;
} while( stop_mark == 0 );
// Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
@@ -1170,7 +1525,15 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
offset = round_ctrl_table[tindex] & 0x04;
stop_mark = round_ctrl_table[tindex] & 0x03;
-
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ if ( aes_masked_round( &aes_data_ptr->xy_values[0],
+ aes_data_ptr->rk_ptr,
+ aes_data_ptr->round, mask, sbox_masked ) == 0 )
+ {
+ flow_control++;
+ }
+ aes_data_ptr->round ++;
+#else
aes_data_ptr->rk_ptr = aes_fround( aes_data_ptr->rk_ptr,
&aes_data_ptr->xy_values[0 + offset],
&aes_data_ptr->xy_values[1 + offset],
@@ -1180,8 +1543,10 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
aes_data_ptr->xy_values[5 - offset],
aes_data_ptr->xy_values[6 - offset],
aes_data_ptr->xy_values[7 - offset] );
- tindex++;
flow_control++;
+#endif
+ tindex++;
+
} while( stop_mark == 0 );
// Calculate final AES round + dummy rounds
@@ -1189,6 +1554,13 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
{
aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
stop_mark = round_ctrl_table[tindex] & 0x03;
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ if ( aes_masked_round_final( &aes_data_ptr->xy_values[0],
+ aes_data_ptr->rk_ptr, sbox_masked ) == 0 )
+ {
+ flow_control++;
+ }
+#else
aes_fround_final( aes_data_ptr->rk_ptr,
&aes_data_ptr->xy_values[0],
&aes_data_ptr->xy_values[1],
@@ -1199,6 +1571,7 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
aes_data_ptr->xy_values[6],
aes_data_ptr->xy_values[7] );
flow_control++;
+#endif
tindex++;
} while( stop_mark == 0 );
@@ -1215,8 +1588,11 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
flow_control++;
} while( ( i = ( i + 1 ) % 4 ) != offset );
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ mbedtls_platform_memset( rk_masked, 0, sizeof(rk_masked) );
+#endif
/* Double negation is used to silence an "extraneous parentheses" warning */
- if( ! ( flow_control != tindex + dummy_rounds + 8 )
+ if( ! ( flow_control != tindex + dummy_rounds + MASKING_FLOW_CONTORL + 8 )
#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
&& check_hash == ctx->hash
#endif
@@ -1233,6 +1609,15 @@ int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
// Clear the output in case of a FI
mbedtls_platform_memset( output, 0, 16 );
+ mbedtls_platform_memset( (uint8_t*)&aes_data_real, 0,
+ sizeof(aes_data_real) );
+ mbedtls_platform_memset ( aes_data_table, 0, sizeof(aes_data_table) );
+#if defined (MBEDTLS_AES_128_BIT_MASKED)
+ //Clear masked key, masked sbox and mask in case of a FI
+ mbedtls_platform_memset( rk_masked, 0, sizeof(rk_masked) );
+ mbedtls_platform_memset( mask, 0, sizeof(mask) );
+ mbedtls_platform_memset( sbox_masked, 0, sizeof(sbox_masked) );
+#endif
return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
@@ -1634,9 +2019,9 @@ int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
return( 0 );
}
+#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
-#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
#endif /* !MBEDTLS_AES_DECRYPT_ALT */
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
diff --git a/library/ccm.c b/library/ccm.c
index 750ec9e98..5ba869a01 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -40,6 +40,7 @@
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
+#include <stdint.h>
#include <string.h>
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
@@ -113,6 +114,43 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
}
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+/* Durstenfeld's version of Fisher-Yates shuffle */
+static void mbedtls_generate_permutation( unsigned char* table, size_t size )
+{
+ size_t i, j;
+
+ for( i = 0; i < size; i++ )
+ {
+ table[i] = (unsigned char) i;
+ }
+
+ if( size < 2 )
+ {
+ return;
+ }
+
+ for( i = size - 1; i > 0; i-- )
+ {
+ unsigned char tmp;
+ j = mbedtls_platform_random_in_range( (uint32_t) i + 1 );
+ tmp = table[i];
+ table[i] = table[j];
+ table[j] = tmp;
+ }
+}
+
+static void mbedtls_generate_masks( unsigned char* table, size_t size )
+{
+ size_t i;
+
+ for( i = 0; i < size; i++ )
+ {
+ table[i] = mbedtls_platform_random_in_range( 256 );
+ }
+}
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
+
/*
* Macros for common operations.
* Results in smaller compiled code than static inline functions.
@@ -121,20 +159,73 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
/*
* Update the CBC-MAC state in y using a block in b
* (Always using b as the source helps the compiler optimise a bit better.)
+ * Initial b masking happens outside of this macro due to various sources of it.
*/
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+#define UPDATE_CBC_MAC \
+ for( i = 0; i < 16; i++ ) \
+ { \
+ y[perm_table[i]] ^= b[perm_table[i]]; \
+ y[perm_table[i]] ^= mask_table[perm_table[i]]; \
+ } \
+ \
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
+ return( ret );
+#else
#define UPDATE_CBC_MAC \
for( i = 0; i < 16; i++ ) \
y[i] ^= b[i]; \
\
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \
return( ret );
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
+
+/*
+ * Copy src to dst starting at a random offset, while masking the whole dst buffer.
+ */
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+#define COPY_MASK( dst, src, mask, len_src, len_dst ) \
+ do \
+ { \
+ unsigned j, offset = mbedtls_platform_random_in_range( 256 ); \
+ mbedtls_generate_masks( mask_table, 16 ); \
+ mbedtls_generate_permutation( perm_table, 16 ); \
+ for( i = 0; i < len_src; i++ ) \
+ { \
+ j = (i + offset) % len_src; \
+ (dst)[j] = (src)[j] ^ (mask)[j]; \
+ } \
+ for( ; i < len_dst; i++ ) \
+ (dst)[i] ^= (mask)[i]; \
+ } while( 0 )
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
/*
* Encrypt or decrypt a partial block with CTR
* Warning: using b for temporary storage! src and dst must not be b!
* This avoids allocating one more 16 bytes buffer while allowing src == dst.
*/
-#define CTR_CRYPT( dst, src, len ) \
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+#define CTR_CRYPT( dst, src, len ) \
+ do \
+ { \
+ mbedtls_generate_permutation( perm_table, len ); \
+ mbedtls_generate_masks( mask_table, len ); \
+ if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \
+ 16, b, &olen ) ) != 0 ) \
+ { \
+ return( ret ); \
+ } \
+ \
+ for( i = 0; i < (len); i++ ) \
+ { \
+ (dst)[perm_table[i]] = (src)[perm_table[i]] ^ mask_table[perm_table[i]];\
+ (dst)[perm_table[i]] ^= b[perm_table[i]]; \
+ (dst)[perm_table[i]] ^= mask_table[perm_table[i]]; \
+ } \
+ } while( 0 )
+#else
+#define CTR_CRYPT( dst, src, len ) \
do \
{ \
if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \
@@ -146,6 +237,7 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
for( i = 0; i < (len); i++ ) \
(dst)[i] = (src)[i] ^ b[i]; \
} while( 0 )
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
/*
* Authenticated encryption or decryption
@@ -157,15 +249,19 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
unsigned char *tag, size_t tag_len )
{
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
- unsigned char i;
- unsigned char q;
+ uint_fast8_t i;
+ uint_fast8_t q;
size_t len_left, olen;
unsigned char b[16];
unsigned char y[16];
unsigned char ctr[16];
const unsigned char *src;
unsigned char *dst;
-
+ volatile size_t flow_ctrl = 0;
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ unsigned char perm_table[16];
+ unsigned char mask_table[16];
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
/*
* Check length requirements: SP800-38C A.1
* Additional requirement: a < 2^16 - 2^8 to simplify the code.
@@ -183,7 +279,12 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
if( add_len > 0xFF00 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
- q = 16 - 1 - (unsigned char) iv_len;
+ mbedtls_platform_zeroize( b, 16 );
+ mbedtls_platform_zeroize( y, 16 );
+ mbedtls_platform_zeroize( ctr, 16 );
+
+ q = (uint_fast8_t) (16 - 1 - iv_len);
+ flow_ctrl++; /* 1 */
/*
* First block B_0:
@@ -197,23 +298,39 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
* 5 .. 3 (t - 2) / 2
* 2 .. 0 q - 1
*/
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ mbedtls_generate_masks( mask_table, 16 );
+ mbedtls_generate_permutation( perm_table, 16 );
+ b[0] = (unsigned char) ( ( ( add_len > 0 ) << 6 ) |
+ ( ( ( tag_len - 2 ) / 2 ) << 3 ) |
+ ( q - 1 ) ) ^ mask_table[0];
+
+ for( i = 0; i < iv_len; i++ )
+ {
+ b[i+1] = iv[i] ^ mask_table[i+1];
+ flow_ctrl++; /* iv_len + 1 */
+ }
+ for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
+ b[15-i] = (unsigned char)( ( len_left & 0xFF ) ) ^ mask_table[15-i];
+#else
b[0] = 0;
b[0] |= ( add_len > 0 ) << 6;
b[0] |= ( ( tag_len - 2 ) / 2 ) << 3;
b[0] |= q - 1;
mbedtls_platform_memcpy( b + 1, iv, iv_len );
-
+ flow_ctrl += iv_len; /* iv_len + 1 */
for( i = 0, len_left = length; i < q; i++, len_left >>= 8 )
b[15-i] = (unsigned char)( len_left & 0xFF );
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
if( len_left > 0 )
return( MBEDTLS_ERR_CCM_BAD_INPUT );
-
/* Start CBC-MAC with first block */
memset( y, 0, 16 );
UPDATE_CBC_MAC;
+ flow_ctrl++; /* iv_len + 2 */
/*
* If there is additional data, update CBC-MAC with
@@ -224,24 +341,37 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
size_t use_len;
len_left = add_len;
src = add;
-
mbedtls_platform_memset( b, 0, 16 );
+
+ use_len = len_left < 16 - 2 ? len_left : 16 - 2;
+
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ COPY_MASK( b+2, src, mask_table+2, use_len, 14 );
+ b[0] = (unsigned char)( ( ( add_len >> 8 ) & 0xFF ) ^ mask_table[0] );
+ b[1] = (unsigned char)( ( ( add_len ) & 0xFF ) ^ mask_table[1] );
+#else
b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF );
b[1] = (unsigned char)( ( add_len ) & 0xFF );
- use_len = len_left < 16 - 2 ? len_left : 16 - 2;
mbedtls_platform_memcpy( b + 2, src, use_len );
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
+
len_left -= use_len;
src += use_len;
UPDATE_CBC_MAC;
+ flow_ctrl++; /* iv_len + 2 + ( add_len? 1 : 0 ) */
while( len_left > 0 )
{
use_len = len_left > 16 ? 16 : len_left;
-
mbedtls_platform_memset( b, 0, 16 );
+
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ COPY_MASK( b, src, mask_table, use_len, 16 );
+#else
mbedtls_platform_memcpy( b, src, use_len );
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
UPDATE_CBC_MAC;
len_left -= use_len;
@@ -263,6 +393,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
mbedtls_platform_memcpy( ctr + 1, iv, iv_len );
mbedtls_platform_memset( ctr + 1 + iv_len, 0, q );
ctr[15] = 1;
+ flow_ctrl++; /* iv_len + 3 + ( add_len? 1 : 0 ) */
/*
* Authenticate and {en,de}crypt the message.
@@ -281,8 +412,14 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
if( mode == CCM_ENCRYPT )
{
mbedtls_platform_memset( b, 0, 16 );
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ COPY_MASK( b, src, mask_table, use_len, 16 );
+#else
mbedtls_platform_memcpy( b, src, use_len );
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
+
UPDATE_CBC_MAC;
+ flow_ctrl++; /* iv_len + 3 + ( add_len? 1 : 0 ) + encryptions */
}
CTR_CRYPT( dst, src, use_len );
@@ -290,8 +427,13 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
if( mode == CCM_DECRYPT )
{
mbedtls_platform_memset( b, 0, 16 );
- mbedtls_platform_memcpy( b, dst, use_len );
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ COPY_MASK( b, dst, mask_table, use_len, 16 );
+#else
+ mbedtls_platform_memcpy( b, dst, use_len );
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
UPDATE_CBC_MAC;
+ flow_ctrl++; /* iv_len + 3 + ( add_len? 1 : 0 ) + decryptions */
}
dst += use_len;
@@ -306,6 +448,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
if( ++ctr[15-i] != 0 )
break;
}
+ flow_ctrl++; /* iv_len + 4 + ( add_len? 1 : 0 ) + enc/dec */
/*
* Authentication: reset counter and crypt/mask internal tag
@@ -316,7 +459,25 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
CTR_CRYPT( y, y, 16 );
mbedtls_platform_memcpy( tag, y, tag_len );
- return( ret );
+ flow_ctrl++; /* iv_len + 5 + ( add_len? 1 : 0 ) + enc/dec */
+
+ mbedtls_platform_zeroize( b, 16 );
+ mbedtls_platform_zeroize( y, 16 );
+ mbedtls_platform_zeroize( ctr, 16 );
+
+ {
+ size_t operations = length / 16;
+ operations += ( length % 16 ? 1 : 0 );
+ operations += ( add_len > 0 ? 1 : 0 );
+ /* See comments above on steps in calculating flow_ctrl */
+ if( flow_ctrl == iv_len + 5 + operations )
+ {
+ mbedtls_platform_random_delay();
+ if( flow_ctrl == iv_len + 5 + operations )
+ return( ret );
+ }
+ }
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
/*
@@ -368,7 +529,7 @@ int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
{
int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
unsigned char check_tag[16];
- unsigned char i;
+ uint_fast8_t i;
int diff;
CCM_VALIDATE_RET( ctx != NULL );
diff --git a/library/cipher.c b/library/cipher.c
index 7164741b1..6eab899bc 100644
--- a/library/cipher.c
+++ b/library/cipher.c
@@ -36,6 +36,7 @@
#include "mbedtls/platform_util.h"
#include <stdlib.h>
+#include <stdint.h>
#include <string.h>
#if defined(MBEDTLS_CHACHAPOLY_C)
@@ -186,6 +187,7 @@ int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_in
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
mbedtls_platform_memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) );
+ ctx->operation = MBEDTLS_OPERATION_NONE;
if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) )
return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
@@ -590,7 +592,7 @@ static void add_pkcs_padding( unsigned char *output, size_t output_len,
size_t data_len )
{
size_t padding_len = output_len - data_len;
- unsigned char i;
+ uint_fast8_t i;
for( i = 0; i < padding_len; i++ )
output[data_len + i] = (unsigned char) padding_len;
@@ -600,7 +602,7 @@ static int get_pkcs_padding( unsigned char *input, size_t input_len,
size_t *data_len )
{
size_t i, pad_idx;
- unsigned char padding_len, bad = 0;
+ uint_fast8_t padding_len, bad = 0;
if( NULL == input || NULL == data_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@@ -630,7 +632,7 @@ static void add_one_and_zeros_padding( unsigned char *output,
size_t output_len, size_t data_len )
{
size_t padding_len = output_len - data_len;
- unsigned char i = 0;
+ uint_fast8_t i = 0;
output[data_len] = 0x80;
for( i = 1; i < padding_len; i++ )
@@ -641,7 +643,7 @@ static int get_one_and_zeros_padding( unsigned char *input, size_t input_len,
size_t *data_len )
{
size_t i;
- unsigned char done = 0, prev_done, bad;
+ uint_fast8_t done = 0, prev_done, bad;
if( NULL == input || NULL == data_len )
return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
@@ -669,7 +671,7 @@ static void add_zeros_and_len_padding( unsigned char *output,
size_t output_len, size_t data_len )
{
size_t padding_len = output_len - data_len;
- unsigned char i = 0;
+ uint_fast8_t i = 0;
for( i = 1; i < padding_len; i++ )
output[data_len + i - 1] = 0x00;
diff --git a/library/ecp.c b/library/ecp.c
index 3cdd566b5..ff13e8858 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -82,6 +82,7 @@
#include "mbedtls/threading.h"
#include "mbedtls/platform_util.h"
+#include <stdint.h>
#include <string.h>
#if !defined(MBEDTLS_ECP_ALT)
@@ -183,7 +184,7 @@ static void ecp_restart_rsm_init( mbedtls_ecp_restart_mul_ctx *ctx )
*/
static void ecp_restart_rsm_free( mbedtls_ecp_restart_mul_ctx *ctx )
{
- unsigned char i;
+ uint_fast8_t i;
if( ctx == NULL )
return;
@@ -1753,7 +1754,7 @@ static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
unsigned char i )
{
int ret;
- unsigned char ii, j;
+ uint_fast8_t ii, j;
/* Ignore the "sign" bit and scale down */
ii = ( i & 0x7Fu ) >> 1;
@@ -2019,7 +2020,8 @@ static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
mbedtls_ecp_restart_ctx *rs_ctx )
{
int ret;
- unsigned char w, p_eq_g, i;
+ unsigned char w, p_eq_g;
+ uint_fast8_t i;
size_t d;
unsigned char T_size, T_ok;
mbedtls_ecp_point *T;
diff --git a/library/platform_util.c b/library/platform_util.c
index 458dfc9be..88987d807 100644
--- a/library/platform_util.c
+++ b/library/platform_util.c
@@ -48,6 +48,12 @@
#include "mbedtls/entropy_poll.h"
#endif
+#if defined(MBEDTLS_PLATFORM_FAULT_CALLBACKS)
+#include "platform_fault.h"
+#else
+static void mbedtls_platform_fault(){}
+#endif
+
#include <stddef.h>
#include <string.h>
@@ -119,43 +125,45 @@ void *mbedtls_platform_zeroize( void *buf, size_t len )
void *mbedtls_platform_memset( void *ptr, int value, size_t num )
{
- size_t i, start_offset;
+ size_t i, start_offset = 0;
volatile size_t flow_counter = 0;
volatile char *b = ptr;
char rnd_data;
+ if( num > 0 )
+ {
+ start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
- start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
- rnd_data = (char) mbedtls_platform_random_in_range( 256 );
+ rnd_data = (char) mbedtls_platform_random_in_range( 256 );
- /* Perform a memset operations with random data and start from a random
- * location */
- for( i = start_offset; i < num; ++i )
- {
- b[i] = rnd_data;
- flow_counter++;
- }
+ /* Perform a memset operations with random data and start from a random
+ * location */
+ for( i = start_offset; i < num; ++i )
+ {
+ b[i] = rnd_data;
+ flow_counter++;
+ }
- /* Start from a random location with target data */
- for( i = start_offset; i < num; ++i )
- {
- b[i] = value;
- flow_counter++;
- }
+ /* Start from a random location with target data */
+ for( i = start_offset; i < num; ++i )
+ {
+ b[i] = value;
+ flow_counter++;
+ }
- /* Second memset operation with random data */
- for( i = 0; i < start_offset; ++i )
- {
- b[i] = rnd_data;
- flow_counter++;
- }
+ /* Second memset operation with random data */
+ for( i = 0; i < start_offset; ++i )
+ {
+ b[i] = rnd_data;
+ flow_counter++;
+ }
- /* Finish memset operation with correct data */
- for( i = 0; i < start_offset; ++i )
- {
- b[i] = value;
- flow_counter++;
+ /* Finish memset operation with correct data */
+ for( i = 0; i < start_offset; ++i )
+ {
+ b[i] = value;
+ flow_counter++;
+ }
}
-
/* check the correct number of iterations */
if( flow_counter == 2 * num )
{
@@ -165,6 +173,7 @@ void *mbedtls_platform_memset( void *ptr, int value, size_t num )
return ptr;
}
}
+ mbedtls_platform_fault();
return NULL;
}
@@ -204,6 +213,7 @@ void *mbedtls_platform_memcpy( void *dst, const void *src, size_t num )
return dst;
}
}
+ mbedtls_platform_fault();
return NULL;
}
@@ -245,22 +255,25 @@ int mbedtls_platform_memequal( const void *buf1, const void *buf2, size_t num )
/* Start from a random location and check the correct number of iterations */
size_t i, flow_counter = 0;
- size_t start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
-
- for( i = start_offset; i < num; i++ )
+ size_t start_offset = 0;
+ if( num > 0 )
{
- unsigned char x = A[i], y = B[i];
- flow_counter++;
- diff |= x ^ y;
- }
+ start_offset = (size_t) mbedtls_platform_random_in_range( (uint32_t) num );
- for( i = 0; i < start_offset; i++ )
- {
- unsigned char x = A[i], y = B[i];
- flow_counter++;
- diff |= x ^ y;
- }
+ for( i = start_offset; i < num; i++ )
+ {
+ unsigned char x = A[i], y = B[i];
+ flow_counter++;
+ diff |= x ^ y;
+ }
+ for( i = 0; i < start_offset; i++ )
+ {
+ unsigned char x = A[i], y = B[i];
+ flow_counter++;
+ diff |= x ^ y;
+ }
+ }
/* Return 0 only when diff is 0 and flow_counter is equal to num */
return( (int) diff | (int) ( flow_counter ^ num ) );
}
@@ -321,6 +334,7 @@ uint32_t mbedtls_platform_random_uint32( void )
void mbedtls_platform_random_buf( uint8_t *buf, size_t len )
{
+ volatile size_t flow_control = 0, flow_control_check = len;
uint16_t val;
while( len > 1 )
@@ -329,29 +343,24 @@ void mbedtls_platform_random_buf( uint8_t *buf, size_t len )
buf[len-1] = (uint8_t)val;
buf[len-2] = (uint8_t)(val>>8);
len -= 2;
+ flow_control += 2;
}
if( len == 1 )
{
buf[0] = (uint8_t)mbedtls_platform_random_uint16();
+ flow_control ++;
}
- return;
+ if ( flow_control == flow_control_check )
+ {
+ return;
+ }
+ mbedtls_platform_fault();
}
uint32_t mbedtls_platform_random_in_range( uint32_t num )
{
- uint32_t result;
-
- if( num <= 1 )
- {
- result = 0;
- }
- else
- {
- result = mbedtls_platform_random_uint32() % num;
- }
-
- return( result );
+ return mbedtls_platform_random_uint32() % num;
}
void mbedtls_platform_random_delay( void )
@@ -442,6 +451,20 @@ struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
}
#endif /* MBEDTLS_HAVE_TIME_DATE && MBEDTLS_PLATFORM_GMTIME_R_ALT */
+#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY) || defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+uint32_t mbedtls_hash( const void *data, size_t data_len_bytes )
+{
+ uint32_t result = 0;
+ size_t i;
+ /* data_len_bytes - only multiples of 4 are considered, rest is truncated */
+ for( i = 0; i < data_len_bytes >> 2; i++ )
+ {
+ result ^= ( (uint32_t*) data )[i];
+ }
+ return result;
+}
+#endif
+
unsigned char* mbedtls_platform_put_uint32_be( unsigned char *buf,
size_t num )
{
diff --git a/library/sha256.c b/library/sha256.c
index 52145918b..c2a20d2cc 100644
--- a/library/sha256.c
+++ b/library/sha256.c
@@ -281,7 +281,9 @@ int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx,
if( flow_ctrl == 8 )
{
- return( 0 );
+ mbedtls_platform_random_delay();
+ if( flow_ctrl == 8 )
+ return( 0 );
}
/* Free the ctx upon suspected FI */
mbedtls_sha256_free( ctx );
@@ -355,6 +357,7 @@ int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx,
/* Re-check ilen_dup to protect from a FI attack */
if( ilen_dup < 64 )
{
+ mbedtls_platform_random_delay();
/* Re-check that the calculated offsets are correct */
ilen_change = ilen - ilen_dup;
if( ( input_dup + ilen_change ) == input )
@@ -458,7 +461,9 @@ int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx,
/* flow ctrl was incremented twice and then 7 times in two loops */
if( flow_ctrl == 9 )
{
- return( 0 );
+ mbedtls_platform_random_delay();
+ if( flow_ctrl == 9 )
+ return( 0 );
}
/* Free the ctx and clear output upon suspected FI */
mbedtls_sha256_free( ctx );
@@ -509,7 +514,9 @@ exit:
if( input_dup == input && ilen_dup == ilen )
{
- return( ret );
+ mbedtls_platform_random_delay();
+ if( input_dup == input && ilen_dup == ilen )
+ return( ret );
}
mbedtls_platform_memset( output, 0, 32 );
return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index e2c24e28a..22429e1b5 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -683,7 +683,7 @@ static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl,
*/
static int ssl_generate_random( mbedtls_ssl_context *ssl )
{
- int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
unsigned char *p = ssl->handshake->randbytes;
#if defined(MBEDTLS_HAVE_TIME)
mbedtls_time_t t;
@@ -838,7 +838,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
mbedtls_ssl_write_version( mbedtls_ssl_conf_get_max_major_ver( ssl->conf ),
mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ),
- ssl->conf->transport, p );
+ mbedtls_ssl_conf_get_transport( ssl->conf ), p );
p += 2;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]",
@@ -1141,11 +1141,17 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
- ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
- return( ret );
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ mbedtls_ssl_immediate_flight_done( ssl );
+#else
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -1541,7 +1547,8 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
* } HelloVerifyRequest;
*/
MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
- mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p );
+ mbedtls_ssl_read_version( &major_ver, &minor_ver,
+ mbedtls_ssl_conf_get_transport( ssl->conf ), p );
p += 2;
/*
@@ -1704,7 +1711,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 );
mbedtls_ssl_read_version( &major_ver, &minor_ver,
- ssl->conf->transport,
+ mbedtls_ssl_conf_get_transport( ssl->conf ),
buf + 0 );
if( mbedtls_ssl_ver_lt( major_ver,
@@ -2379,7 +2386,7 @@ static int ssl_rsa_generate_partial_pms( mbedtls_ssl_context *ssl,
mbedtls_ssl_write_version( mbedtls_ssl_conf_get_max_major_ver( ssl->conf ),
mbedtls_ssl_conf_get_max_minor_ver( ssl->conf ),
- ssl->conf->transport, out );
+ mbedtls_ssl_conf_get_transport( ssl->conf ), out );
ret = mbedtls_ssl_conf_get_frng( ssl->conf )
( mbedtls_ssl_conf_get_prng( ssl->conf ), out + 2, 46 );
@@ -2794,6 +2801,7 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl,
* structural change to provide default flow assumes failure
*/
volatile int ret = 0;
+ volatile int ret_fi = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
unsigned char *p;
unsigned char *end;
@@ -2931,6 +2939,7 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl,
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
{
((void) ret);
+ ((void) ret_fi);
((void) p);
((void) end);
((void) ciphersuite_info);
@@ -2947,7 +2956,7 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl,
mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE;
unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl );
size_t params_len = p - params;
- void *rs_ctx = NULL;
+ void * volatile rs_ctx = NULL;
mbedtls_pk_context * peer_pk;
@@ -3100,7 +3109,16 @@ static int ssl_in_server_key_exchange_parse( mbedtls_ssl_context *ssl,
{
mbedtls_platform_random_delay();
- if( ret == 0 )
+ if( rs_ctx == NULL )
+ {
+ ret_fi = mbedtls_pk_verify_restartable( peer_pk,
+ md_alg, hash, hashlen, p, sig_len, rs_ctx );
+ }
+ else
+ {
+ ret_fi = 0;
+ }
+ if( ret == 0 && ret_fi == 0 )
{
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* We don't need the peer's public key anymore. Free it,
@@ -3581,7 +3599,7 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl,
size_t buflen,
size_t *olen )
{
- int ret;
+ int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
unsigned char *p, *end;
size_t n;
mbedtls_ssl_ciphersuite_handle_t ciphersuite_info =
@@ -3642,18 +3660,23 @@ static int ssl_out_client_key_exchange_write( mbedtls_ssl_context *ssl,
{
((void) n);
-
+ ((void) ret);
if( (size_t)( end - p ) < 2 * NUM_ECC_BYTES + 2 )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
*p++ = 2 * NUM_ECC_BYTES + 1;
*p++ = 0x04; /* uncompressed point presentation */
+#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION)
+ mbedtls_platform_memcpy( p, ssl->handshake->ecdh_publickey,
+ 2 * NUM_ECC_BYTES );
+#else
ret = uECC_make_key( p, ssl->handshake->ecdh_privkey );
if( ret == UECC_FAULT_DETECTED )
return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
if( ret != UECC_SUCCESS )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION && MBEDTLS_USE_TINYCRYPT */
p += 2 * NUM_ECC_BYTES;
}
else
@@ -4205,7 +4228,11 @@ static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )
*/
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
{
- int ret = 0;
+ int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+ void *rs_ctx = NULL;
+ int authmode;
+#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -4234,10 +4261,12 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
}
#endif
+ ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
switch( ssl->state )
{
case MBEDTLS_SSL_HELLO_REQUEST:
ssl->state = MBEDTLS_SSL_CLIENT_HELLO;
+ ret = 0;
break;
/*
@@ -4255,6 +4284,25 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
* ServerHelloDone
*/
case MBEDTLS_SSL_SERVER_HELLO:
+#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION) && defined(MBEDTLS_USE_TINYCRYPT)
+ {
+ volatile uint8_t ecdhe_computed = ssl->handshake->ecdhe_computed;
+ /* Make sure that the ECDHE pre-computation is only done once */
+ if( ecdhe_computed == 0 )
+ {
+ ret = uECC_make_key( ssl->handshake->ecdh_publickey, ssl->handshake->ecdh_privkey );
+ if( ret == UECC_FAULT_DETECTED )
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ if( ret != UECC_SUCCESS )
+ return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
+ ssl->handshake->ecdhe_computed = 1;
+ ecdhe_computed = 1;
+ }
+ if( ecdhe_computed == 0 || ssl->handshake->ecdhe_computed == 0 )
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
+#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION && MBEDTLS_USE_TINYCRYPT */
+
ret = ssl_parse_server_hello( ssl );
break;
@@ -4298,6 +4346,24 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
break;
case MBEDTLS_SSL_CLIENT_FINISHED:
+
+#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
+ authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
+ ? ssl->handshake->sni_authmode
+ : mbedtls_ssl_conf_get_authmode( ssl->conf );
+#else
+ authmode = mbedtls_ssl_conf_get_authmode( ssl->conf );
+#endif
+
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "execute delayed server certificate verification" ) );
+
+ ret = mbedtls_ssl_parse_delayed_certificate_verify( ssl, authmode,
+ ssl->session_negotiate->peer_cert, rs_ctx );
+ if( ret != 0 )
+ break;
+#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
+
ret = mbedtls_ssl_write_finished( ssl );
break;
@@ -4323,6 +4389,7 @@ int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl )
case MBEDTLS_SSL_FLUSH_BUFFERS:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) );
ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP;
+ ret = 0;
break;
case MBEDTLS_SSL_HANDSHAKE_WRAPUP:
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index ec0c21a6a..7ef263c49 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1468,7 +1468,8 @@ read_record_header:
MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]",
buf[1], buf[2] ) );
- mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 );
+ mbedtls_ssl_read_version( &major, &minor,
+ mbedtls_ssl_conf_get_transport( ssl->conf ), buf + 1 );
/* According to RFC 5246 Appendix E.1, the version here is typically
* "{03,00}, the lowest version number supported by the client, [or] the
@@ -1674,7 +1675,7 @@ read_record_header:
{
int minor_ver, major_ver;
mbedtls_ssl_read_version( &major_ver, &minor_ver,
- ssl->conf->transport,
+ mbedtls_ssl_conf_get_transport( ssl->conf ),
buf );
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
@@ -2703,7 +2704,7 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
* version looks like the most interoperable thing to do. */
mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ),
mbedtls_ssl_get_minor_ver( ssl ),
- ssl->conf->transport, p );
+ mbedtls_ssl_conf_get_transport( ssl->conf ), p );
MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 );
p += 2;
@@ -2742,11 +2743,17 @@ static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
- ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
- return( ret );
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ mbedtls_ssl_immediate_flight_done( ssl );
+#else
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -2797,7 +2804,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ),
mbedtls_ssl_get_minor_ver( ssl ),
- ssl->conf->transport, p );
+ mbedtls_ssl_conf_get_transport( ssl->conf ), p );
p += 2;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]",
@@ -3801,11 +3808,17 @@ static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
- ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
- return( ret );
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ mbedtls_ssl_immediate_flight_done( ssl );
+#else
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
+#endif
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
@@ -4001,7 +4014,7 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
ssl->handshake->max_minor_ver,
- ssl->conf->transport, ver );
+ mbedtls_ssl_conf_get_transport( ssl->conf ), ver );
/* Avoid data-dependent branches while checking for invalid
* padding, to protect against timing-based Bleichenbacher-type
@@ -4456,7 +4469,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
- volatile int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ volatile int ret_fi = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
size_t i, sig_len;
unsigned char hash[48];
unsigned char *hash_start = hash;
@@ -4643,14 +4657,17 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
}
ret = mbedtls_pk_verify( peer_pk,
- md_alg, hash_start, hashlen,
- ssl->in_msg + i, sig_len );
+ md_alg, hash_start, hashlen,
+ ssl->in_msg + i, sig_len );
if( ret == 0 )
{
mbedtls_platform_random_delay();
- if( ret == 0 )
+ ret_fi = mbedtls_pk_verify( peer_pk,
+ md_alg, hash_start, hashlen,
+ ssl->in_msg + i, sig_len );
+ if( ret == 0 && ret_fi == 0 )
{
mbedtls_ssl_update_handshake_status( ssl );
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 4ebfb5c93..6f152437f 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -35,6 +35,8 @@
#if defined(MBEDTLS_SSL_TLS_C)
+#include <stdint.h>
+
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
@@ -56,7 +58,68 @@
#include "mbedtls/oid.h"
#endif
-#define PROPER_HS_FRAGMENT 0x75555555
+#define PROPER_HS_FRAGMENT 0x75
+
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+static int mbedtls_ssl_switch_key( mbedtls_ssl_transform *transform,
+ const mbedtls_operation_t operation )
+{
+ unsigned char * key;
+ int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ volatile int flow_ctrl = 0;
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ uint32_t hash;
+#endif
+ if( operation == MBEDTLS_ENCRYPT )
+ {
+ flow_ctrl++;
+ key = transform->key_enc;
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ hash = transform->key_enc_hash;
+#endif
+ }
+ else if ( operation == MBEDTLS_DECRYPT )
+ {
+ flow_ctrl++;
+ key = transform->key_dec;
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ hash = transform->key_dec_hash;
+#endif
+ }
+ else
+ {
+ return ( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ /* Check hash */
+ if( hash != mbedtls_hash( key, transform->key_bitlen >> 3 ) )
+ {
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+ }
+ else
+ {
+ flow_ctrl++;
+ }
+#else
+ flow_ctrl++;
+#endif
+ if( operation != transform->cipher_ctx.operation )
+ {
+ if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx,
+ key,
+ transform->key_bitlen,
+ operation ) ) != 0 )
+ {
+ return( ret );
+ }
+ }
+ if( flow_ctrl == 2 )
+ {
+ return( 0 );
+ }
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
+}
+#endif
#if defined(MBEDTLS_USE_TINYCRYPT)
static int uecc_rng_wrapper( uint8_t *dest, unsigned int size )
@@ -371,11 +434,16 @@ static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl );
static size_t ssl_get_maximum_datagram_size( mbedtls_ssl_context const *ssl )
{
size_t mtu = ssl_get_current_mtu( ssl );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
- if( mtu != 0 && mtu < MBEDTLS_SSL_OUT_BUFFER_LEN )
+ if( mtu != 0 && mtu < out_buf_len )
return( mtu );
- return( MBEDTLS_SSL_OUT_BUFFER_LEN );
+ return( out_buf_len );
}
static int ssl_get_remaining_space_in_datagram( mbedtls_ssl_context const *ssl )
@@ -401,7 +469,7 @@ static int ssl_get_remaining_payload_in_datagram( mbedtls_ssl_context const *ssl
size_t max_len = MBEDTLS_SSL_OUT_CONTENT_LEN;
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+ const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
if( max_len > mfl )
max_len = mfl;
@@ -579,6 +647,95 @@ int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
return( 0 );
}
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+static int resize_buffer( unsigned char **buffer, size_t len_new, size_t *len_old )
+{
+ unsigned char* resized_buffer = mbedtls_calloc( 1, len_new );
+ if( resized_buffer == NULL )
+ return -1;
+
+ /* We want to copy len_new bytes when downsizing the buffer, and
+ * len_old bytes when upsizing, so we choose the smaller of two sizes,
+ * to fit one buffer into another. Size checks, ensuring that no data is
+ * lost, are done outside of this function. */
+ memcpy( resized_buffer, *buffer,
+ ( len_new < *len_old ) ? len_new : *len_old );
+ mbedtls_platform_zeroize( *buffer, *len_old );
+ mbedtls_free( *buffer );
+
+ *buffer = resized_buffer;
+ *len_old = len_new;
+
+ return 0;
+}
+
+#define BUFFER_UPSIZING 0
+#define BUFFER_DOWNSIZING 1
+static void handle_buffer_resizing( mbedtls_ssl_context *ssl, int downsizing,
+ uint32_t in_buf_new_len,
+ uint32_t out_buf_new_len )
+{
+ int modified = 0;
+ size_t written_in = 0, len_offset_in = 0;
+ size_t written_out = 0, iv_offset_out = 0, len_offset_out = 0;
+ if( ssl->in_buf != NULL )
+ {
+ written_in = ssl->in_msg - ssl->in_buf;
+ len_offset_in = ssl->in_len - ssl->in_buf;
+ if( ( downsizing && ssl->in_buf_len > in_buf_new_len && ssl->in_left < in_buf_new_len ) ||
+ ( !downsizing && ssl->in_buf_len < in_buf_new_len ) )
+ {
+ if( resize_buffer( &ssl->in_buf, in_buf_new_len, &ssl->in_buf_len ) != 0 )
+ {
+ /* No need to return an error here; The buffer will remain as
+ * is with no negative impact on the flow. */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "input buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating in_buf to %d", in_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+
+ if( ssl->out_buf != NULL )
+ {
+ written_out = ssl->out_msg - ssl->out_buf;
+ iv_offset_out = ssl->out_iv - ssl->out_buf;
+ len_offset_out = ssl->out_len - ssl->out_buf;
+ if( ( downsizing && ssl->out_buf_len > out_buf_new_len && ssl->out_left < out_buf_new_len ) ||
+ ( !downsizing && ssl->out_buf_len < out_buf_new_len ) )
+ {
+ if( resize_buffer( &ssl->out_buf, out_buf_new_len, &ssl->out_buf_len ) != 0 )
+ {
+ /* No need to return an error here; The buffer will remain as
+ * is with no negative impact on the flow. */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "output buffer resizing failed - out of memory" ) );
+ }
+ else
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "Reallocating out_buf to %d", out_buf_new_len ) );
+ modified = 1;
+ }
+ }
+ }
+ if( modified )
+ {
+ /* Update pointers here to avoid doing it twice. */
+ ssl_reset_in_out_pointers( ssl );
+ /* Fields below might not be properly updated with record
+ * splitting or with CID, so they are manually updated here. */
+ ssl->out_msg = ssl->out_buf + written_out;
+ ssl->out_len = ssl->out_buf + len_offset_out;
+ ssl->out_iv = ssl->out_buf + iv_offset_out;
+
+ ssl->in_msg = ssl->in_buf + written_in;
+ ssl->in_len = ssl->in_buf + len_offset_in;
+ }
+}
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
+
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl,
const unsigned char *key_enc, const unsigned char *key_dec,
@@ -776,8 +933,8 @@ int tls_prf_generic( mbedtls_md_type_t md_type,
{
size_t nb;
size_t i, j, k, md_len;
- unsigned char tmp[128];
- unsigned char h_i[MBEDTLS_MD_MAX_SIZE];
+ unsigned char tmp[128] = {0};
+ unsigned char h_i[MBEDTLS_MD_MAX_SIZE] = {0};
mbedtls_md_handle_t md_info;
mbedtls_md_context_t md_ctx;
int ret;
@@ -1278,7 +1435,8 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform,
#if !defined(MBEDTLS_SSL_HW_RECORD_ACCEL) && \
!defined(MBEDTLS_SSL_EXPORT_KEYS) && \
- !defined(MBEDTLS_DEBUG_C)
+ !defined(MBEDTLS_DEBUG_C) && \
+ !defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
ssl = NULL; /* make sure we don't use it except for those cases */
(void) ssl;
#endif
@@ -1563,7 +1721,31 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform,
iv_copy_len );
}
#endif
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx,
+ cipher_info ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+ return( ret );
+ }
+ transform->key_enc = mbedtls_calloc( 1, cipher_info->key_bitlen >> 3 );
+ transform->key_dec = mbedtls_calloc( 1, cipher_info->key_bitlen >> 3 );
+
+ if( transform->key_enc == NULL || transform->key_dec == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to allocate cipher keys" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+ memcpy( transform->key_enc, key1, cipher_info->key_bitlen >> 3 );
+ memcpy( transform->key_dec, key2, cipher_info->key_bitlen >> 3 );
+
+ transform->key_bitlen = cipher_info->key_bitlen;
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ transform->key_enc_hash = mbedtls_hash( transform->key_enc, transform->key_bitlen >> 3 );
+ transform->key_dec_hash = mbedtls_hash( transform->key_dec, transform->key_bitlen >> 3 );
+#endif
+#else
if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
cipher_info ) ) != 0 )
{
@@ -1593,10 +1775,18 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
return( ret );
}
-
+#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
if( cipher_info->mode == MBEDTLS_MODE_CBC )
{
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx,
+ MBEDTLS_PADDING_NONE ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
+ return( ret );
+ }
+#else
if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc,
MBEDTLS_PADDING_NONE ) ) != 0 )
{
@@ -1610,6 +1800,7 @@ int ssl_populate_transform( mbedtls_ssl_transform *transform,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret );
return( ret );
}
+#endif
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
@@ -2512,6 +2703,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ];
size_t add_data_len;
size_t post_avail;
+ int encryption_status = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
/* The SSL context is only used for debugging purposes! */
#if !defined(MBEDTLS_DEBUG_C)
@@ -2554,9 +2746,11 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
post_avail = rec->buf_len - ( rec->data_len + rec->data_offset );
MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload",
data, rec->data_len );
-
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx );
+#else
mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc );
-
+#endif
if( rec->data_len > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "Record content %u too large, maximum %d",
@@ -2671,8 +2865,15 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, "
"including %d bytes of padding",
rec->data_len, 0 ) );
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_ENCRYPT ) )
+ != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret );
+ return( ret );
+ }
- if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx,
transform->iv_enc, transform->ivlen,
data, rec->data_len,
data, &olen ) ) != 0 )
@@ -2680,7 +2881,16 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
return( ret );
}
-
+#else
+ if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ transform->iv_enc, transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+#endif
if( rec->data_len != olen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
@@ -2725,7 +2935,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
else if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
{
/* ChachaPoly: fixed XOR sequence number */
- unsigned char i;
+ uint_fast8_t i;
mbedtls_platform_memcpy( iv, transform->iv_enc, transform->fixed_ivlen );
@@ -2754,8 +2964,15 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
/*
* Encrypt and authenticate
*/
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_ENCRYPT ) )
+ != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret );
+ return( ret );
+ }
- if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
+ if( ( ret = encryption_status = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx,
iv, transform->ivlen,
add_data, add_data_len, /* add data */
data, rec->data_len, /* source */
@@ -2765,6 +2982,18 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
return( ret );
}
+#else
+ if( ( ret = encryption_status = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc,
+ iv, transform->ivlen,
+ add_data, add_data_len, /* add data */
+ data, rec->data_len, /* source */
+ data, &rec->data_len, /* destination */
+ data + rec->data_len, transform->taglen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
+ return( ret );
+ }
+#endif
MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag",
data + rec->data_len, transform->taglen );
@@ -2841,8 +3070,15 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
"including %d bytes of IV and %d bytes of padding",
rec->data_len, transform->ivlen,
padlen + 1 ) );
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_ENCRYPT ) )
+ != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret );
+ return( ret );
+ }
- if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx,
transform->iv_enc,
transform->ivlen,
data, rec->data_len,
@@ -2851,6 +3087,17 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
return( ret );
}
+#else
+ if( ( ret = encryption_status = mbedtls_cipher_crypt( &transform->cipher_ctx_enc,
+ transform->iv_enc,
+ transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+#endif
if( rec->data_len != olen )
{
@@ -2866,8 +3113,13 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
/*
* Save IV in SSL3 and TLS1
*/
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mbedtls_platform_memcpy( transform->iv_enc, transform->cipher_ctx.iv,
+ transform->ivlen );
+#else
mbedtls_platform_memcpy( transform->iv_enc, transform->cipher_ctx_enc.iv,
transform->ivlen );
+#endif
}
else
#endif
@@ -2935,7 +3187,11 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl,
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) );
- return( 0 );
+ if( encryption_status == 0 )
+ {
+ return( 0 );
+ }
+ return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
}
int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
@@ -2968,8 +3224,11 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
}
data = rec->buf + rec->data_offset;
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx );
+#else
mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec );
-
+#endif
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
/*
* Match record's CID with incoming CID.
@@ -2985,6 +3244,23 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
if( mode == MBEDTLS_MODE_STREAM )
{
padlen = 0;
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_DECRYPT ) )
+ != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret );
+ return( ret );
+ }
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx,
+ transform->iv_dec,
+ transform->ivlen,
+ data, rec->data_len,
+ data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+#else
if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
transform->iv_dec,
transform->ivlen,
@@ -2994,7 +3270,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
return( ret );
}
-
+#endif
if( rec->data_len != olen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
@@ -3044,7 +3320,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
if( transform->ivlen == 12 && transform->fixed_ivlen == 12 )
{
/* ChachaPoly: fixed XOR sequence number */
- unsigned char i;
+ uint_fast8_t i;
mbedtls_platform_memcpy( iv, transform->iv_dec, transform->fixed_ivlen );
@@ -3082,6 +3358,29 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
/*
* Decrypt and authenticate
*/
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_DECRYPT ) )
+ != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret );
+ return( ret );
+ }
+ if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx,
+ iv, transform->ivlen,
+ add_data, add_data_len,
+ data, rec->data_len,
+ data, &olen,
+ data + rec->data_len,
+ transform->taglen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
+
+ if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED )
+ return( MBEDTLS_ERR_SSL_INVALID_MAC );
+
+ return( ret );
+ }
+#else
if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec,
iv, transform->ivlen,
add_data, add_data_len,
@@ -3097,6 +3396,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
return( ret );
}
+#endif
+
auth_done++;
/* Double-check that AEAD decryption doesn't change content length. */
@@ -3239,7 +3540,22 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */
/* We still have data_len % ivlen == 0 and data_len >= ivlen here. */
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( ( ret = mbedtls_ssl_switch_key( transform, MBEDTLS_DECRYPT ) )
+ != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_switch_key", ret );
+ return( ret );
+ }
+ if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx,
+ transform->iv_dec, transform->ivlen,
+ data, rec->data_len, data, &olen ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
+ return( ret );
+ }
+#else
if( ( ret = mbedtls_cipher_crypt( &transform->cipher_ctx_dec,
transform->iv_dec, transform->ivlen,
data, rec->data_len, data, &olen ) ) != 0 )
@@ -3247,7 +3563,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret );
return( ret );
}
-
+#endif
/* Double-check that length hasn't changed during decryption. */
if( rec->data_len != olen )
{
@@ -3266,8 +3582,13 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context const *ssl,
* of the records; in other words, IVs are maintained across
* record decryptions.
*/
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mbedtls_platform_memcpy( transform->iv_dec, transform->cipher_ctx.iv,
+ transform->ivlen );
+#else
mbedtls_platform_memcpy( transform->iv_dec, transform->cipher_ctx_dec.iv,
transform->ivlen );
+#endif
}
#endif
@@ -3591,6 +3912,11 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
ptrdiff_t bytes_written = ssl->out_msg - ssl->out_buf;
size_t len_pre = ssl->out_msglen;
unsigned char *msg_pre = ssl->compress_buf;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) );
@@ -3608,7 +3934,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
ssl->transform_out->ctx_deflate.next_in = msg_pre;
ssl->transform_out->ctx_deflate.avail_in = len_pre;
ssl->transform_out->ctx_deflate.next_out = msg_post;
- ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_OUT_BUFFER_LEN - bytes_written;
+ ssl->transform_out->ctx_deflate.avail_out = out_buf_len - bytes_written;
ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH );
if( ret != Z_OK )
@@ -3617,7 +3943,7 @@ static int ssl_compress_buf( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
}
- ssl->out_msglen = MBEDTLS_SSL_OUT_BUFFER_LEN -
+ ssl->out_msglen = out_buf_len -
ssl->transform_out->ctx_deflate.avail_out - bytes_written;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ",
@@ -3638,6 +3964,11 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
ptrdiff_t header_bytes = ssl->in_msg - ssl->in_buf;
size_t len_pre = ssl->in_msglen;
unsigned char *msg_pre = ssl->compress_buf;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) );
@@ -3655,7 +3986,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
ssl->transform_in->ctx_inflate.next_in = msg_pre;
ssl->transform_in->ctx_inflate.avail_in = len_pre;
ssl->transform_in->ctx_inflate.next_out = msg_post;
- ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_IN_BUFFER_LEN -
+ ssl->transform_in->ctx_inflate.avail_out = in_buf_len -
header_bytes;
ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH );
@@ -3665,7 +3996,7 @@ static int ssl_decompress_buf( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED );
}
- ssl->in_msglen = MBEDTLS_SSL_IN_BUFFER_LEN -
+ ssl->in_msglen = in_buf_len -
ssl->transform_in->ctx_inflate.avail_out - header_bytes;
MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ",
@@ -3693,7 +4024,7 @@ static int ssl_resend_hello_request( mbedtls_ssl_context *ssl )
uint32_t ratio =
mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) /
mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) + 1;
- unsigned char doublings = 1;
+ int_fast8_t doublings = 1;
while( ratio != 0 )
{
@@ -3732,6 +4063,11 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
{
int ret;
size_t len;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) );
@@ -3743,7 +4079,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- if( nb_want > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) )
+ if( nb_want > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -3830,7 +4166,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want )
}
else
{
- len = MBEDTLS_SSL_IN_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf );
+ len = in_buf_len - ( ssl->in_hdr - ssl->in_buf );
if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
timeout = ssl->handshake->retransmit_timeout;
@@ -4025,6 +4361,131 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl )
* Functions to handle the DTLS retransmission state machine
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
+static int ssl_swap_epochs( mbedtls_ssl_context *ssl );
+
+static int mbedtls_ssl_flight_transmit_msg( mbedtls_ssl_context *ssl, mbedtls_ssl_flight_item *msg )
+{
+ size_t max_frag_len;
+ int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ int const is_retransmitting =
+ ( ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING );
+ int const is_finished =
+ ( msg->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
+ msg->p[0] == MBEDTLS_SSL_HS_FINISHED );
+
+ uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
+ SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
+
+ /* Swap epochs before sending Finished: we can't do it after
+ * sending ChangeCipherSpec, in case write returns WANT_READ.
+ * Must be done before copying, may change out_msg pointer */
+ if( is_retransmitting && is_finished && ssl->handshake->cur_msg_p == ( msg->p + 12 ) )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
+ }
+
+ ret = ssl_get_remaining_payload_in_datagram( ssl );
+ if( ret < 0 )
+ return( ret );
+ max_frag_len = (size_t) ret;
+
+ /* CCS is copied as is, while HS messages may need fragmentation */
+ if( msg->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
+ {
+ if( max_frag_len == 0 )
+ {
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+ }
+
+ mbedtls_platform_memcpy( ssl->out_msg, msg->p, msg->len );
+ ssl->out_msglen = msg->len;
+ ssl->out_msgtype = msg->type;
+
+ /* Update position inside current message */
+ ssl->handshake->cur_msg_p += msg->len;
+ }
+ else
+ {
+ const unsigned char * const p = ssl->handshake->cur_msg_p;
+ const size_t hs_len = msg->len - 12;
+ const size_t frag_off = p - ( msg->p + 12 );
+ const size_t rem_len = hs_len - frag_off;
+ size_t cur_hs_frag_len, max_hs_frag_len;
+
+ if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
+ {
+ if( is_finished && is_retransmitting )
+ {
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
+ }
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+
+ return( 0 );
+ }
+ max_hs_frag_len = max_frag_len - 12;
+
+ cur_hs_frag_len = rem_len > max_hs_frag_len ?
+ max_hs_frag_len : rem_len;
+
+ if( frag_off == 0 && cur_hs_frag_len != hs_len )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
+ (unsigned) cur_hs_frag_len,
+ (unsigned) max_hs_frag_len ) );
+ }
+
+ /* Messages are stored with handshake headers as if not fragmented,
+ * copy beginning of headers then fill fragmentation fields.
+ * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
+ mbedtls_platform_memcpy( ssl->out_msg, msg->p, 6 );
+
+ (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[6], frag_off );
+ (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[9],
+ cur_hs_frag_len );
+
+ MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
+
+ /* Copy the handshake message content and set records fields */
+ mbedtls_platform_memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
+ ssl->out_msglen = cur_hs_frag_len + 12;
+ ssl->out_msgtype = msg->type;
+
+ /* Update position inside current message */
+ ssl->handshake->cur_msg_p += cur_hs_frag_len;
+ }
+
+ /* If done with the current message move to the next one if any */
+ if( ssl->handshake->cur_msg_p >= msg->p + msg->len )
+ {
+ if( msg->next != NULL )
+ {
+ ssl->handshake->cur_msg = msg->next;
+ ssl->handshake->cur_msg_p = msg->next->p + 12;
+ }
+ else
+ {
+ ssl->handshake->cur_msg = NULL;
+ ssl->handshake->cur_msg_p = NULL;
+ }
+ }
+
+ /* Actually send the message out */
+ if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ return( ret );
+ }
+ return( ret );
+}
+
/*
* Append current handshake message to current outgoing flight
*/
@@ -4067,6 +4528,24 @@ static int ssl_flight_append( mbedtls_ssl_context *ssl )
cur->next = msg;
}
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ ssl->handshake->cur_msg = msg;
+ ssl->handshake->cur_msg_p = msg->p + 12;
+ {
+ int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ while( ssl->handshake->cur_msg != NULL )
+ {
+ if( ( ret = mbedtls_ssl_flight_transmit_msg( ssl, ssl->handshake->cur_msg ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit_msg", ret );
+ return( ret );
+ }
+
+ if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
+ return( ret );
+ }
+ }
+#endif
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= ssl_flight_append" ) );
return( 0 );
}
@@ -4156,6 +4635,24 @@ int mbedtls_ssl_resend( mbedtls_ssl_context *ssl )
return( ret );
}
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+void mbedtls_ssl_immediate_flight_done( mbedtls_ssl_context *ssl )
+{
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_immediate_flight_done" ) );
+
+ /* Update state and set timer */
+ if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER )
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED;
+ else
+ {
+ ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING;
+ ssl_set_timer( ssl, ssl->handshake->retransmit_timeout );
+ }
+
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_immediate_flight_done" ) );
+}
+#endif
+
/*
* Transmit or retransmit the current flight of messages.
*
@@ -4182,121 +4679,9 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
while( ssl->handshake->cur_msg != NULL )
{
- size_t max_frag_len;
- const mbedtls_ssl_flight_item * const cur = ssl->handshake->cur_msg;
-
- int const is_finished =
- ( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE &&
- cur->p[0] == MBEDTLS_SSL_HS_FINISHED );
-
- uint8_t const force_flush = ssl->disable_datagram_packing == 1 ?
- SSL_FORCE_FLUSH : SSL_DONT_FORCE_FLUSH;
-
- /* Swap epochs before sending Finished: we can't do it after
- * sending ChangeCipherSpec, in case write returns WANT_READ.
- * Must be done before copying, may change out_msg pointer */
- if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
- }
-
- ret = ssl_get_remaining_payload_in_datagram( ssl );
- if( ret < 0 )
- return( ret );
- max_frag_len = (size_t) ret;
-
- /* CCS is copied as is, while HS messages may need fragmentation */
- if( cur->type == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC )
- {
- if( max_frag_len == 0 )
- {
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- continue;
- }
-
- mbedtls_platform_memcpy( ssl->out_msg, cur->p, cur->len );
- ssl->out_msglen = cur->len;
- ssl->out_msgtype = cur->type;
-
- /* Update position inside current message */
- ssl->handshake->cur_msg_p += cur->len;
- }
- else
- {
- const unsigned char * const p = ssl->handshake->cur_msg_p;
- const size_t hs_len = cur->len - 12;
- const size_t frag_off = p - ( cur->p + 12 );
- const size_t rem_len = hs_len - frag_off;
- size_t cur_hs_frag_len, max_hs_frag_len;
-
- if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
- {
- if( is_finished )
- {
- if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
- return( ret );
- }
-
- if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
- return( ret );
-
- continue;
- }
- max_hs_frag_len = max_frag_len - 12;
-
- cur_hs_frag_len = rem_len > max_hs_frag_len ?
- max_hs_frag_len : rem_len;
-
- if( frag_off == 0 && cur_hs_frag_len != hs_len )
- {
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "fragmenting handshake message (%u > %u)",
- (unsigned) cur_hs_frag_len,
- (unsigned) max_hs_frag_len ) );
- }
-
- /* Messages are stored with handshake headers as if not fragmented,
- * copy beginning of headers then fill fragmentation fields.
- * Handshake headers: type(1) len(3) seq(2) f_off(3) f_len(3) */
- mbedtls_platform_memcpy( ssl->out_msg, cur->p, 6 );
-
- (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[6], frag_off );
- (void)mbedtls_platform_put_uint24_be( &ssl->out_msg[9],
- cur_hs_frag_len );
-
- MBEDTLS_SSL_DEBUG_BUF( 3, "handshake header", ssl->out_msg, 12 );
-
- /* Copy the handshake message content and set records fields */
- mbedtls_platform_memcpy( ssl->out_msg + 12, p, cur_hs_frag_len );
- ssl->out_msglen = cur_hs_frag_len + 12;
- ssl->out_msgtype = cur->type;
-
- /* Update position inside current message */
- ssl->handshake->cur_msg_p += cur_hs_frag_len;
- }
-
- /* If done with the current message move to the next one if any */
- if( ssl->handshake->cur_msg_p >= cur->p + cur->len )
+ if( ( ret = mbedtls_ssl_flight_transmit_msg( ssl, ssl->handshake->cur_msg ) ) != 0 )
{
- if( cur->next != NULL )
- {
- ssl->handshake->cur_msg = cur->next;
- ssl->handshake->cur_msg_p = cur->next->p + 12;
- }
- else
- {
- ssl->handshake->cur_msg = NULL;
- ssl->handshake->cur_msg_p = NULL;
- }
- }
-
- /* Actually send the message out */
- if( ( ret = mbedtls_ssl_write_record( ssl, force_flush ) ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret );
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit_msg", ret );
return( ret );
}
}
@@ -4315,7 +4700,7 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_flight_transmit" ) );
- return( 0 );
+ return( ret );
}
/*
@@ -4602,13 +4987,19 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
unsigned i;
size_t protected_record_size;
volatile int encrypted_fi = 0;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
/* Skip writing the record content type to after the encryption,
* as it may change when using the CID extension. */
mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ),
mbedtls_ssl_get_minor_ver( ssl ),
- ssl->conf->transport, ssl->out_hdr + 1 );
+ mbedtls_ssl_conf_get_transport( ssl->conf ),
+ ssl->out_hdr + 1 );
mbedtls_platform_memcpy( ssl->out_ctr, ssl->cur_out_ctr, 8 );
(void)mbedtls_platform_put_uint16_be( ssl->out_len, len );
@@ -4618,15 +5009,15 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush )
mbedtls_record rec;
rec.buf = ssl->out_iv;
- rec.buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN -
- ( ssl->out_iv - ssl->out_buf );
+ rec.buf_len = out_buf_len - ( ssl->out_iv - ssl->out_buf );
rec.data_len = ssl->out_msglen;
rec.data_offset = ssl->out_msg - rec.buf;
mbedtls_platform_memcpy( &rec.ctr[0], ssl->out_ctr, 8 );
mbedtls_ssl_write_version( mbedtls_ssl_get_major_ver( ssl ),
mbedtls_ssl_get_minor_ver( ssl ),
- ssl->conf->transport, rec.ver );
+ mbedtls_ssl_conf_get_transport( ssl->conf ),
+ rec.ver );
rec.type = ssl->out_msgtype;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
@@ -5478,7 +5869,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context const *ssl,
rec->ver[0] = buf[ rec_hdr_version_offset + 0 ];
rec->ver[1] = buf[ rec_hdr_version_offset + 1 ];
mbedtls_ssl_read_version( &major_ver, &minor_ver,
- ssl->conf->transport,
+ mbedtls_ssl_conf_get_transport( ssl->conf ),
&rec->ver[0] );
if( major_ver != mbedtls_ssl_get_major_ver( ssl ) )
@@ -6344,6 +6735,11 @@ static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
unsigned char * rec;
size_t rec_len;
unsigned rec_epoch;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
return( 0 );
@@ -6374,8 +6770,7 @@ static int ssl_load_buffered_record( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "Found buffered record from current epoch - load" ) );
/* Double-check that the record is not too large */
- if( rec_len > MBEDTLS_SSL_IN_BUFFER_LEN -
- (size_t)( ssl->in_hdr - ssl->in_buf ) )
+ if( rec_len > in_buf_len - (size_t)( ssl->in_hdr - ssl->in_buf ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
@@ -7627,6 +8022,26 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl,
return( verify_ret );
}
+
+#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+/* mbedtls_ssl_parse_delayed_certificate_verify() defines a wrapper around ssl_parse_certificate_verify
+ * to call it in ssl_cli.c rather than purely internal to ssl_tls.c.
+ */
+int mbedtls_ssl_parse_delayed_certificate_verify( mbedtls_ssl_context *ssl,
+ int authmode,
+ mbedtls_x509_crt *chain,
+ void *rs_ctx )
+{
+
+ return( ssl_parse_certificate_verify( ssl,
+ authmode,
+ chain,
+ rs_ctx ) );
+
+}
+#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED && MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
+
+
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
#if defined(MBEDTLS_SSL_RENEGOTIATION)
@@ -7684,8 +8099,10 @@ static int ssl_remember_peer_pubkey( mbedtls_ssl_context *ssl,
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
- int ret = 0;
- int crt_expected;
+ volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ volatile int ret_verify = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
+ volatile int check_cert_initiated = 0;
+ volatile int crt_expected = SSL_CERTIFICATE_EXPECTED;
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
? ssl->handshake->sni_authmode
@@ -7701,8 +8118,14 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
if( crt_expected == SSL_CERTIFICATE_SKIP )
{
- MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
- goto exit;
+ mbedtls_platform_random_delay();
+ crt_expected = ssl_parse_certificate_coordinate( ssl, authmode );
+ if( crt_expected == SSL_CERTIFICATE_SKIP )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
+ ret = 0;
+ goto exit;
+ }
}
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
@@ -7763,14 +8186,29 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
ssl->handshake->ecrs_state = ssl_ecrs_crt_verify;
crt_verify:
+ check_cert_initiated = 1;
if( ssl->handshake->ecrs_enabled)
rs_ctx = &ssl->handshake->ecrs_ctx;
#endif
- ret = ssl_parse_certificate_verify( ssl, authmode,
- chain, rs_ctx );
- if( ret != 0 )
- goto exit;
+#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+ if ( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "delay server certificate verification" ) );
+ check_cert_initiated = 0;
+ ret = 0;
+ }
+ else
+#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
+ {
+ ret_verify = ssl_parse_certificate_verify( ssl, authmode,
+ chain, rs_ctx );
+ ret = ret_verify;
+ if( ret_verify != 0 )
+ {
+ goto exit;
+ }
+ }
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
{
@@ -7819,6 +8257,10 @@ crt_verify:
exit:
+ if( check_cert_initiated && ( ret == 0 ) )
+ {
+ ret = ret_verify;
+ }
if( ret == 0 )
{
if( ssl->state == MBEDTLS_SSL_CLIENT_CERTIFICATE )
@@ -8263,7 +8705,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_PROTO_DTLS)
if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
- unsigned char i;
+ uint_fast8_t i;
/* Remember current epoch settings for resending */
ssl->handshake->alt_transform_out = ssl->transform_out;
@@ -8318,13 +8760,19 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
- ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
- MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
- return( ret );
- }
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ mbedtls_ssl_immediate_flight_done( ssl );
+#else
+ if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
+ return( ret );
+ }
#endif
+ }
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) );
@@ -8495,9 +8943,12 @@ static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake )
void mbedtls_ssl_transform_init( mbedtls_ssl_transform *transform )
{
memset( transform, 0, sizeof(mbedtls_ssl_transform) );
-
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mbedtls_cipher_init( &transform->cipher_ctx );
+#else
mbedtls_cipher_init( &transform->cipher_ctx_enc );
mbedtls_cipher_init( &transform->cipher_ctx_dec );
+#endif
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
mbedtls_md_init( &transform->md_ctx_enc );
@@ -8539,6 +8990,12 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) );
}
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ /* If the buffers are too small - reallocate */
+ handle_buffer_resizing( ssl, BUFFER_UPSIZING, MBEDTLS_SSL_IN_BUFFER_LEN,
+ MBEDTLS_SSL_OUT_BUFFER_LEN );
+#endif
+
/* All pointers should exist and can be directly freed without issue */
if( ssl->handshake == NULL ||
ssl->transform_negotiate == NULL ||
@@ -8744,6 +9201,8 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
const mbedtls_ssl_config *conf )
{
int ret;
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
ssl->conf = conf;
@@ -8758,18 +9217,25 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl,
/* Set to NULL in case of an error condition */
ssl->out_buf = NULL;
- ssl->in_buf = mbedtls_calloc( 1, MBEDTLS_SSL_IN_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->in_buf_len = in_buf_len;
+#endif
+ ssl->in_buf = mbedtls_calloc( 1, in_buf_len );
if( ssl->in_buf == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_IN_BUFFER_LEN) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", in_buf_len) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
- ssl->out_buf = mbedtls_calloc( 1, MBEDTLS_SSL_OUT_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->out_buf_len = out_buf_len;
+#endif
+
+ ssl->out_buf = mbedtls_calloc( 1, out_buf_len );
if( ssl->out_buf == NULL )
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", MBEDTLS_SSL_OUT_BUFFER_LEN) );
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", out_buf_len) );
ret = MBEDTLS_ERR_SSL_ALLOC_FAILED;
goto error;
}
@@ -8789,6 +9255,11 @@ error:
ssl->conf = NULL;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ ssl->in_buf_len = 0;
+ ssl->out_buf_len = 0;
+#endif
+
ssl->in_buf = NULL;
ssl->out_buf = NULL;
@@ -8816,6 +9287,13 @@ error:
static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
{
int ret;
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
#if !defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) || \
!defined(MBEDTLS_SSL_SRV_C)
@@ -8871,14 +9349,14 @@ static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial )
ssl->session_in = NULL;
ssl->session_out = NULL;
- mbedtls_platform_memset( ssl->out_buf, 0, MBEDTLS_SSL_OUT_BUFFER_LEN );
+ mbedtls_platform_memset( ssl->out_buf, 0, out_buf_len );
#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C)
if( partial == 0 )
#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */
{
ssl->in_left = 0;
- mbedtls_platform_memset( ssl->in_buf, 0, MBEDTLS_SSL_IN_BUFFER_LEN );
+ mbedtls_platform_memset( ssl->in_buf, 0, in_buf_len );
}
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
@@ -8947,10 +9425,12 @@ void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint )
}
#endif /* MBEDTLS_SSL_CONF_ENDPOINT */
+#if !defined(MBEDTLS_SSL_CONF_TRANSPORT)
void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
{
conf->transport = transport;
}
+#endif /* MBEDTLS_SSL_CONF_TRANSPORT */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \
!defined(MBEDTLS_SSL_CONF_ANTI_REPLAY)
@@ -9866,8 +10346,11 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL )
return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
#endif
-
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx ) )
+#else
switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) )
+#endif
{
#if defined(MBEDTLS_GCM_C) || \
defined(MBEDTLS_CCM_C) || \
@@ -9898,10 +10381,13 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
case MBEDTLS_MODE_CBC:
{
size_t block_size;
-
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ block_size = mbedtls_cipher_get_block_size(
+ &transform->cipher_ctx );
+#else
block_size = mbedtls_cipher_get_block_size(
&transform->cipher_ctx_enc );
-
+#endif
/* Expansion due to the addition of the MAC. */
transform_expansion += transform->maclen;
@@ -9939,7 +10425,42 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl )
}
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
-size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+size_t mbedtls_ssl_get_input_max_frag_len( const mbedtls_ssl_context *ssl )
+{
+ size_t max_len = MBEDTLS_SSL_MAX_CONTENT_LEN;
+ size_t read_mfl;
+
+ /* Use the configured MFL for the client if we're past SERVER_HELLO_DONE */
+ if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT &&
+ ssl->state >= MBEDTLS_SSL_SERVER_HELLO_DONE )
+ {
+ return ssl_mfl_code_to_length( ssl->conf->mfl_code );
+ }
+
+ /* Check if a smaller max length was negotiated */
+ if( ssl->session_out != NULL )
+ {
+ read_mfl = ssl_mfl_code_to_length( ssl->session_out->mfl_code );
+ if( read_mfl < max_len )
+ {
+ max_len = read_mfl;
+ }
+ }
+
+ // During a handshake, use the value being negotiated
+ if( ssl->session_negotiate != NULL )
+ {
+ read_mfl = ssl_mfl_code_to_length( ssl->session_negotiate->mfl_code );
+ if( read_mfl < max_len )
+ {
+ max_len = read_mfl;
+ }
+ }
+
+ return( max_len );
+}
+
+size_t mbedtls_ssl_get_output_max_frag_len( const mbedtls_ssl_context *ssl )
{
size_t max_len;
@@ -9964,6 +10485,13 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
return( max_len );
}
+
+#if !defined(MBEDTLS_DEPRECATED_REMOVED)
+size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl )
+{
+ return mbedtls_ssl_get_output_max_frag_len( ssl );
+}
+#endif /* !MBEDTLS_DEPRECATED_REMOVED */
#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
@@ -9996,7 +10524,7 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl )
#endif
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- const size_t mfl = mbedtls_ssl_get_max_frag_len( ssl );
+ const size_t mfl = mbedtls_ssl_get_output_max_frag_len( ssl );
if( max_len > mfl )
max_len = mfl;
@@ -11260,7 +11788,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len )
static int ssl_write_real( mbedtls_ssl_context *ssl,
const unsigned char *buf, size_t len )
{
- int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
+ volatile int ret = mbedtls_ssl_get_max_out_record_payload( ssl );
const size_t max_len = (size_t) ret;
if( ret < 0 )
@@ -11371,8 +11899,13 @@ static int ssl_write_split( mbedtls_ssl_context *ssl,
mbedtls_ssl_ver_gt(
mbedtls_ssl_get_minor_ver( ssl ),
MBEDTLS_SSL_MINOR_VERSION_1 ) ||
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx )
+ != MBEDTLS_MODE_CBC )
+#else
mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc )
!= MBEDTLS_MODE_CBC )
+#endif
{
return( ssl_write_real( ssl, buf, len ) );
}
@@ -11486,10 +12019,16 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform )
deflateEnd( &transform->ctx_deflate );
inflateEnd( &transform->ctx_inflate );
#endif
-
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ mbedtls_cipher_free( &transform->cipher_ctx );
+ if( transform->key_dec != NULL )
+ mbedtls_free( transform->key_dec );
+ if( transform->key_enc != NULL )
+ mbedtls_free( transform->key_enc );
+#else
mbedtls_cipher_free( &transform->cipher_ctx_enc );
mbedtls_cipher_free( &transform->cipher_ctx_dec );
-
+#endif
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
mbedtls_md_free( &transform->md_ctx_enc );
mbedtls_md_free( &transform->md_ctx_dec );
@@ -11577,6 +12116,19 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
#endif
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
+#if defined(MBEDTLS_SSL_FREE_SERVER_CERTIFICATE) && \
+ defined(MBEDTLS_X509_CRT_PARSE_C) && \
+ defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
+ if( ssl->session_negotiate )
+ {
+ ssl_clear_peer_cert( ssl->session_negotiate );
+ }
+ if( ssl->session )
+ {
+ ssl_clear_peer_cert( ssl->session );
+ }
+#endif /* MBEDTLS_SSL_FREE_SERVER_CERTIFICATE */
+
#if defined(MBEDTLS_DHM_C)
mbedtls_dhm_free( &handshake->dhm_ctx );
#endif
@@ -11641,6 +12193,16 @@ void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
mbedtls_platform_zeroize( handshake,
sizeof( mbedtls_ssl_handshake_params ) );
+
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ /* If the buffers are too big - reallocate. Because of the way Mbed TLS
+ * processes datagrams and the fact that a datagram is allowed to have
+ * several records in it, it is possible that the I/O buffers are not
+ * empty at this stage */
+ handle_buffer_resizing( ssl, BUFFER_DOWNSIZING,
+ mbedtls_ssl_get_input_buflen( ssl ),
+ mbedtls_ssl_get_output_buflen( ssl ) );
+#endif
}
void mbedtls_ssl_session_free( mbedtls_ssl_session *session )
@@ -12256,14 +12818,26 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
if( ssl->out_buf != NULL )
{
- mbedtls_platform_zeroize( ssl->out_buf, MBEDTLS_SSL_OUT_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t out_buf_len = ssl->out_buf_len;
+#else
+ size_t out_buf_len = MBEDTLS_SSL_OUT_BUFFER_LEN;
+#endif
+ mbedtls_platform_zeroize( ssl->out_buf, out_buf_len );
mbedtls_free( ssl->out_buf );
+ ssl->out_buf = NULL;
}
if( ssl->in_buf != NULL )
{
- mbedtls_platform_zeroize( ssl->in_buf, MBEDTLS_SSL_IN_BUFFER_LEN );
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ size_t in_buf_len = ssl->in_buf_len;
+#else
+ size_t in_buf_len = MBEDTLS_SSL_IN_BUFFER_LEN;
+#endif
+ mbedtls_platform_zeroize( ssl->in_buf, in_buf_len );
mbedtls_free( ssl->in_buf );
+ ssl->in_buf = NULL;
}
#if defined(MBEDTLS_ZLIB_SUPPORT)
@@ -12331,8 +12905,10 @@ void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
memset( conf, 0, sizeof( mbedtls_ssl_config ) );
#if !defined(MBEDTLS_SSL_PROTO_TLS)
+#if !defined(MBEDTLS_SSL_CONF_TRANSPORT)
conf->transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
#endif
+#endif
}
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
@@ -12396,8 +12972,14 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
/* Use the functions here so that they are covered in tests,
* but otherwise access member directly for efficiency */
+#if !defined(MBEDTLS_SSL_CONF_ENDPOINT)
mbedtls_ssl_conf_endpoint( conf, endpoint );
+#endif
+#if !defined(MBEDTLS_SSL_CONF_TRANSPORT)
mbedtls_ssl_conf_transport( conf, transport );
+#else
+ ((void) transport);
+#endif
/*
* Things that are common to all presets
diff --git a/library/version_features.c b/library/version_features.c
index 84cb8a62b..c270c3a63 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -33,6 +33,9 @@
static const char *features[] = {
#if defined(MBEDTLS_VERSION_FEATURES)
+#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+ "MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION",
+#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
#if defined(MBEDTLS_HAVE_ASM)
"MBEDTLS_HAVE_ASM",
#endif /* MBEDTLS_HAVE_ASM */
@@ -273,9 +276,15 @@ static const char *features[] = {
#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
"MBEDTLS_AES_SCA_COUNTERMEASURES",
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
+#if defined(MBEDTLS_AES_128_BIT_MASKED)
+ "MBEDTLS_AES_128_BIT_MASKED",
+#endif /* MBEDTLS_AES_128_BIT_MASKED */
#if defined(MBEDTLS_FI_COUNTERMEASURES)
"MBEDTLS_FI_COUNTERMEASURES",
#endif /* MBEDTLS_FI_COUNTERMEASURES */
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ "MBEDTLS_CCM_SHUFFLING_MASKING",
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
"MBEDTLS_CAMELLIA_SMALL_MEMORY",
#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */
@@ -483,6 +492,15 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
"MBEDTLS_SSL_KEEP_PEER_CERTIFICATE",
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#if defined(MBEDTLS_SSL_FREE_SERVER_CERTIFICATE)
+ "MBEDTLS_SSL_FREE_SERVER_CERTIFICATE",
+#endif /* MBEDTLS_SSL_FREE_SERVER_CERTIFICATE */
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ "MBEDTLS_SSL_IMMEDIATE_TRANSMISSION",
+#endif /* MBEDTLS_SSL_IMMEDIATE_TRANSMISSION */
+#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION)
+ "MBEDTLS_SSL_EARLY_KEY_COMPUTATION",
+#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
"MBEDTLS_SSL_HW_RECORD_ACCEL",
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
@@ -555,6 +573,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT)
"MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT",
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH",
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
#if defined(MBEDTLS_THREADING_ALT)
"MBEDTLS_THREADING_ALT",
#endif /* MBEDTLS_THREADING_ALT */
@@ -678,6 +699,9 @@ static const char *features[] = {
#if defined(MBEDTLS_USE_TINYCRYPT)
"MBEDTLS_USE_TINYCRYPT",
#endif /* MBEDTLS_USE_TINYCRYPT */
+#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM)
+ "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM",
+#endif /* MBEDTLS_OPTIMIZE_TINYCRYPT_ASM */
#if defined(MBEDTLS_ENTROPY_C)
"MBEDTLS_ENTROPY_C",
#endif /* MBEDTLS_ENTROPY_C */
@@ -687,6 +711,9 @@ static const char *features[] = {
#if defined(MBEDTLS_CRC_C)
"MBEDTLS_CRC_C",
#endif /* MBEDTLS_CRC_C */
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ "MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY",
+#endif /* MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY */
#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
"MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY",
#endif /* MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY */
@@ -720,6 +747,9 @@ static const char *features[] = {
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
"MBEDTLS_MEMORY_BUFFER_ALLOC_C",
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
+#if defined(MBEDTLS_PLATFORM_FAULT_CALLBACKS)
+ "MBEDTLS_PLATFORM_FAULT_CALLBACKS",
+#endif /* MBEDTLS_PLATFORM_FAULT_CALLBACKS */
#if defined(MBEDTLS_NET_C)
"MBEDTLS_NET_C",
#endif /* MBEDTLS_NET_C */
@@ -792,6 +822,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_TLS_C)
"MBEDTLS_SSL_TLS_C",
#endif /* MBEDTLS_SSL_TLS_C */
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ "MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS",
+#endif /* MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS */
#if defined(MBEDTLS_THREADING_C)
"MBEDTLS_THREADING_C",
#endif /* MBEDTLS_THREADING_C */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 3b75bb5df..18db3b23f 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -2989,7 +2989,7 @@ static int x509_crt_find_parent_in(
for( parent_crt = candidates; parent_crt != NULL;
parent_crt = parent_crt->next )
{
- int parent_valid, parent_match, path_len_ok;
+ volatile int parent_valid, parent_match, path_len_ok;
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
check_signature:
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index af77ed553..4798f7ca7 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -130,6 +130,14 @@
int query_config( const char *config )
{
+#if defined(MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION)
+ if( strcmp( "MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION */
+
#if defined(MBEDTLS_HAVE_ASM)
if( strcmp( "MBEDTLS_HAVE_ASM", config ) == 0 )
{
@@ -770,6 +778,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
+#if defined(MBEDTLS_AES_128_BIT_MASKED)
+ if( strcmp( "MBEDTLS_AES_128_BIT_MASKED", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_AES_128_BIT_MASKED );
+ return( 0 );
+ }
+#endif /* MBEDTLS_AES_128_BIT_MASKED */
+
#if defined(MBEDTLS_FI_COUNTERMEASURES)
if( strcmp( "MBEDTLS_FI_COUNTERMEASURES", config ) == 0 )
{
@@ -778,6 +794,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_FI_COUNTERMEASURES */
+#if defined(MBEDTLS_CCM_SHUFFLING_MASKING)
+ if( strcmp( "MBEDTLS_CCM_SHUFFLING_MASKING", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_CCM_SHUFFLING_MASKING );
+ return( 0 );
+ }
+#endif /* MBEDTLS_CCM_SHUFFLING_MASKING */
+
#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY)
if( strcmp( "MBEDTLS_CAMELLIA_SMALL_MEMORY", config ) == 0 )
{
@@ -1330,6 +1354,30 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
+#if defined(MBEDTLS_SSL_FREE_SERVER_CERTIFICATE)
+ if( strcmp( "MBEDTLS_SSL_FREE_SERVER_CERTIFICATE", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_FREE_SERVER_CERTIFICATE );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_FREE_SERVER_CERTIFICATE */
+
+#if defined(MBEDTLS_SSL_IMMEDIATE_TRANSMISSION)
+ if( strcmp( "MBEDTLS_SSL_IMMEDIATE_TRANSMISSION", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_IMMEDIATE_TRANSMISSION );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_IMMEDIATE_TRANSMISSION */
+
+#if defined(MBEDTLS_SSL_EARLY_KEY_COMPUTATION)
+ if( strcmp( "MBEDTLS_SSL_EARLY_KEY_COMPUTATION", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_EARLY_KEY_COMPUTATION );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_EARLY_KEY_COMPUTATION */
+
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( strcmp( "MBEDTLS_SSL_HW_RECORD_ACCEL", config ) == 0 )
{
@@ -1522,6 +1570,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT */
+#if defined(MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH)
+ if( strcmp( "MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH */
+
#if defined(MBEDTLS_THREADING_ALT)
if( strcmp( "MBEDTLS_THREADING_ALT", config ) == 0 )
{
@@ -1850,6 +1906,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_USE_TINYCRYPT */
+#if defined(MBEDTLS_OPTIMIZE_TINYCRYPT_ASM)
+ if( strcmp( "MBEDTLS_OPTIMIZE_TINYCRYPT_ASM", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_OPTIMIZE_TINYCRYPT_ASM );
+ return( 0 );
+ }
+#endif /* MBEDTLS_OPTIMIZE_TINYCRYPT_ASM */
+
#if defined(MBEDTLS_ENTROPY_C)
if( strcmp( "MBEDTLS_ENTROPY_C", config ) == 0 )
{
@@ -1874,6 +1938,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_CRC_C */
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ if( strcmp( "MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY );
+ return( 0 );
+ }
+#endif /* MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY */
+
#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
if( strcmp( "MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY", config ) == 0 )
{
@@ -1962,6 +2034,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
+#if defined(MBEDTLS_PLATFORM_FAULT_CALLBACKS)
+ if( strcmp( "MBEDTLS_PLATFORM_FAULT_CALLBACKS", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_PLATFORM_FAULT_CALLBACKS );
+ return( 0 );
+ }
+#endif /* MBEDTLS_PLATFORM_FAULT_CALLBACKS */
+
#if defined(MBEDTLS_NET_C)
if( strcmp( "MBEDTLS_NET_C", config ) == 0 )
{
@@ -2154,6 +2234,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_TLS_C */
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ if( strcmp( "MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS */
+
#if defined(MBEDTLS_THREADING_C)
if( strcmp( "MBEDTLS_THREADING_C", config ) == 0 )
{
@@ -2746,6 +2834,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_CONF_ENDPOINT */
+#if defined(MBEDTLS_SSL_CONF_TRANSPORT)
+ if( strcmp( "MBEDTLS_SSL_CONF_TRANSPORT", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_TRANSPORT );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_CONF_TRANSPORT */
+
#if defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST)
if( strcmp( "MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST", config ) == 0 )
{
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 3bf9e6243..f6907f2b9 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -2332,8 +2332,10 @@ int main( int argc, char *argv[] )
mbedtls_printf( " [ Record expansion is unknown (compression) ]\n" );
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- mbedtls_printf( " [ Maximum fragment length is %u ]\n",
- (unsigned int) mbedtls_ssl_get_max_frag_len( ssl ) );
+ mbedtls_printf( " [ Maximum input fragment length is %u ]\n",
+ (unsigned int) mbedtls_ssl_get_input_max_frag_len( ssl ) );
+ mbedtls_printf( " [ Maximum output fragment length is %u ]\n",
+ (unsigned int) mbedtls_ssl_get_output_max_frag_len( ssl ) );
#endif
#if defined(MBEDTLS_SSL_ALPN)
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index bf10987df..952af41a8 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -1643,6 +1643,103 @@ int main( int argc, char *argv[] )
char *p, *q;
const int *list;
+#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
+ mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
+#if defined(MBEDTLS_MEMORY_DEBUG)
+ size_t current_heap_memory, peak_heap_memory, heap_blocks;
+#endif /* MBEDTLS_MEMORY_DEBUG */
+#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */
+
+ ssl = mbedtls_calloc( 1, sizeof( *ssl ) );
+ conf = mbedtls_calloc( 1, sizeof( *conf ) );
+ entropy = mbedtls_calloc( 1, sizeof( *entropy) );
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ cacert = mbedtls_calloc( 1, sizeof( *cacert ) );
+ srvcert = mbedtls_calloc( 1, sizeof( *srvcert ) );
+ pkey = mbedtls_calloc( 1, sizeof( *pkey ) );
+ srvcert2 = mbedtls_calloc( 1, sizeof( *srvcert2 ) );
+ pkey2 = mbedtls_calloc( 1, sizeof( *pkey2 ) );
+#endif
+#if defined(MBEDTLS_SSL_CACHE_C)
+ cache = mbedtls_calloc( 1, sizeof( *cache ) );
+#endif
+#if defined(MBEDTLS_TIMING_C)
+ timer = mbedtls_calloc( 1, sizeof( *timer ) );
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ ticket_ctx = mbedtls_calloc( 1, sizeof( *ticket_ctx ) );
+#endif
+#if defined(MBEDTLS_CTR_DRBG_C)
+ ctr_drbg = mbedtls_calloc( 1, sizeof( *ctr_drbg ) );
+#else
+ hmac_drbg = mbedtls_calloc( 1, sizeof( *hmac_drbg ) );
+#endif
+
+ if( ssl == NULL || conf == NULL ||
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ cacert == NULL || srvcert == NULL ||
+ pkey == NULL || srvcert2 == NULL ||
+ pkey2 == NULL ||
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ ticket_ctx == NULL ||
+#endif
+#if defined(MBEDTLS_SSL_CACHE_C)
+ cache == NULL ||
+#endif
+#if defined(MBEDTLS_TIMING_C)
+ timer == NULL ||
+#endif
+#if defined(MBEDTLS_CTR_DRBG_C)
+ ctr_drbg == NULL ||
+#else
+ hmac_drbg == NULL ||
+#endif
+ entropy == NULL)
+ {
+ mbedtls_printf( "Initial allocations failed!\n" );
+ goto exit;
+ }
+
+ /*
+ * Make sure memory references are valid in case we exit early.
+ */
+ mbedtls_net_init( &client_fd );
+ mbedtls_net_init( &listen_fd );
+ mbedtls_ssl_init( ssl );
+ mbedtls_ssl_config_init( conf );
+ mbedtls_entropy_init( entropy );
+#if defined(MBEDTLS_CTR_DRBG_C)
+ mbedtls_ctr_drbg_init( ctr_drbg );
+#else
+ mbedtls_hmac_drbg_init( hmac_drbg );
+#endif /* MBEDTLS_CTR_DRBG_C */
+#if defined(MBEDTLS_X509_CRT_PARSE_C)
+ mbedtls_x509_crt_init( cacert );
+ mbedtls_x509_crt_init( srvcert );
+ mbedtls_pk_init( pkey );
+ mbedtls_x509_crt_init( srvcert2 );
+ mbedtls_pk_init( pkey2 );
+#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
+ memset( &ssl_async_keys, 0, sizeof( ssl_async_keys ) );
+#endif
+#endif
+#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
+ mbedtls_dhm_init( &dhm );
+#endif
+#if defined(MBEDTLS_SSL_CACHE_C)
+ mbedtls_ssl_cache_init( cache );
+#endif
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+ mbedtls_ssl_ticket_init( ticket_ctx );
+#endif
+#if defined(MBEDTLS_SSL_ALPN)
+ memset( (void *) alpn_list, 0, sizeof( alpn_list ) );
+#endif
+#if defined(MBEDTLS_SSL_COOKIE_C)
+ mbedtls_ssl_cookie_init( &cookie_ctx );
+#endif
+
#if !defined(_WIN32)
/* Abort cleanly on SIGTERM and SIGINT */
signal( SIGTERM, term_handler );
@@ -2309,101 +2406,6 @@ int main( int argc, char *argv[] )
}
}
-
-#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
- mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
-#endif
-
- ssl = mbedtls_calloc( 1, sizeof( *ssl ) );
- conf = mbedtls_calloc( 1, sizeof( *conf ) );
- entropy = mbedtls_calloc( 1, sizeof( *entropy) );
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- cacert = mbedtls_calloc( 1, sizeof( *cacert ) );
- srvcert = mbedtls_calloc( 1, sizeof( *srvcert ) );
- pkey = mbedtls_calloc( 1, sizeof( *pkey ) );
- srvcert2 = mbedtls_calloc( 1, sizeof( *srvcert2 ) );
- pkey2 = mbedtls_calloc( 1, sizeof( *pkey2 ) );
-#endif
-#if defined(MBEDTLS_SSL_CACHE_C)
- cache = mbedtls_calloc( 1, sizeof( *cache ) );
-#endif
-#if defined(MBEDTLS_TIMING_C)
- timer = mbedtls_calloc( 1, sizeof( *timer ) );
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ticket_ctx = mbedtls_calloc( 1, sizeof( *ticket_ctx ) );
-#endif
-#if defined(MBEDTLS_CTR_DRBG_C)
- ctr_drbg = mbedtls_calloc( 1, sizeof( *ctr_drbg ) );
-#else
- hmac_drbg = mbedtls_calloc( 1, sizeof( *hmac_drbg ) );
-#endif
-
- if( ssl == NULL || conf == NULL ||
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- cacert == NULL || srvcert == NULL ||
- pkey == NULL || srvcert2 == NULL ||
- pkey2 == NULL ||
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- ticket_ctx == NULL ||
-#endif
-#if defined(MBEDTLS_SSL_CACHE_C)
- cache == NULL ||
-#endif
-#if defined(MBEDTLS_TIMING_C)
- timer == NULL ||
-#endif
-#if defined(MBEDTLS_CTR_DRBG_C)
- ctr_drbg == NULL ||
-#else
- hmac_drbg == NULL ||
-#endif
- entropy == NULL)
- {
- mbedtls_printf( "Initial allocations failed!\n" );
- goto exit;
- }
-
- /*
- * Make sure memory references are valid in case we exit early.
- */
- mbedtls_net_init( &client_fd );
- mbedtls_net_init( &listen_fd );
- mbedtls_ssl_init( ssl );
- mbedtls_ssl_config_init( conf );
- mbedtls_entropy_init( entropy );
-#if defined(MBEDTLS_CTR_DRBG_C)
- mbedtls_ctr_drbg_init( ctr_drbg );
-#else
- mbedtls_hmac_drbg_init( hmac_drbg );
-#endif /* MBEDTLS_CTR_DRBG_C */
-#if defined(MBEDTLS_X509_CRT_PARSE_C)
- mbedtls_x509_crt_init( cacert );
- mbedtls_x509_crt_init( srvcert );
- mbedtls_pk_init( pkey );
- mbedtls_x509_crt_init( srvcert2 );
- mbedtls_pk_init( pkey2 );
-#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
- memset( &ssl_async_keys, 0, sizeof( ssl_async_keys ) );
-#endif
-#endif
-#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
- mbedtls_dhm_init( &dhm );
-#endif
-#if defined(MBEDTLS_SSL_CACHE_C)
- mbedtls_ssl_cache_init( cache );
-#endif
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- mbedtls_ssl_ticket_init( ticket_ctx );
-#endif
-#if defined(MBEDTLS_SSL_ALPN)
- memset( (void *) alpn_list, 0, sizeof( alpn_list ) );
-#endif
-#if defined(MBEDTLS_SSL_COOKIE_C)
- mbedtls_ssl_cookie_init( &cookie_ctx );
-#endif
-
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
if( unhexify( cid, opt.cid_val, &cid_len ) != 0 )
{
@@ -3420,8 +3422,10 @@ handshake:
mbedtls_printf( " [ Record expansion is unknown (compression) ]\n" );
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
- mbedtls_printf( " [ Maximum fragment length is %u ]\n",
- (unsigned int) mbedtls_ssl_get_max_frag_len( ssl ) );
+ mbedtls_printf( " [ Maximum input fragment length is %u ]\n",
+ (unsigned int) mbedtls_ssl_get_input_max_frag_len( ssl ) );
+ mbedtls_printf( " [ Maximum output fragment length is %u ]\n",
+ (unsigned int) mbedtls_ssl_get_output_max_frag_len( ssl ) );
#endif
#if defined(MBEDTLS_SSL_ALPN)
@@ -3486,6 +3490,13 @@ handshake:
}
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
+#if defined(MBEDTLS_MEMORY_DEBUG)
+ mbedtls_memory_buffer_alloc_cur_get( &current_heap_memory, &heap_blocks );
+ mbedtls_memory_buffer_alloc_max_get( &peak_heap_memory, &heap_blocks );
+ mbedtls_printf( "Heap memory usage after handshake: %lu bytes. Peak memory usage was %lu\n",
+ (unsigned long) current_heap_memory, (unsigned long) peak_heap_memory );
+#endif /* MBEDTLS_MEMORY_DEBUG */
+
if( opt.exchanges == 0 )
goto close_notify;
diff --git a/scripts/baremetal.sh b/scripts/baremetal.sh
index 53ccedbb0..e2c0338d1 100755
--- a/scripts/baremetal.sh
+++ b/scripts/baremetal.sh
@@ -97,7 +97,7 @@ baremetal_build_gcc()
if [ $check -ne 0 ]; then
CFLAGS_BAREMETAL="$CFLAGS_BAREMETAL -Werror"
fi
- CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
+ CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG -DENABLE_TESTS"
echo "GCC version: $gcc_ver"
echo "Flags: $CFLAGS_BAREMETAL"
@@ -132,7 +132,7 @@ baremetal_build_armc5()
fi
CFLAGS_BAREMETAL="$OPTIM_CFLAGS_ARMC5 --thumb --cpu Cortex-m0plus"
- CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
+ CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG -DENABLE_TESTS"
WARNING_CFLAGS="--strict --c99"
if [ $check -ne 0 ]; then
@@ -175,7 +175,7 @@ baremetal_build_armc6()
if [ $check -ne 0 ]; then
CFLAGS_BAREMETAL="$CFLAGS_BAREMETAL -Werror"
fi
- CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
+ CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG -DENABLE_TESTS"
echo "ARMC6 version: $armc6_ver"
echo "Flags: $CFLAGS_BAREMETAL"
@@ -204,7 +204,7 @@ baremetal_ram_build() {
echo "Cleanup..."
make clean
- CFLAGS="$BASE_CFLAGS $CFLAGS_CONFIG $CFLAGS_USER_CONFIG"
+ CFLAGS="$BASE_CFLAGS $CFLAGS_CONFIG $CFLAGS_USER_CONFIG -DENABLE_TESTS"
if [ "$build_only" -eq 1 ]; then
CFLAGS="$CFLAGS -Werror"
fi
diff --git a/scripts/config.pl b/scripts/config.pl
index b63dc7766..6d6a470b9 100755
--- a/scripts/config.pl
+++ b/scripts/config.pl
@@ -57,6 +57,15 @@
# MBEDTLS_AES_ONLY_ENCRYPT
# MBEDTLS_AES_SCA_COUNTERMEASURES
# MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+# MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+# MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+# MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+# MBEDTLS_AES_128_BIT_MASKED
+# MBEDTLS_PLATFORM_FAULT_CALLBACKS
+# MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION
+# MBEDTLS_SSL_FREE_SERVER_CERTIFICATE
+# MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
+# MBEDTLS_SSL_EARLY_KEY_COMPUTATION
# and any symbol beginning _ALT
#
# The baremetal configuration excludes options that require a library or
@@ -140,6 +149,15 @@ MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH
MBEDTLS_AES_ONLY_ENCRYPT
MBEDTLS_AES_SCA_COUNTERMEASURES
MBEDTLS_CTR_DRBG_USE_128_BIT_KEY
+MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS
+MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY
+MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+MBEDTLS_AES_128_BIT_MASKED
+MBEDTLS_PLATFORM_FAULT_CALLBACKS
+MBEDTLS_SSL_DELAYED_SERVER_CERT_VERIFICATION
+MBEDTLS_SSL_FREE_SERVER_CERTIFICATE
+MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
+MBEDTLS_SSL_EARLY_KEY_COMPUTATION
_ALT\s*$
);
diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh
index 5439b854b..fd67349d3 100755
--- a/tests/scripts/all.sh
+++ b/tests/scripts/all.sh
@@ -1276,6 +1276,75 @@ component_test_no_max_fragment_length_small_ssl_out_content_len () {
if_build_succeeded tests/ssl-opt.sh -f "Max fragment length\|Large buffer"
}
+component_test_variable_ssl_in_out_buffer_len () {
+ msg "build: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled (ASan build)"
+ scripts/config.pl set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
+ make test
+
+ msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
+ if_build_succeeded tests/ssl-opt.sh
+
+ msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH enabled"
+ if_build_succeeded tests/compat.sh
+}
+
+component_test_variable_ssl_in_out_buffer_len_CID () {
+ msg "build: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled (ASan build)"
+ scripts/config.pl set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ scripts/config.pl set MBEDTLS_SSL_DTLS_CONNECTION_ID
+
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID"
+ make test
+
+ msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled"
+ if_build_succeeded tests/ssl-opt.sh
+
+ msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_DTLS_CONNECTION_ID enabled"
+ if_build_succeeded tests/compat.sh
+}
+
+component_test_variable_ssl_in_out_buffer_len_record_splitting () {
+ msg "build: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_CBC_RECORD_SPLITTING enabled (ASan build)"
+ scripts/config.pl set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ scripts/config.pl set MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+ CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
+ make
+
+ msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_CBC_RECORD_SPLITTING"
+ make test
+
+ msg "test: ssl-opt.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_CBC_RECORD_SPLITTING enabled"
+ if_build_succeeded tests/ssl-opt.sh
+
+ msg "test: compat.sh, MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH and MBEDTLS_SSL_CBC_RECORD_SPLITTING enabled"
+ if_build_succeeded tests/compat.sh
+}
+
+component_test_ssl_alloc_buffer_and_mfl () {
+ msg "build: default config with memory buffer allocator and MFL extension"
+ scripts/config.pl set MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ scripts/config.pl set MBEDTLS_PLATFORM_MEMORY
+ scripts/config.pl set MBEDTLS_MEMORY_DEBUG
+ scripts/config.pl set MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ scripts/config.pl set MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+ CC=gcc cmake .
+ make
+
+ msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH, MBEDTLS_MEMORY_BUFFER_ALLOC_C, MBEDTLS_MEMORY_DEBUG and MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
+ make test
+
+ msg "test: MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH, MBEDTLS_MEMORY_BUFFER_ALLOC_C, MBEDTLS_MEMORY_DEBUG and MBEDTLS_SSL_MAX_FRAGMENT_LENGTH"
+ if_build_succeeded tests/ssl-opt.sh -f "Handshake memory usage"
+}
+
component_test_when_no_ciphersuites_have_mac () {
msg "build: when no ciphersuites have MAC"
scripts/config.pl unset MBEDTLS_CIPHER_NULL_CIPHER
@@ -1634,15 +1703,21 @@ component_build_arm_none_eabi_gcc_no_64bit_multiplication () {
}
component_build_armcc () {
- msg "build: ARM Compiler 5"
+ msg "build: ARM Compiler 5 strict"
scripts/config.pl baremetal
make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib
- msg "size: ARM Compiler 5"
+ msg "size: ARM Compiler 5 strict"
"$ARMC5_FROMELF" -z library/*.o
make clean
+ msg "build: ARM Compiler 5 non strict"
+ make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--c99' lib
+
+ msg "size: ARM Compiler 5 non strict"
+ "$ARMC5_FROMELF" -z library/*.o
+
# ARM Compiler 6 - Target ARMv7-A
armc6_build_test "--target=arm-arm-none-eabi -march=armv7-a"
@@ -1690,7 +1765,7 @@ component_test_default_tinycrypt_without_legacy_ecc () {
scripts/config.pl unset MBEDTLS_ECP_DP_SECP192K1_ENABLED
scripts/config.pl unset MBEDTLS_ECP_DP_SECP224K1_ENABLED
scripts/config.pl unset MBEDTLS_ECP_DP_SECP256K1_ENABLED
- make CC=gcc CFLAGS='-Werror -Wall -Wextra'
+ make CC=gcc CFLAGS='-Werror -Wall -Wextra -DENABLE_TESTS'
msg "test: default config with tinycrypt enabled and legacy ECC disabled"
make test
@@ -1738,7 +1813,7 @@ component_test_hardcoded_pk_type () {
scripts/config.pl unset MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
scripts/config.pl unset MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
scripts/config.pl unset MBEDTLS_X509_RSASSA_PSS_SUPPORT
- make CFLAGS='-Werror -O1'
+ make CFLAGS='-Werror -O1 -DENABLE_TESTS'
msg "test: default config + single PK type harcoded (tinycrypt)"
make test
@@ -1752,6 +1827,13 @@ component_test_baremetal () {
msg "test: baremetal.h + baremetal_test.h"
if_build_succeeded make test
if_build_succeeded tests/ssl-opt.sh
+
+ # Optional parts (slow; currently broken on OS X because programs don't
+ # seem to receive signals under valgrind on OS X).
+ if [ "$MEMORY" -gt 0 ]; then
+ msg "test: ssl-opt.sh --memcheck"
+ if_build_succeeded tests/ssl-opt.sh --memcheck
+ fi
}
component_test_hardware_entropy () {
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
index b2113103e..ebd570fab 100755
--- a/tests/ssl-opt.sh
+++ b/tests/ssl-opt.sh
@@ -153,7 +153,7 @@ skip_next_test() {
}
requires_ciphersuite_enabled() {
- if [ -z "$($P_CLI --help | grep "$1")" ]; then
+ if [ -z "$($P_CLI --help 2>/dev/null | grep $1)" ]; then
SKIP_NEXT="YES"
fi
}
@@ -510,6 +510,45 @@ check_server_hello_time() {
fi
}
+# Get handshake memory usage from server or client output and put it into the variable specified by the first argument
+handshake_memory_get() {
+ OUTPUT_VARIABLE="$1"
+ OUTPUT_FILE="$2"
+
+ # Get memory usage from a pattern like "Heap memory usage after handshake: 23112 bytes. Peak memory usage was 33112"
+ MEM_USAGE=$(sed -n 's/.*Heap memory usage after handshake: //p' < "$OUTPUT_FILE" | grep -o "[0-9]*" | head -1)
+
+ # Check if memory usage was read
+ if [ -z "$MEM_USAGE" ]; then
+ echo "Error: Can not read the value of handshake memory usage"
+ return 1
+ else
+ eval "$OUTPUT_VARIABLE=$MEM_USAGE"
+ return 0
+ fi
+}
+
+# Get handshake memory usage from server or client output and check if this value
+# is not higher than the maximum given by the first argument
+handshake_memory_check() {
+ MAX_MEMORY="$1"
+ OUTPUT_FILE="$2"
+
+ # Get memory usage
+ if ! handshake_memory_get "MEMORY_USAGE" "$OUTPUT_FILE"; then
+ return 1
+ fi
+
+ # Check if memory usage is below max value
+ if [ "$MEMORY_USAGE" -gt "$MAX_MEMORY" ]; then
+ echo "\nFailed: Handshake memory usage was $MEMORY_USAGE bytes," \
+ "but should be below $MAX_MEMORY bytes"
+ return 1
+ else
+ return 0
+ fi
+}
+
# wait for client to terminate and set CLI_EXIT
# must be called right after starting the client
wait_client_done() {
@@ -999,6 +1038,58 @@ run_test() {
rm -f $SRV_OUT $CLI_OUT $PXY_OUT
}
+# Test that the server's memory usage after a handshake is reduced when a client specifies
+# a maximum fragment length.
+# first argument ($1) is MFL for SSL client
+# second argument ($2) is memory usage for SSL client with default MFL (16k)
+run_test_memory_after_hanshake_with_mfl()
+{
+ # The test passes if the difference is around 2*(16k-MFL)
+ local MEMORY_USAGE_LIMIT="$(( $2 - ( 2 * ( 16384 - $1 )) ))"
+
+ # Leave some margin for robustness
+ MEMORY_USAGE_LIMIT="$(( ( MEMORY_USAGE_LIMIT * 110 ) / 100 ))"
+
+ run_test "Handshake memory usage (MFL $1)" \
+ "$P_SRV debug_level=3 auth_mode=required force_version=tls1_2" \
+ "$P_CLI debug_level=3 force_version=tls1_2 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM max_frag_len=$1" \
+ 0 \
+ -F "handshake_memory_check $MEMORY_USAGE_LIMIT"
+}
+
+
+# Test that the server's memory usage after a handshake is reduced when a client specifies
+# different values of Maximum Fragment Length: default (16k), 4k, 2k, 1k and 512 bytes
+run_tests_memory_after_hanshake()
+{
+ # all tests in this sequence requires the same configuration (see requires_config_enabled())
+ SKIP_THIS_TESTS="$SKIP_NEXT"
+
+ # first test with default MFU is to get reference memory usage
+ MEMORY_USAGE_MFL_16K=0
+ run_test "Handshake memory usage initial (MFL 16384 - default)" \
+ "$P_SRV debug_level=3 auth_mode=required force_version=tls1_2" \
+ "$P_CLI debug_level=3 force_version=tls1_2 \
+ crt_file=data_files/server5.crt key_file=data_files/server5.key \
+ force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM" \
+ 0 \
+ -F "handshake_memory_get MEMORY_USAGE_MFL_16K"
+
+ SKIP_NEXT="$SKIP_THIS_TESTS"
+ run_test_memory_after_hanshake_with_mfl 4096 "$MEMORY_USAGE_MFL_16K"
+
+ SKIP_NEXT="$SKIP_THIS_TESTS"
+ run_test_memory_after_hanshake_with_mfl 2048 "$MEMORY_USAGE_MFL_16K"
+
+ SKIP_NEXT="$SKIP_THIS_TESTS"
+ run_test_memory_after_hanshake_with_mfl 1024 "$MEMORY_USAGE_MFL_16K"
+
+ SKIP_NEXT="$SKIP_THIS_TESTS"
+ run_test_memory_after_hanshake_with_mfl 512 "$MEMORY_USAGE_MFL_16K"
+}
+
cleanup() {
rm -f $CLI_OUT $SRV_OUT $PXY_OUT $SESSION
test -n "${SRV_PID:-}" && kill $SRV_PID >/dev/null 2>&1
@@ -1277,6 +1368,7 @@ run_test "SHA-256 allowed by default in client certificate" \
0
# Tests for datagram packing
+requires_config_disabled MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
run_test "DTLS: multiple records in same datagram, client and server" \
"$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
@@ -1284,6 +1376,7 @@ run_test "DTLS: multiple records in same datagram, client and server" \
-c "next record in same datagram" \
-s "next record in same datagram"
+requires_config_disabled MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
run_test "DTLS: multiple records in same datagram, client only" \
"$P_SRV dtls=1 dgram_packing=0 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=1 debug_level=2" \
@@ -1291,6 +1384,7 @@ run_test "DTLS: multiple records in same datagram, client only" \
-s "next record in same datagram" \
-C "next record in same datagram"
+requires_config_disabled MBEDTLS_SSL_IMMEDIATE_TRANSMISSION
run_test "DTLS: multiple records in same datagram, server only" \
"$P_SRV dtls=1 dgram_packing=1 debug_level=2" \
"$P_CLI dtls=1 dgram_packing=0 debug_level=2" \
@@ -2176,6 +2270,32 @@ run_test "Connection ID, 3D: Cli+Srv enabled, Srv disables on renegotiation"
-c "ignoring unexpected CID" \
-s "ignoring unexpected CID"
+requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
+requires_config_enabled MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+run_test "Connection ID: Cli+Srv enabled, variable buffer lengths, MFL=512" \
+ "$P_SRV dtls=1 cid=1 cid_val=dead debug_level=2" \
+ "$P_CLI force_ciphersuite="TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" max_frag_len=512 dtls=1 cid=1 cid_val=beef" \
+ 0 \
+ -c "(initial handshake) Peer CID (length 2 Bytes): de ad" \
+ -s "(initial handshake) Peer CID (length 2 Bytes): be ef" \
+ -s "(initial handshake) Use of Connection ID has been negotiated" \
+ -c "(initial handshake) Use of Connection ID has been negotiated" \
+ -s "Reallocating in_buf" \
+ -s "Reallocating out_buf"
+
+requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID
+requires_config_enabled MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH
+run_test "Connection ID: Cli+Srv enabled, variable buffer lengths, MFL=1024" \
+ "$P_SRV dtls=1 cid=1 cid_val=dead debug_level=2" \
+ "$P_CLI force_ciphersuite="TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" max_frag_len=1024 dtls=1 cid=1 cid_val=beef" \
+ 0 \
+ -c "(initial handshake) Peer CID (length 2 Bytes): de ad" \
+ -s "(initial handshake) Peer CID (length 2 Bytes): be ef" \
+ -s "(initial handshake) Use of Connection ID has been negotiated" \
+ -c "(initial handshake) Use of Connection ID has been negotiated" \
+ -s "Reallocating in_buf" \
+ -s "Reallocating out_buf"
+
# Tests for Encrypt-then-MAC extension
run_test "Encrypt then MAC: default" \
@@ -3047,14 +3167,15 @@ run_test "Session resume using cache, DTLS: openssl server" \
if [ $MAX_CONTENT_LEN -ne 16384 ]; then
printf "Using non-default maximum content length $MAX_CONTENT_LEN\n"
fi
-
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
run_test "Max fragment length: enabled, default" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3" \
0 \
- -c "Maximum fragment length is $MAX_CONTENT_LEN" \
- -s "Maximum fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum output fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum output fragment length is $MAX_CONTENT_LEN" \
-C "client hello, adding max_fragment_length extension" \
-S "found max fragment length extension" \
-S "server hello, max_fragment_length extension" \
@@ -3065,8 +3186,10 @@ run_test "Max fragment length: enabled, default, larger message" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 request_size=$(( $MAX_CONTENT_LEN + 1))" \
0 \
- -c "Maximum fragment length is $MAX_CONTENT_LEN" \
- -s "Maximum fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum output fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum output fragment length is $MAX_CONTENT_LEN" \
-C "client hello, adding max_fragment_length extension" \
-S "found max fragment length extension" \
-S "server hello, max_fragment_length extension" \
@@ -3076,13 +3199,14 @@ run_test "Max fragment length: enabled, default, larger message" \
-s "1 bytes read"
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 4096
run_test "Max fragment length, DTLS: enabled, default, larger message" \
"$P_SRV debug_level=3 dtls=1" \
"$P_CLI debug_level=3 dtls=1 request_size=$(( $MAX_CONTENT_LEN + 1))" \
1 \
- -c "Maximum fragment length is $MAX_CONTENT_LEN" \
- -s "Maximum fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum output fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum output fragment length is $MAX_CONTENT_LEN" \
-C "client hello, adding max_fragment_length extension" \
-S "found max fragment length extension" \
-S "server hello, max_fragment_length extension" \
@@ -3094,72 +3218,245 @@ run_test "Max fragment length, DTLS: enabled, default, larger message" \
# content length configuration.)
requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 16384
run_test "Max fragment length: disabled, larger message" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 request_size=$(( $MAX_CONTENT_LEN + 1))" \
0 \
- -C "Maximum fragment length is 16384" \
- -S "Maximum fragment length is 16384" \
+ -C "Maximum input fragment length is 16384" \
+ -C "Maximum output fragment length is 16384" \
+ -S "Maximum input fragment length is 16384" \
+ -S "Maximum output fragment length is 16384" \
-c "$(( $MAX_CONTENT_LEN + 1)) bytes written in 2 fragments" \
-s "$MAX_CONTENT_LEN bytes read" \
-s "1 bytes read"
requires_config_disabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 16384
run_test "Max fragment length DTLS: disabled, larger message" \
"$P_SRV debug_level=3 dtls=1" \
"$P_CLI debug_level=3 dtls=1 request_size=$(( $MAX_CONTENT_LEN + 1))" \
1 \
- -C "Maximum fragment length is 16384" \
- -S "Maximum fragment length is 16384" \
+ -C "Maximum input fragment length is 16384" \
+ -C "Maximum output fragment length is 16384" \
+ -S "Maximum input fragment length is 16384" \
+ -S "Maximum output fragment length is 16384" \
-c "fragment larger than.*maximum "
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 4096
run_test "Max fragment length: used by client" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 max_frag_len=4096" \
0 \
- -c "Maximum fragment length is 4096" \
- -s "Maximum fragment length is 4096" \
+ -c "Maximum input fragment length is 4096" \
+ -c "Maximum output fragment length is 4096" \
+ -s "Maximum input fragment length is 4096" \
+ -s "Maximum output fragment length is 4096" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 512, server 1024" \
+ "$P_SRV debug_level=3 max_frag_len=1024" \
+ "$P_CLI debug_level=3 max_frag_len=512" \
+ 0 \
+ -c "Maximum input fragment length is 512" \
+ -c "Maximum output fragment length is 512" \
+ -s "Maximum input fragment length is 512" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 512, server 2048" \
+ "$P_SRV debug_level=3 max_frag_len=2048" \
+ "$P_CLI debug_level=3 max_frag_len=512" \
+ 0 \
+ -c "Maximum input fragment length is 512" \
+ -c "Maximum output fragment length is 512" \
+ -s "Maximum input fragment length is 512" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 512, server 4096" \
+ "$P_SRV debug_level=3 max_frag_len=4096" \
+ "$P_CLI debug_level=3 max_frag_len=512" \
+ 0 \
+ -c "Maximum input fragment length is 512" \
+ -c "Maximum output fragment length is 512" \
+ -s "Maximum input fragment length is 512" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 1024, server 512" \
+ "$P_SRV debug_level=3 max_frag_len=512" \
+ "$P_CLI debug_level=3 max_frag_len=1024" \
+ 0 \
+ -c "Maximum input fragment length is 1024" \
+ -c "Maximum output fragment length is 1024" \
+ -s "Maximum input fragment length is 1024" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 1024, server 2048" \
+ "$P_SRV debug_level=3 max_frag_len=2048" \
+ "$P_CLI debug_level=3 max_frag_len=1024" \
+ 0 \
+ -c "Maximum input fragment length is 1024" \
+ -c "Maximum output fragment length is 1024" \
+ -s "Maximum input fragment length is 1024" \
+ -s "Maximum output fragment length is 1024" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 1024, server 4096" \
+ "$P_SRV debug_level=3 max_frag_len=4096" \
+ "$P_CLI debug_level=3 max_frag_len=1024" \
+ 0 \
+ -c "Maximum input fragment length is 1024" \
+ -c "Maximum output fragment length is 1024" \
+ -s "Maximum input fragment length is 1024" \
+ -s "Maximum output fragment length is 1024" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 2048, server 512" \
+ "$P_SRV debug_level=3 max_frag_len=512" \
+ "$P_CLI debug_level=3 max_frag_len=2048" \
+ 0 \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 2048, server 1024" \
+ "$P_SRV debug_level=3 max_frag_len=1024" \
+ "$P_CLI debug_level=3 max_frag_len=2048" \
+ 0 \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 1024" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 2048, server 4096" \
+ "$P_SRV debug_level=3 max_frag_len=4096" \
+ "$P_CLI debug_level=3 max_frag_len=2048" \
+ 0 \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 2048" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 4096, server 512" \
+ "$P_SRV debug_level=3 max_frag_len=512" \
+ "$P_CLI debug_level=3 max_frag_len=4096" \
+ 0 \
+ -c "Maximum input fragment length is 4096" \
+ -c "Maximum output fragment length is 4096" \
+ -s "Maximum input fragment length is 4096" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 4096, server 1024" \
+ "$P_SRV debug_level=3 max_frag_len=1024" \
+ "$P_CLI debug_level=3 max_frag_len=4096" \
+ 0 \
+ -c "Maximum input fragment length is 4096" \
+ -c "Maximum output fragment length is 4096" \
+ -s "Maximum input fragment length is 4096" \
+ -s "Maximum output fragment length is 1024" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension"
+
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Max fragment length: client 4096, server 2048" \
+ "$P_SRV debug_level=3 max_frag_len=2048" \
+ "$P_CLI debug_level=3 max_frag_len=4096" \
+ 0 \
+ -c "Maximum input fragment length is 4096" \
+ -c "Maximum output fragment length is 4096" \
+ -s "Maximum input fragment length is 4096" \
+ -s "Maximum output fragment length is 2048" \
-c "client hello, adding max_fragment_length extension" \
-s "found max fragment length extension" \
-s "server hello, max_fragment_length extension" \
-c "found max_fragment_length extension"
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 4096
run_test "Max fragment length: used by server" \
"$P_SRV debug_level=3 max_frag_len=4096" \
"$P_CLI debug_level=3" \
0 \
- -c "Maximum fragment length is $MAX_CONTENT_LEN" \
- -s "Maximum fragment length is 4096" \
+ -c "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -c "Maximum output fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum input fragment length is $MAX_CONTENT_LEN" \
+ -s "Maximum output fragment length is 4096" \
-C "client hello, adding max_fragment_length extension" \
-S "found max fragment length extension" \
-S "server hello, max_fragment_length extension" \
-C "found max_fragment_length extension"
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 4096
requires_gnutls
run_test "Max fragment length: gnutls server" \
"$G_SRV" \
- "$P_CLI debug_level=3 max_frag_len=4096 ca_file=data_files/test-ca2.crt" \
+ "$P_CLI debug_level=3 max_frag_len=4096" \
0 \
- -c "Maximum fragment length is 4096" \
+ -c "Maximum input fragment length is 4096" \
+ -c "Maximum output fragment length is 4096" \
-c "client hello, adding max_fragment_length extension" \
-c "found max_fragment_length extension"
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 2048
run_test "Max fragment length: client, message just fits" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 max_frag_len=2048 request_size=2048" \
0 \
- -c "Maximum fragment length is 2048" \
- -s "Maximum fragment length is 2048" \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 2048" \
-c "client hello, adding max_fragment_length extension" \
-s "found max fragment length extension" \
-s "server hello, max_fragment_length extension" \
@@ -3168,13 +3465,14 @@ run_test "Max fragment length: client, message just fits" \
-s "2048 bytes read"
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 2048
run_test "Max fragment length: client, larger message" \
"$P_SRV debug_level=3" \
"$P_CLI debug_level=3 max_frag_len=2048 request_size=2345" \
0 \
- -c "Maximum fragment length is 2048" \
- -s "Maximum fragment length is 2048" \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 2048" \
-c "client hello, adding max_fragment_length extension" \
-s "found max fragment length extension" \
-s "server hello, max_fragment_length extension" \
@@ -3184,13 +3482,14 @@ run_test "Max fragment length: client, larger message" \
-s "297 bytes read"
requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
-requires_config_value_at_least "MBEDTLS_SSL_MAX_CONTENT_LEN" 2048
run_test "Max fragment length: DTLS client, larger message" \
"$P_SRV debug_level=3 dtls=1" \
"$P_CLI debug_level=3 dtls=1 max_frag_len=2048 request_size=2345" \
1 \
- -c "Maximum fragment length is 2048" \
- -s "Maximum fragment length is 2048" \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 2048" \
-c "client hello, adding max_fragment_length extension" \
-s "found max fragment length extension" \
-s "server hello, max_fragment_length extension" \
@@ -3292,6 +3591,29 @@ run_test "Renegotiation: double" \
-s "write hello request"
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_test "Renegotiation with max fragment length: client 2048, server 512" \
+ "$P_SRV debug_level=3 exchanges=2 renegotiation=1 auth_mode=optional renegotiate=1 max_frag_len=512" \
+ "$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1 max_frag_len=2048 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \
+ 0 \
+ -c "Maximum input fragment length is 2048" \
+ -c "Maximum output fragment length is 2048" \
+ -s "Maximum input fragment length is 2048" \
+ -s "Maximum output fragment length is 512" \
+ -c "client hello, adding max_fragment_length extension" \
+ -s "found max fragment length extension" \
+ -s "server hello, max_fragment_length extension" \
+ -c "found max_fragment_length extension" \
+ -c "client hello, adding renegotiation extension" \
+ -s "received TLS_EMPTY_RENEGOTIATION_INFO" \
+ -s "found renegotiation extension" \
+ -s "server hello, secure renegotiation extension" \
+ -c "found renegotiation extension" \
+ -c "=> renegotiate" \
+ -s "=> renegotiate" \
+ -s "write hello request"
+
+requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
run_test "Renegotiation: client-initiated, server-rejected" \
"$P_SRV debug_level=3 exchanges=2 renegotiation=0 auth_mode=optional" \
"$P_CLI debug_level=3 exchanges=2 renegotiation=1 renegotiate=1" \
@@ -7092,8 +7414,8 @@ not_with_valgrind # spurious resend
requires_config_disabled MBEDTLS_SSL_CONF_READ_TIMEOUT
requires_config_enabled MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
run_test "DTLS client reconnect from same port: reference" \
- "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
- "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000" \
+ "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=15000-25000" \
+ "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=15000-25000" \
0 \
-C "resend" \
-S "The operation timed out" \
@@ -7103,8 +7425,8 @@ not_with_valgrind # spurious resend
requires_config_disabled MBEDTLS_SSL_CONF_READ_TIMEOUT
requires_config_enabled MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
run_test "DTLS client reconnect from same port: reconnect" \
- "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=10000-20000" \
- "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=10000-20000 reconnect_hard=1" \
+ "$P_SRV dtls=1 exchanges=2 read_timeout=20000 hs_timeout=15000-25000" \
+ "$P_CLI dtls=1 exchanges=2 debug_level=2 hs_timeout=15000-25000 reconnect_hard=1" \
0 \
-C "resend" \
-S "The operation timed out" \
@@ -8774,6 +9096,12 @@ run_test "DTLS proxy: 3d, gnutls server, fragmentation, nbio" \
-s "Extra-header:" \
-c "Extra-header:"
+# Test heap memory usage after handshake
+requires_config_enabled MBEDTLS_MEMORY_DEBUG
+requires_config_enabled MBEDTLS_MEMORY_BUFFER_ALLOC_C
+requires_config_enabled MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+run_tests_memory_after_hanshake
+
# Final report
echo "------------------------------------------------------------------------"
diff --git a/tests/suites/test_suite_ssl.function b/tests/suites/test_suite_ssl.function
index 9873dd828..68d844252 100644
--- a/tests/suites/test_suite_ssl.function
+++ b/tests/suites/test_suite_ssl.function
@@ -68,15 +68,49 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
memset( key0, 0x1, keylen );
memset( key1, 0x2, keylen );
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ t_in->key_enc = mbedtls_calloc( 1, keylen );
+ t_in->key_dec = mbedtls_calloc( 1, keylen );
+
+ t_out->key_enc = mbedtls_calloc( 1, keylen );
+ t_out->key_dec = mbedtls_calloc( 1, keylen );
+
+ memcpy( t_in->key_enc, key0, keylen);
+ memcpy( t_in->key_dec, key1, keylen);
+ t_in->key_bitlen = cipher_info->key_bitlen;
+
+ memcpy( t_out->key_enc, key1, keylen);
+ memcpy( t_out->key_dec, key0, keylen);
+ t_out->key_bitlen = cipher_info->key_bitlen;
+
+#if defined(MBEDTLS_VALIDATE_SSL_KEYS_INTEGRITY)
+ t_in->key_enc_hash = mbedtls_hash( t_in->key_enc, t_in->key_bitlen >> 3 );
+ t_in->key_dec_hash = mbedtls_hash( t_in->key_dec, t_in->key_bitlen >> 3 );
+
+ t_out->key_enc_hash = mbedtls_hash( t_out->key_enc, t_out->key_bitlen >> 3 );
+ t_out->key_dec_hash = mbedtls_hash( t_out->key_dec, t_out->key_bitlen >> 3 );
+#endif
+
+ /* Setup cipher contexts */
+ CHK( mbedtls_cipher_setup( &t_in->cipher_ctx, cipher_info ) == 0 );
+ CHK( mbedtls_cipher_setup( &t_out->cipher_ctx, cipher_info ) == 0 );
+#else
/* Setup cipher contexts */
CHK( mbedtls_cipher_setup( &t_in->cipher_ctx_enc, cipher_info ) == 0 );
CHK( mbedtls_cipher_setup( &t_in->cipher_ctx_dec, cipher_info ) == 0 );
CHK( mbedtls_cipher_setup( &t_out->cipher_ctx_enc, cipher_info ) == 0 );
CHK( mbedtls_cipher_setup( &t_out->cipher_ctx_dec, cipher_info ) == 0 );
+#endif
#if defined(MBEDTLS_CIPHER_MODE_CBC)
if( cipher_info->mode == MBEDTLS_MODE_CBC )
{
+#if defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
+ CHK( mbedtls_cipher_set_padding_mode( &t_in->cipher_ctx,
+ MBEDTLS_PADDING_NONE ) == 0 );
+ CHK( mbedtls_cipher_set_padding_mode( &t_out->cipher_ctx,
+ MBEDTLS_PADDING_NONE ) == 0 );
+#else
CHK( mbedtls_cipher_set_padding_mode( &t_in->cipher_ctx_enc,
MBEDTLS_PADDING_NONE ) == 0 );
CHK( mbedtls_cipher_set_padding_mode( &t_in->cipher_ctx_dec,
@@ -85,9 +119,11 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
MBEDTLS_PADDING_NONE ) == 0 );
CHK( mbedtls_cipher_set_padding_mode( &t_out->cipher_ctx_dec,
MBEDTLS_PADDING_NONE ) == 0 );
+#endif
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
+#if !defined(MBEDTLS_SSL_TRANSFORM_OPTIMIZE_CIPHERS)
CHK( mbedtls_cipher_setkey( &t_in->cipher_ctx_enc, key0,
keylen << 3, MBEDTLS_ENCRYPT ) == 0 );
CHK( mbedtls_cipher_setkey( &t_in->cipher_ctx_dec, key1,
@@ -96,7 +132,7 @@ static int build_transforms( mbedtls_ssl_transform *t_in,
keylen << 3, MBEDTLS_ENCRYPT ) == 0 );
CHK( mbedtls_cipher_setkey( &t_out->cipher_ctx_dec, key0,
keylen << 3, MBEDTLS_DECRYPT ) == 0 );
-
+#endif
/* Setup MAC contexts */
#if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
if( cipher_info->mode == MBEDTLS_MODE_CBC ||
diff --git a/tests/suites/test_suite_tinycrypt.data b/tests/suites/test_suite_tinycrypt.data
index 2c4d54b5a..f0ba505b7 100644
--- a/tests/suites/test_suite_tinycrypt.data
+++ b/tests/suites/test_suite_tinycrypt.data
@@ -4,8 +4,173 @@ test_ecdh:
Tinycrypt ECDSA
test_ecdsa:
+NIST CAVP SP 800-56A ECCCDH count 0
+ecdh_primitive_vector:"700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287":"db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac":"7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534":"46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b"
+
+NIST CAVP SP 800-56A ECCCDH count 1
+ecdh_primitive_vector:"809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae":"b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3":"38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5":"057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67"
+
+NIST CAVP SP 800-56A ECCCDH count 2
+ecdh_primitive_vector:"a2339c12d4a03c33546de533268b4ad667debf458b464d77443636440ee7fec3":"ef48a3ab26e20220bcda2c1851076839dae88eae962869a497bf73cb66faf536":"1accfaf1b97712b85a6f54b148985a1bdc4c9bec0bd258cad4b3d603f49f32c8":"2d457b78b4614132477618a5b077965ec90730a8c81a1c75d6d4ec68005d67ec"
+
+NIST CAVP SP 800-56A ECCCDH count 3
+ecdh_primitive_vector:"df3989b9fa55495719b3cf46dccd28b5153f7808191dd518eff0c3cff2b705ed":"422294ff46003429d739a33206c8752552c8ba54a270defc06e221e0feaf6ac4":"207c43a79bfee03db6f4b944f53d2fb76cc49ef1c9c4d34d51b6c65c4db6932d":"96441259534b80f6aee3d287a6bb17b5094dd4277d9e294f8fe73e48bf2a0024"
+
+NIST CAVP SP 800-56A ECCCDH count 4
+ecdh_primitive_vector:"41192d2813e79561e6a1d6f53c8bc1a433a199c835e141b05a74a97b0faeb922":"1af98cc45e98a7e041b01cf35f462b7562281351c8ebf3ffa02e33a0722a1328":"59137e38152350b195c9718d39673d519838055ad908dd4757152fd8255c09bf":"19d44c8d63e8e8dd12c22a87b8cd4ece27acdde04dbf47f7f27537a6999a8e62"
+
+NIST CAVP SP 800-56A ECCCDH count 5
+ecdh_primitive_vector:"33e82092a0f1fb38f5649d5867fba28b503172b7035574bf8e5b7100a3052792":"f2cf6b601e0a05945e335550bf648d782f46186c772c0f20d3cd0d6b8ca14b2f":"f5f8e0174610a661277979b58ce5c90fee6c9b3bb346a90a7196255e40b132ef":"664e45d5bba4ac931cd65d52017e4be9b19a515f669bea4703542a2c525cd3d3"
+
+NIST CAVP SP 800-56A ECCCDH count 6
+ecdh_primitive_vector:"6a9e0c3f916e4e315c91147be571686d90464e8bf981d34a90b6353bca6eeba7":"40f9bead39c2f2bcc2602f75b8a73ec7bdffcbcead159d0174c6c4d3c5357f05":"3b589af7db03459c23068b64f63f28d3c3c6bc25b5bf76ac05f35482888b5190":"ca342daa50dc09d61be7c196c85e60a80c5cb04931746820be548cdde055679d"
+
+NIST CAVP SP 800-56A ECCCDH count 7
+ecdh_primitive_vector:"a9c0acade55c2a73ead1a86fb0a9713223c82475791cd0e210b046412ce224bb":"f6de0afa20e93e078467c053d241903edad734c6b403ba758c2b5ff04c9d4229":"d8bf929a20ea7436b2461b541a11c80e61d826c0a4c9d322b31dd54e7f58b9c8":"35aa9b52536a461bfde4e85fc756be928c7de97923f0416c7a3ac8f88b3d4489"
+
+NIST CAVP SP 800-56A ECCCDH count 8
+ecdh_primitive_vector:"94e94f16a98255fff2b9ac0c9598aac35487b3232d3231bd93b7db7df36f9eb9":"d8049a43579cfa90b8093a94416cbefbf93386f15b3f6e190b6e3455fedfe69a":"0f9883ba0ef32ee75ded0d8bda39a5146a29f1f2507b3bd458dbea0b2bb05b4d":"605c16178a9bc875dcbff54d63fe00df699c03e8a888e9e94dfbab90b25f39b4"
+
+NIST CAVP SP 800-56A ECCCDH count 9
+ecdh_primitive_vector:"e099bf2a4d557460b5544430bbf6da11004d127cb5d67f64ab07c94fcdf5274f":"d9c50dbe70d714edb5e221f4e020610eeb6270517e688ca64fb0e98c7ef8c1c5":"2beedb04b05c6988f6a67500bb813faf2cae0d580c9253b6339e4a3337bb6c08":"f96e40a1b72840854bb62bc13c40cc2795e373d4e715980b261476835a092e0b"
+
+NIST CAVP SP 800-56A ECCCDH count 10
+ecdh_primitive_vector:"f75a5fe56bda34f3c1396296626ef012dc07e4825838778a645c8248cff01658":"33bbdf1b1772d8059df568b061f3f1122f28a8d819167c97be448e3dc3fb0c3c":"77c15dcf44610e41696bab758943eff1409333e4d5a11bbe72c8f6c395e9f848":"8388fa79c4babdca02a8e8a34f9e43554976e420a4ad273c81b26e4228e9d3a3"
+
+NIST CAVP SP 800-56A ECCCDH count 11
+ecdh_primitive_vector:"2db4540d50230756158abf61d9835712b6486c74312183ccefcaef2797b7674d":"62f57f314e3f3495dc4e099012f5e0ba71770f9660a1eada54104cdfde77243e":"42a83b985011d12303db1a800f2610f74aa71cdf19c67d54ce6c9ed951e9093e":"72877cea33ccc4715038d4bcbdfe0e43f42a9e2c0c3b017fc2370f4b9acbda4a"
+
+NIST CAVP SP 800-56A ECCCDH count 12
+ecdh_primitive_vector:"cd94fc9497e8990750309e9a8534fd114b0a6e54da89c4796101897041d14ecb":"c3def4b5fe04faee0a11932229fff563637bfdee0e79c6deeaf449f85401c5c4":"ceed35507b5c93ead5989119b9ba342cfe38e6e638ba6eea343a55475de2800b":"e4e7408d85ff0e0e9c838003f28cdbd5247cdce31f32f62494b70e5f1bc36307"
+
+NIST CAVP SP 800-56A ECCCDH count 13
+ecdh_primitive_vector:"15b9e467af4d290c417402e040426fe4cf236bae72baa392ed89780dfccdb471":"cdf4e9170fb904302b8fd93a820ba8cc7ed4efd3a6f2d6b05b80b2ff2aee4e77":"43e0e9d95af4dc36483cdd1968d2b7eeb8611fcce77f3a4e7d059ae43e509604":"ed56bcf695b734142c24ecb1fc1bb64d08f175eb243a31f37b3d9bb4407f3b96"
+
+NIST CAVP SP 800-56A ECCCDH count 14
+ecdh_primitive_vector:"49c503ba6c4fa605182e186b5e81113f075bc11dcfd51c932fb21e951eee2fa1":"8af706ff0922d87b3f0c5e4e31d8b259aeb260a9269643ed520a13bb25da5924":"b2f3600df3368ef8a0bb85ab22f41fc0e5f4fdd54be8167a5c3cd4b08db04903":"bc5c7055089fc9d6c89f83c1ea1ada879d9934b2ea28fcf4e4a7e984b28ad2cf"
+
+NIST CAVP SP 800-56A ECCCDH count 15
+ecdh_primitive_vector:"19b38de39fdd2f70f7091631a4f75d1993740ba9429162c2a45312401636b29c":"09aed7232b28e060941741b6828bcdfa2bc49cc844f3773611504f82a390a5ae":"4002534307f8b62a9bf67ff641ddc60fef593b17c3341239e95bdb3e579bfdc8":"9a4e8e657f6b0e097f47954a63c75d74fcba71a30d83651e3e5a91aa7ccd8343"
+
+NIST CAVP SP 800-56A ECCCDH count 16
+ecdh_primitive_vector:"2c91c61f33adfe9311c942fdbff6ba47020feff416b7bb63cec13faf9b099954":"6cab31b06419e5221fca014fb84ec870622a1b12bab5ae43682aa7ea73ea08d0":"4dfa12defc60319021b681b3ff84a10a511958c850939ed45635934ba4979147":"3ca1fc7ad858fb1a6aba232542f3e2a749ffc7203a2374a3f3d3267f1fc97b78"
+
+NIST CAVP SP 800-56A ECCCDH count 17
+ecdh_primitive_vector:"a28a2edf58025668f724aaf83a50956b7ac1cfbbff79b08c3bf87dfd2828d767":"dfa7bfffd4c766b86abeaf5c99b6e50cb9ccc9d9d00b7ffc7804b0491b67bc03":"1331f6d874a4ed3bc4a2c6e9c74331d3039796314beee3b7152fcdba5556304e":"1aaabe7ee6e4a6fa732291202433a237df1b49bc53866bfbe00db96a0f58224f"
+
+NIST CAVP SP 800-56A ECCCDH count 18
+ecdh_primitive_vector:"a2ef857a081f9d6eb206a81c4cf78a802bdf598ae380c8886ecd85fdc1ed7644":"563c4c20419f07bc17d0539fade1855e34839515b892c0f5d26561f97fa04d1a":"dd5e9f70ae740073ca0204df60763fb6036c45709bf4a7bb4e671412fad65da3":"430e6a4fba4449d700d2733e557f66a3bf3d50517c1271b1ddae1161b7ac798c"
+
+NIST CAVP SP 800-56A ECCCDH count 19
+ecdh_primitive_vector:"ccd8a2d86bc92f2e01bce4d6922cf7fe1626aed044685e95e2eebd464505f01f":"e9ddd583a9635a667777d5b8a8f31b0f79eba12c75023410b54b8567dddc0f38":"5ae026cfc060d55600717e55b8a12e116d1d0df34af831979057607c2d9c2f76":"1ce9e6740529499f98d1f1d71329147a33df1d05e4765b539b11cf615d6974d3"
+
+NIST CAVP SP 800-56A ECCCDH count 20
+ecdh_primitive_vector:"c188ffc8947f7301fb7b53e36746097c2134bf9cc981ba74b4e9c4361f595e4e":"bf7d2f2056e72421ef393f0c0f2b0e00130e3cac4abbcc00286168e85ec55051":"b601ac425d5dbf9e1735c5e2d5bdb79ca98b3d5be4a2cfd6f2273f150e064d9d":"4690e3743c07d643f1bc183636ab2a9cb936a60a802113c49bb1b3f2d0661660"
+
+NIST CAVP SP 800-56A ECCCDH count 21
+ecdh_primitive_vector:"317e1020ff53fccef18bf47bb7f2dd7707fb7b7a7578e04f35b3beed222a0eb6":"09420ce5a19d77c6fe1ee587e6a49fbaf8f280e8df033d75403302e5a27db2ae":"fefb1dda1845312b5fce6b81b2be205af2f3a274f5a212f66c0d9fc33d7ae535":"30c2261bd0004e61feda2c16aa5e21ffa8d7e7f7dbf6ec379a43b48e4b36aeb0"
+
+NIST CAVP SP 800-56A ECCCDH count 22
+ecdh_primitive_vector:"45fb02b2ceb9d7c79d9c2fa93e9c7967c2fa4df5789f9640b24264b1e524fcb1":"5c6e8ecf1f7d3023893b7b1ca1e4d178972ee2a230757ddc564ffe37f5c5a321":"334ae0c4693d23935a7e8e043ebbde21e168a7cba3fa507c9be41d7681e049ce":"2adae4a138a239dcd93c243a3803c3e4cf96e37fe14e6a9b717be9599959b11c"
+
+NIST CAVP SP 800-56A ECCCDH count 23
+ecdh_primitive_vector:"a19ef7bff98ada781842fbfc51a47aff39b5935a1c7d9625c8d323d511c92de6":"e9c184df75c955e02e02e400ffe45f78f339e1afe6d056fb3245f4700ce606ef":"2c4bde40214fcc3bfc47d4cf434b629acbe9157f8fd0282540331de7942cf09d":"2e277ec30f5ea07d6ce513149b9479b96e07f4b6913b1b5c11305c1444a1bc0b"
+
+NIST CAVP SP 800-56A ECCCDH count 24
+ecdh_primitive_vector:"356c5a444c049a52fee0adeb7e5d82ae5aa83030bfff31bbf8ce2096cf161c4b":"57d128de8b2a57a094d1a001e572173f96e8866ae352bf29cddaf92fc85b2f92":"85a268f9d7772f990c36b42b0a331adc92b5941de0b862d5d89a347cbf8faab0":"1e51373bd2c6044c129c436e742a55be2a668a85ae08441b6756445df5493857"
+
ECDH primitive rfc 5903 p256
ecdh_primitive_testvec:"C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433":"DAD0B65394221CF9B051E1FECA5787D098DFE637FC90B9EF945D0C3772581180":"5271A0461CDB8252D61F1C456FA3E59AB1F45B33ACCF5F58389E0577B8990BB3":"C6EF9C5D78AE012A011164ACB397CE2088685D8F06BF9BE0B283AB46476BEE53":"D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63":"56FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB":"D6840F6B42F6EDAFD13116E0E12565202FEF8E9ECE7DCE03812464D04B9442DE"
ECDSA primitive rfc 4754 p256
ecdsa_primitive_testvec:"2442A5CC0ECD015FA3CA31DC8E2BBC70BF42D60CBCA20085E0822CB04235E970":"6FC98BD7E50211A4A27102FA3549DF79EBCB4BF246B80945CDDFE7D509BBFD7D":"BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD":"CB28E0999B9C7715FD0A80D8E47A77079716CBBF917DD72E97566EA1C066957C":"86FA3BB4E26CAD5BF90B7F81899256CE7594BB1EA0C89212748BFF3B3D5B0315"
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 1 (failure)
+ecdsa_verify_msg:"e4796db5f785f207aa30d311693b3702821dff1168fd2e04c0836825aefd850d9aa60326d88cde1a23c7745351392ca2288d632c264f197d05cd424a30336c19fd09bb229654f0222fcb881a4b35c290a093ac159ce13409111ff0358411133c24f5b8e2090d6db6558afc36f06ca1f6ef779785adba68db27a409859fc4c4a0":"87f8f2b218f49845f6f10eec3877136269f5c1a54736dbdf69f89940cad41555":"e15f369036f49842fac7a86c8a2b0557609776814448b8f5e84aa9f4395205e9":"d19ff48b324915576416097d2544f7cbdf8768b1454ad20e0baac50e211f23b0":"a3e81e59311cdfff2d4784949f7a2cb50ba6c3a91fa54710568e61aca3e847c6":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 2 (failure)
+ecdsa_verify_msg:"069a6e6b93dfee6df6ef6997cd80dd2182c36653cef10c655d524585655462d683877f95ecc6d6c81623d8fac4e900ed0019964094e7de91f1481989ae1873004565789cbf5dc56c62aedc63f62f3b894c9c6f7788c8ecaadc9bd0e81ad91b2b3569ea12260e93924fdddd3972af5273198f5efda0746219475017557616170e":"5cf02a00d205bdfee2016f7421807fc38ae69e6b7ccd064ee689fc1a94a9f7d2":"ec530ce3cc5c9d1af463f264d685afe2b4db4b5828d7e61b748930f3ce622a85":"dc23d130c6117fb5751201455e99f36f59aba1a6a21cf2d0e7481a97451d6693":"d6ce7708c18dbf35d4f8aa7240922dc6823f2e7058cbc1484fcad1599db5018c":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 3 (failure)
+ecdsa_verify_msg:"df04a346cf4d0e331a6db78cca2d456d31b0a000aa51441defdb97bbeb20b94d8d746429a393ba88840d661615e07def615a342abedfa4ce912e562af714959896858af817317a840dcff85a057bb91a3c2bf90105500362754a6dd321cdd86128cfc5f04667b57aa78c112411e42da304f1012d48cd6a7052d7de44ebcc01de":"2ddfd145767883ffbb0ac003ab4a44346d08fa2570b3120dcce94562422244cb":"5f70c7d11ac2b7a435ccfbbae02c3df1ea6b532cc0e9db74f93fffca7c6f9a64":"9913111cff6f20c5bf453a99cd2c2019a4e749a49724a08774d14e4c113edda8":"9467cd4cd21ecb56b0cab0a9a453b43386845459127a952421f5c6382866c5cc":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 4 (success)
+ecdsa_verify_msg:"e1130af6a38ccb412a9c8d13e15dbfc9e69a16385af3c3f1e5da954fd5e7c45fd75e2b8c36699228e92840c0562fbf3772f07e17f1add56588dd45f7450e1217ad239922dd9c32695dc71ff2424ca0dec1321aa47064a044b7fe3c2b97d03ce470a592304c5ef21eed9f93da56bb232d1eeb0035f9bf0dfafdcc4606272b20a3":"e424dc61d4bb3cb7ef4344a7f8957a0c5134e16f7a67c074f82e6e12f49abf3c":"970eed7aa2bc48651545949de1dddaf0127e5965ac85d1243d6f60e7dfaee927":"bf96b99aa49c705c910be33142017c642ff540c76349b9dab72f981fd9347f4f":"17c55095819089c2e03b9cd415abdf12444e323075d98f31920b9e0f57ec871c":UECC_SUCCESS
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 5 (success)
+ecdsa_verify_msg:"73c5f6a67456ae48209b5f85d1e7de7758bf235300c6ae2bdceb1dcb27a7730fb68c950b7fcada0ecc4661d3578230f225a875e69aaa17f1e71c6be5c831f22663bac63d0c7a9635edb0043ff8c6f26470f02a7bc56556f1437f06dfa27b487a6c4290d8bad38d4879b334e341ba092dde4e4ae694a9c09302e2dbf443581c08":"e0fc6a6f50e1c57475673ee54e3a57f9a49f3328e743bf52f335e3eeaa3d2864":"7f59d689c91e463607d9194d99faf316e25432870816dde63f5d4b373f12f22a":"1d75830cd36f4c9aa181b2c4221e87f176b7f05b7c87824e82e396c88315c407":"cb2acb01dac96efc53a32d4a0d85d0c2e48955214783ecf50a4f0414a319c05a":UECC_SUCCESS
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 6 (failure)
+ecdsa_verify_msg:"666036d9b4a2426ed6585a4e0fd931a8761451d29ab04bd7dc6d0c5b9e38e6c2b263ff6cb837bd04399de3d757c6c7005f6d7a987063cf6d7e8cb38a4bf0d74a282572bd01d0f41e3fd066e3021575f0fa04f27b700d5b7ddddf50965993c3f9c7118ed78888da7cb221849b3260592b8e632d7c51e935a0ceae15207bedd548":"a849bef575cac3c6920fbce675c3b787136209f855de19ffe2e8d29b31a5ad86":"bf5fe4f7858f9b805bd8dcc05ad5e7fb889de2f822f3d8b41694e6c55c16b471":"25acc3aa9d9e84c7abf08f73fa4195acc506491d6fc37cb9074528a7db87b9d6":"9b21d5b5259ed3f2ef07dfec6cc90d3a37855d1ce122a85ba6a333f307d31537":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 7 (failure)
+ecdsa_verify_msg:"7e80436bce57339ce8da1b5660149a20240b146d108deef3ec5da4ae256f8f894edcbbc57b34ce37089c0daa17f0c46cd82b5a1599314fd79d2fd2f446bd5a25b8e32fcf05b76d644573a6df4ad1dfea707b479d97237a346f1ec632ea5660efb57e8717a8628d7f82af50a4e84b11f21bdff6839196a880ae20b2a0918d58cd":"3dfb6f40f2471b29b77fdccba72d37c21bba019efa40c1c8f91ec405d7dcc5df":"f22f953f1e395a52ead7f3ae3fc47451b438117b1e04d613bc8555b7d6e6d1bb":"548886278e5ec26bed811dbb72db1e154b6f17be70deb1b210107decb1ec2a5a":"e93bfebd2f14f3d827ca32b464be6e69187f5edbd52def4f96599c37d58eee75":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 8 (failure)
+ecdsa_verify_msg:"1669bfb657fdc62c3ddd63269787fc1c969f1850fb04c933dda063ef74a56ce13e3a649700820f0061efabf849a85d474326c8a541d99830eea8131eaea584f22d88c353965dabcdc4bf6b55949fd529507dfb803ab6b480cd73ca0ba00ca19c438849e2cea262a1c57d8f81cd257fb58e19dec7904da97d8386e87b84948169":"69b7667056e1e11d6caf6e45643f8b21e7a4bebda463c7fdbc13bc98efbd0214":"d3f9b12eb46c7c6fda0da3fc85bc1fd831557f9abc902a3be3cb3e8be7d1aa2f":"288f7a1cd391842cce21f00e6f15471c04dc182fe4b14d92dc18910879799790":"247b3c4e89a3bcadfea73c7bfd361def43715fa382b8c3edf4ae15d6e55e9979":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 9 (failure)
+ecdsa_verify_msg:"3fe60dd9ad6caccf5a6f583b3ae65953563446c4510b70da115ffaa0ba04c076115c7043ab8733403cd69c7d14c212c655c07b43a7c71b9a4cffe22c2684788ec6870dc2013f269172c822256f9e7cc674791bf2d8486c0f5684283e1649576efc982ede17c7b74b214754d70402fb4bb45ad086cf2cf76b3d63f7fce39ac970":"bf02cbcf6d8cc26e91766d8af0b164fc5968535e84c158eb3bc4e2d79c3cc682":"069ba6cb06b49d60812066afa16ecf7b51352f2c03bd93ec220822b1f3dfba03":"f5acb06c59c2b4927fb852faa07faf4b1852bbb5d06840935e849c4d293d1bad":"049dab79c89cc02f1484c437f523e080a75f134917fda752f2d5ca397addfe5d":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 10 (failure)
+ecdsa_verify_msg:"983a71b9994d95e876d84d28946a041f8f0a3f544cfcc055496580f1dfd4e312a2ad418fe69dbc61db230cc0c0ed97e360abab7d6ff4b81ee970a7e97466acfd9644f828ffec538abc383d0e92326d1c88c55e1f46a668a039beaa1be631a89129938c00a81a3ae46d4aecbf9707f764dbaccea3ef7665e4c4307fa0b0a3075c":"224a4d65b958f6d6afb2904863efd2a734b31798884801fcab5a590f4d6da9de":"178d51fddada62806f097aa615d33b8f2404e6b1479f5fd4859d595734d6d2b9":"87b93ee2fecfda54deb8dff8e426f3c72c8864991f8ec2b3205bb3b416de93d2":"4044a24df85be0cc76f21a4430b75b8e77b932a87f51e4eccbc45c263ebf8f66":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 11 (failure)
+ecdsa_verify_msg:"4a8c071ac4fd0d52faa407b0fe5dab759f7394a5832127f2a3498f34aac287339e043b4ffa79528faf199dc917f7b066ad65505dab0e11e6948515052ce20cfdb892ffb8aa9bf3f1aa5be30a5bbe85823bddf70b39fd7ebd4a93a2f75472c1d4f606247a9821f1a8c45a6cb80545de2e0c6c0174e2392088c754e9c8443eb5af":"43691c7795a57ead8c5c68536fe934538d46f12889680a9cb6d055a066228369":"f8790110b3c3b281aa1eae037d4f1234aff587d903d93ba3af225c27ddc9ccac":"8acd62e8c262fa50dd9840480969f4ef70f218ebf8ef9584f199031132c6b1ce":"cfca7ed3d4347fb2a29e526b43c348ae1ce6c60d44f3191b6d8ea3a2d9c92154":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 12 (failure)
+ecdsa_verify_msg:"0a3a12c3084c865daf1d302c78215d39bfe0b8bf28272b3c0b74beb4b7409db0718239de700785581514321c6440a4bbaea4c76fa47401e151e68cb6c29017f0bce4631290af5ea5e2bf3ed742ae110b04ade83a5dbd7358f29a85938e23d87ac8233072b79c94670ff0959f9c7f4517862ff829452096c78f5f2e9a7e4e9216":"9157dbfcf8cf385f5bb1568ad5c6e2a8652ba6dfc63bc1753edf5268cb7eb596":"972570f4313d47fc96f7c02d5594d77d46f91e949808825b3d31f029e8296405":"dfaea6f297fa320b707866125c2a7d5d515b51a503bee817de9faa343cc48eeb":"8f780ad713f9c3e5a4f7fa4c519833dfefc6a7432389b1e4af463961f09764f2":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 13 (failure)
+ecdsa_verify_msg:"785d07a3c54f63dca11f5d1a5f496ee2c2f9288e55007e666c78b007d95cc28581dce51f490b30fa73dc9e2d45d075d7e3a95fb8a9e1465ad191904124160b7c60fa720ef4ef1c5d2998f40570ae2a870ef3e894c2bc617d8a1dc85c3c55774928c38789b4e661349d3f84d2441a3b856a76949b9f1f80bc161648a1cad5588e":"072b10c081a4c1713a294f248aef850e297991aca47fa96a7470abe3b8acfdda":"9581145cca04a0fb94cedce752c8f0370861916d2a94e7c647c5373ce6a4c8f5":"09f5483eccec80f9d104815a1be9cc1a8e5b12b6eb482a65c6907b7480cf4f19":"a4f90e560c5e4eb8696cb276e5165b6a9d486345dedfb094a76e8442d026378d":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 14 (failure)
+ecdsa_verify_msg:"76f987ec5448dd72219bd30bf6b66b0775c80b394851a43ff1f537f140a6e7229ef8cd72ad58b1d2d20298539d6347dd5598812bc65323aceaf05228f738b5ad3e8d9fe4100fd767c2f098c77cb99c2992843ba3eed91d32444f3b6db6cd212dd4e5609548f4bb62812a920f6e2bf1581be1ebeebdd06ec4e971862cc42055ca":"09308ea5bfad6e5adf408634b3d5ce9240d35442f7fe116452aaec0d25be8c24":"f40c93e023ef494b1c3079b2d10ef67f3170740495ce2cc57f8ee4b0618b8ee5":"5cc8aa7c35743ec0c23dde88dabd5e4fcd0192d2116f6926fef788cddb754e73":"9c9c045ebaa1b828c32f82ace0d18daebf5e156eb7cbfdc1eff4399a8a900ae7":UECC_FAILURE
+
+ECDSA verification - NIST CAVP FIPS 186-4 vector 15 (success)
+ecdsa_verify_msg:"60cd64b2cd2be6c33859b94875120361a24085f3765cb8b2bf11e026fa9d8855dbe435acf7882e84f3c7857f96e2baab4d9afe4588e4a82e17a78827bfdb5ddbd1c211fbc2e6d884cddd7cb9d90d5bf4a7311b83f352508033812c776a0e00c003c7e0d628e50736c7512df0acfa9f2320bd102229f46495ae6d0857cc452a84":"2d98ea01f754d34bbc3003df5050200abf445ec728556d7ed7d5c54c55552b6d":"9b52672742d637a32add056dfd6d8792f2a33c2e69dafabea09b960bc61e230a":"06108e525f845d0155bf60193222b3219c98e3d49424c2fb2a0987f825c17959":"62b5cdd591e5b507e560167ba8f6f7cda74673eb315680cb89ccbc4eec477dce":UECC_SUCCESS
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 1
+ecdsa_sig:"5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8":"519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464":"94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de":"f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac":"8bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 2
+ecdsa_sig:"c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1":"0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813":"6d3e71882c3b83b156bb14e0ab184aa9fb728068d3ae9fac421187ae0b2f34c6":"976d3a4e9d23326dc0baa9fa560b7c4e53f42864f508483a6473b6a11079b2db":"1b766e9ceb71ba6c01dcd46e0af462cd4cfa652ae5017d4555b8eeefe36e1932"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 3
+ecdsa_sig:"3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee":"e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef":"ad5e887eb2b380b8d8280ad6e5ff8a60f4d26243e0124c2f31a297b5d0835de2":"35fb60f5ca0f3ca08542fb3cc641c8263a2cab7a90ee6a5e1583fac2bb6f6bd1":"ee59d81bc9db1055cc0ed97b159d8784af04e98511d0a9a407b99bb292572e96"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 4
+ecdsa_sig:"0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30":"a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07":"24fc90e1da13f17ef9fe84cc96b9471ed1aaac17e3a4bae33a115df4e5834f18":"d7c562370af617b581c84a2468cc8bd50bb1cbf322de41b7887ce07c0e5884ca":"b46d9f2d8c4bf83546ff178f1d78937c008d64e8ecc5cbb825cb21d94d670d89"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 5
+ecdsa_sig:"dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7":"53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d":"5d833e8d24cc7a402d7ee7ec852a3587cddeb48358cea71b0bedb8fabe84e0c4":"18caaf7b663507a8bcd992b836dec9dc5703c080af5e51dfa3a9a7c387182604":"77c68928ac3b88d985fb43fb615fb7ff45c18ba5c81af796c613dfa98352d29c"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 6
+ecdsa_sig:"600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71":"4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d":"e18f96f84dfa2fd3cdfaec9159d4c338cd54ad314134f0b31e20591fc238d0ab":"8524c5024e2d9a73bde8c72d9129f57873bbad0ed05215a372a84fdbc78f2e68":"d18c2caf3b1072f87064ec5e8953f51301cada03469c640244760328eb5a05cb"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 7
+ecdsa_sig:"dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b":"78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab":"295544dbb2da3da170741c9b2c6551d40af7ed4e891445f11a02b66a5c258a77":"c5a186d72df452015480f7f338970bfe825087f05c0088d95305f87aacc9b254":"84a58f9e9d9e735344b316b1aa1ab5185665b85147dc82d92e969d7bee31ca30"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 8
+ecdsa_sig:"51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b":"80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a":"7c80fd66d62cc076cef2d030c17c0a69c99611549cb32c4ff662475adbe84b22":"9d0c6afb6df3bced455b459cc21387e14929392664bb8741a3693a1795ca6902":"d7f9ddd191f1f412869429209ee3814c75c72fa46a9cccf804a2f5cc0b7e739f"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 9
+ecdsa_sig:"558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8":"5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881":"2e7625a48874d86c9e467f890aaa7cd6ebdf71c0102bfdcfa24565d6af3fdce9":"2f9e2b4e9f747c657f705bffd124ee178bbc5391c86d056717b140c153570fd9":"f5413bfd85949da8d83de83ab0d19b2986613e224d1901d76919de23ccd03199"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 10
+ecdsa_sig:"4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e":"f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308":"62f8665fd6e26b3fa069e85281777a9b1f0dfd2c0b9f54a086d0c109ff9fd615":"1cc628533d0004b2b20e7f4baad0b8bb5e0673db159bbccf92491aef61fc9620":"880e0bbf82a8cf818ed46ba03cf0fc6c898e36fca36cc7fdb1d2db7503634430"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 11
+ecdsa_sig:"f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a":"b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906":"72b656f6b35b9ccbc712c9f1f3b1a14cbbebaec41c4bca8da18f492a062d6f6f":"9886ae46c1415c3bc959e82b760ad760aab66885a84e620aa339fdf102465c42":"2bf3a80bc04faa35ebecc0f4864ac02d349f6f126e0f988501b8d3075409a26c"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 12
+ecdsa_sig:"3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4":"d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7":"d926fe10f1bfd9855610f4f5a3d666b1a149344057e35537373372ead8b1a778":"490efd106be11fc365c7467eb89b8d39e15d65175356775deab211163c2504cb":"644300fc0da4d40fb8c6ead510d14f0bd4e1321a469e9c0a581464c7186b7aa7"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 13
+ecdsa_sig:"c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7":"b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c":"e158bf4a2d19a99149d9cdb879294ccb7aaeae03d75ddd616ef8ae51a6dc1071":"e67a9717ccf96841489d6541f4f6adb12d17b59a6bef847b6183b8fcf16a32eb":"9ae6ba6d637706849a6a9fc388cf0232d85c26ea0d1fe7437adb48de58364333"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 14
+ecdsa_sig:"72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01":"54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1":"646fe933e96c3b8f9f507498e907fdd201f08478d0202c752a7c2cfebf4d061a":"b53ce4da1aa7c0dc77a1896ab716b921499aed78df725b1504aba1597ba0c64b":"d7c246dc7ad0e67700c373edcfdd1c0a0495fc954549ad579df6ed1438840851"
+
+ECDSA signature - NIST CAVP FIPS 186-4 vector 15
+ecdsa_sig:"21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34":"34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1":"a6f463ee72c9492bc792fe98163112837aebd07bab7a84aaed05be64db3086f4":"542c40a18140a6266d6f0286e24e9a7bad7650e72ef0e2131e629c076d962663":"4f7f65305e24a6bbb5cff714ba8f5a2cee5bdc89ba8d75dcbf21966ce38eb66f"
diff --git a/tests/suites/test_suite_tinycrypt.function b/tests/suites/test_suite_tinycrypt.function
index 3247e054d..ac3492941 100644
--- a/tests/suites/test_suite_tinycrypt.function
+++ b/tests/suites/test_suite_tinycrypt.function
@@ -4,6 +4,8 @@
#include "tinycrypt/ecc_dh.h"
#include "tinycrypt/ecc_dsa.h"
+#include "mbedtls/sha256.h"
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -56,6 +58,26 @@ void test_ecdsa()
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_USE_TINYCRYPT */
+void ecdh_primitive_vector( data_t * qx_str, data_t * qy_str,
+ data_t * d_str, data_t * z_str )
+{
+ uint8_t public[2*NUM_ECC_BYTES] = {0};
+ uint8_t private[NUM_ECC_BYTES] = {0};
+ uint8_t secret[NUM_ECC_BYTES] = {0};
+
+ memcpy( public, qx_str->x, qx_str->len );
+ memcpy( public + NUM_ECC_BYTES, qy_str->x, qy_str->len );
+
+ memcpy( private, d_str->x, d_str->len );
+
+ // Compute shared secret and compare to test vector secret
+ TEST_ASSERT( uECC_shared_secret( public, d_str->x, secret ) == UECC_SUCCESS );
+
+ TEST_ASSERT( memcmp( secret, z_str->x, sizeof( secret ) ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_USE_TINYCRYPT */
void ecdh_primitive_testvec( data_t * private1, data_t * xA_str,
data_t * yA_str, data_t * private2,
data_t * xB_str, data_t * yB_str, data_t * z_str )
@@ -82,6 +104,47 @@ void ecdh_primitive_testvec( data_t * private1, data_t * xA_str,
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_USE_TINYCRYPT */
+void ecdsa_verify_msg( data_t * message, data_t * xQ_str, data_t * yQ_str,
+ data_t * r_str, data_t * s_str,
+ int res )
+{
+ uint8_t pub_bytes[2*NUM_ECC_BYTES] = {0};
+ uint8_t sig_bytes[2*NUM_ECC_BYTES] = {0};
+ unsigned char hash[32] = {0};
+
+ memcpy( pub_bytes, xQ_str->x, xQ_str->len );
+ memcpy( pub_bytes + NUM_ECC_BYTES, yQ_str->x, yQ_str->len );
+ memcpy( sig_bytes, r_str->x, r_str->len );
+ memcpy( sig_bytes + NUM_ECC_BYTES, s_str->x, r_str->len );
+
+ TEST_ASSERT( mbedtls_sha256_ret( message->x, message->len, hash, 0 ) == 0 );
+ TEST_ASSERT( uECC_verify( pub_bytes, hash, sizeof(hash),
+ sig_bytes ) == res );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_USE_TINYCRYPT */
+void ecdsa_sig( data_t * message, data_t * d_str, data_t * k_str,
+ data_t * r_str, data_t * s_str )
+{
+ uint8_t sig_bytes[2*NUM_ECC_BYTES] = {0};
+ uint8_t hash[32] = {0};
+ uint8_t k[NUM_ECC_BYTES] = {0};
+ uint8_t i = 0;
+ /* Reverse k as expected by tinycrypt */
+ for( i = 0; i < NUM_ECC_BYTES; i++ )
+ {
+ k[i] = k_str->x[NUM_ECC_BYTES - i - 1];
+ }
+ TEST_ASSERT( mbedtls_sha256_ret( message->x, message->len, hash, 0 ) == 0 );
+ TEST_ASSERT( uECC_sign_with_k( d_str->x, hash, sizeof(hash), (uECC_word_t*) k,
+ sig_bytes ) == UECC_SUCCESS );
+ TEST_ASSERT( memcmp( sig_bytes, r_str->x, NUM_ECC_BYTES) == 0 );
+ TEST_ASSERT( memcmp( sig_bytes + NUM_ECC_BYTES, s_str->x, NUM_ECC_BYTES ) == 0 );
+}
+/* END_CASE */
+
+/* BEGIN_CASE depends_on:MBEDTLS_USE_TINYCRYPT */
void ecdsa_primitive_testvec( data_t * xQ_str, data_t * yQ_str,
data_t * hash, data_t * r_str, data_t * s_str )
{
diff --git a/tinycrypt/ecc.c b/tinycrypt/ecc.c
index aeb6447f3..1a1643836 100644
--- a/tinycrypt/ecc.c
+++ b/tinycrypt/ecc.c
@@ -63,12 +63,25 @@
#include MBEDTLS_CONFIG_FILE
#endif
+#if defined(MBEDTLS_USE_TINYCRYPT)
#include <tinycrypt/ecc.h>
#include "mbedtls/platform_util.h"
#include "mbedtls/sha256.h"
#include <string.h>
#include "mbedtls/platform_util.h"
+#if defined(MBEDTLS_PLATFORM_FAULT_CALLBACKS)
+#include "platform_fault.h"
+#else
+static void mbedtls_platform_fault(){}
+#endif
+
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM
+#ifndef asm
+#define asm __asm
+#endif
+#endif /* MBEDTLS_OPTIMIZE_TINYCRYPT_ASM */
+
/* Parameters for curve NIST P-256 aka secp256r1 */
const uECC_word_t curve_p[NUM_ECC_WORDS] = {
BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF),
@@ -153,7 +166,7 @@ static int uECC_check_curve_integrity(void)
0x76, 0x0a, 0xe2, 0xbc, 0xce, 0x2a, 0xa2, 0xc6,
0x38, 0xf2, 0x19, 0x1d, 0x76, 0x72, 0x93, 0x49,
};
- unsigned char diff = 0;
+ int diff = 0;
unsigned char tmp1, tmp2;
volatile unsigned i;
@@ -170,7 +183,7 @@ static int uECC_check_curve_integrity(void)
/* i should be 32 */
mbedtls_platform_random_delay();
- diff |= (unsigned char) i ^ 32;
+ diff |= i ^ 32;
return diff;
}
@@ -203,6 +216,64 @@ int uECC_curve_public_key_size(void)
return 2 * NUM_ECC_BYTES;
}
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
+__asm void uECC_vli_clear(uECC_word_t *vli)
+{
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+#if !defined __thumb__ || __TARGET_ARCH_THUMB < 4
+ MOVS r1,#0
+ MOVS r2,#0
+ STMIA r0!,{r1,r2}
+ STMIA r0!,{r1,r2}
+ STMIA r0!,{r1,r2}
+ STMIA r0!,{r1,r2}
+ BX lr
+#else
+ MOVS r1,#0
+ STRD r1,r1,[r0,#0] // Only Thumb2 STRD can store same reg twice, not ARM
+ STRD r1,r1,[r0,#8]
+ STRD r1,r1,[r0,#16]
+ STRD r1,r1,[r0,#24]
+ BX lr
+#endif
+}
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
+void uECC_vli_clear(uECC_word_t *vli)
+{
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+#if !defined __thumb__ || !defined __thumb2__
+ register uECC_word_t *r0 asm("r0") = vli;
+ register uECC_word_t r1 asm("r1") = 0;
+ register uECC_word_t r2 asm("r2") = 0;
+ asm volatile (
+ ".syntax unified \n\t"
+ "STMIA r0!,{r1,r2} \n\t"
+ "STMIA r0!,{r1,r2} \n\t"
+ "STMIA r0!,{r1,r2} \n\t"
+ "STMIA r0!,{r1,r2} \n\t"
+ ".syntax divided \n\t"
+ : "+r" (r0)
+ : "r" (r1), "r" (r2)
+ : "memory"
+#else
+ register uECC_word_t *r0 asm("r0") = vli;
+ register uECC_word_t r1 asm("r1") = 0;
+ asm volatile (
+ "STRD r1,r1,[r0,#0] \n\t" // Only Thumb2 STRD can store same reg twice, not ARM
+ "STRD r1,r1,[r0,#8] \n\t"
+ "STRD r1,r1,[r0,#16] \n\t"
+ "STRD r1,r1,[r0,#24] \n\t"
+ :
+ : "r" (r0), "r" (r1)
+ : "memory"
+#endif
+ );
+}
+#else
void uECC_vli_clear(uECC_word_t *vli)
{
wordcount_t i;
@@ -210,7 +281,112 @@ void uECC_vli_clear(uECC_word_t *vli)
vli[i] = 0;
}
}
+#endif
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
+__asm uECC_word_t uECC_vli_isZero(const uECC_word_t *vli)
+{
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+#if defined __thumb__ && __TARGET_ARCH_THUMB < 4
+ LDMIA r0!,{r1,r2,r3}
+ ORRS r1,r2
+ ORRS r1,r3
+ LDMIA r0!,{r2,r3}
+ ORRS r1,r2
+ ORRS r1,r3
+ LDMIA r0,{r0,r2,r3}
+ ORRS r1,r0
+ ORRS r1,r2
+ ORRS r1,r3
+ RSBS r1,r1,#0 // C set if zero
+ MOVS r0,#0
+ ADCS r0,r0
+ BX lr
+#else
+ LDMIA r0!,{r1,r2,r3,ip}
+ ORRS r1,r2
+ ORRS r1,r3
+ ORRS r1,ip
+ LDMIA r0,{r0,r2,r3,ip}
+ ORRS r1,r0
+ ORRS r1,r2
+ ORRS r1,r3
+ ORRS r1,ip
+#ifdef __ARM_FEATURE_CLZ
+ CLZ r0,r1 // 32 if zero
+ LSRS r0,r0,#5
+#else
+ RSBS r1,r1,#0 // C set if zero
+ MOVS r0,#0
+ ADCS r0,r0
+#endif
+ BX lr
+#endif
+}
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
+uECC_word_t uECC_vli_isZero(const uECC_word_t *vli)
+{
+ uECC_word_t ret;
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+#if defined __thumb__ && !defined __thumb2__
+ register uECC_word_t r1 asm ("r1");
+ register uECC_word_t r2 asm ("r2");
+ register uECC_word_t r3 asm ("r3");
+ asm volatile (
+ ".syntax unified \n\t"
+ "LDMIA %[vli]!,{%[r1],%[r2],%[r3]} \n\t"
+ "ORRS %[r1],%[r2] \n\t"
+ "ORRS %[r1],%[r3] \n\t"
+ "LDMIA %[vli]!,{%[r2],%[r3]} \n\t"
+ "ORRS %[r1],%[r2] \n\t"
+ "ORRS %[r1],%[r3] \n\t"
+ "LDMIA %[vli],{%[vli],%[r2],%[r3]} \n\t"
+ "ORRS %[r1],%[vli] \n\t"
+ "ORRS %[r1],%[r2] \n\t"
+ "ORRS %[r1],%[r3] \n\t"
+ "RSBS %[r1],%[r1],#0 \n\t" // C set if zero
+ "MOVS %[ret],#0 \n\t"
+ "ADCS %[ret],r0 \n\t"
+ ".syntax divided \n\t"
+ : [ret]"=r" (ret), [r1]"=r" (r1), [r2]"=r" (r2), [r3]"=r" (r3)
+ : [vli]"[ret]" (vli)
+ : "cc", "memory"
+ );
+#else
+ register uECC_word_t r1 asm ("r1");
+ register uECC_word_t r2 asm ("r2");
+ register uECC_word_t r3 asm ("r3");
+ register uECC_word_t ip asm ("ip");
+ asm volatile (
+ "LDMIA %[vli]!,{%[r1],%[r2],%[r3],%[ip]}\n\t"
+ "ORRS %[r1],%[r2] \n\t"
+ "ORRS %[r1],%[r3] \n\t"
+ "ORRS %[r1],%[ip] \n\t"
+ "LDMIA %[vli],{%[vli],%[r2],%[r3],%[ip]}\n\t"
+ "ORRS %[r1],%[vli] \n\t"
+ "ORRS %[r1],%[r2] \n\t"
+ "ORRS %[r1],%[r3] \n\t"
+ "ORRS %[r1],%[ip] \n\t"
+#if __ARM_ARCH >= 5
+ "CLZ %[ret],%[r1] \n\t" // r0 = 32 if zero
+ "LSRS %[ret],%[ret],#5 \n\t"
+#else
+ "RSBS %[r1],%[r1],#0 \n\t" // C set if zero
+ "MOVS %[ret],#0 \n\t"
+ "ADCS %[ret],r0 \n\t"
+#endif
+ : [ret]"=r" (ret), [r1]"=r" (r1), [r2]"=r" (r2), [r3]"=r" (r3), [ip]"=r" (ip)
+ : [vli]"[ret]" (vli)
+ : "cc", "memory"
+ );
+#endif
+ return ret;
+}
+#else
uECC_word_t uECC_vli_isZero(const uECC_word_t *vli)
{
uECC_word_t bits = 0;
@@ -220,6 +396,7 @@ uECC_word_t uECC_vli_isZero(const uECC_word_t *vli)
}
return (bits == 0);
}
+#endif
uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit)
{
@@ -252,9 +429,13 @@ bitcount_t uECC_vli_numBits(const uECC_word_t *vli)
}
digit = vli[num_digits - 1];
+#if defined __GNUC__ || defined __clang__ || defined __CC_ARM
+ i = uECC_WORD_BITS - __builtin_clz(digit);
+#else
for (i = 0; digit; ++i) {
digit >>= 1;
}
+#endif
return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i);
}
@@ -317,11 +498,130 @@ uECC_word_t uECC_vli_equal(const uECC_word_t *left, const uECC_word_t *right)
uECC_word_t cond_set(uECC_word_t p_true, uECC_word_t p_false, unsigned int cond)
{
- return (p_true*(cond)) | (p_false*(!cond));
+ return (p_true*(cond)) | (p_false*(cond ^ 1));
}
/* Computes result = left - right, returning borrow, in constant time.
* Can modify in place. */
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
+__asm uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
+ const uECC_word_t *right)
+{
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+#if defined __thumb__ && __TARGET_ARCH_THUMB < 4
+ PUSH {r4-r6,lr}
+ FRAME PUSH {r4-r6,lr}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ SUBS r3,r5
+ SBCS r4,r6
+ STMIA r0!,{r3,r4}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ SBCS r3,r5
+ SBCS r4,r6
+ STMIA r0!,{r3,r4}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ SBCS r3,r5
+ SBCS r4,r6
+ STMIA r0!,{r3,r4}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ SBCS r3,r5
+ SBCS r4,r6
+ STMIA r0!,{r3,r4}
+ SBCS r0,r0 // r0 := r0 - r0 - borrow = -borrow
+ RSBS r0,r0,#0 // r0 := borrow
+ POP {r4-r6,pc}
+#else
+ PUSH {r4-r8,lr}
+ FRAME PUSH {r4-r8,lr}
+ LDMIA r1!,{r3-r6}
+ LDMIA r2!,{r7,r8,r12,lr}
+ SUBS r3,r7
+ SBCS r4,r8
+ SBCS r5,r12
+ SBCS r6,lr
+ STMIA r0!,{r3-r6}
+ LDMIA r1!,{r3-r6}
+ LDMIA r2!,{r7,r8,r12,lr}
+ SBCS r3,r7
+ SBCS r4,r8
+ SBCS r5,r12
+ SBCS r6,lr
+ STMIA r0!,{r3-r6}
+ SBCS r0,r0 // r0 := r0 - r0 - borrow = -borrow
+ RSBS r0,r0,#0 // r0 := borrow
+ POP {r4-r8,pc}
+#endif
+}
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
+uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
+ const uECC_word_t *right)
+{
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+ register uECC_word_t *r0 asm ("r0") = result;
+ register const uECC_word_t *r1 asm ("r1") = left;
+ register const uECC_word_t *r2 asm ("r2") = right;
+ asm volatile (
+#if defined __thumb__ && !defined __thumb2__
+ ".syntax unified \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "SUBS r3,r5 \n\t"
+ "SBCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "SBCS r3,r5 \n\t"
+ "SBCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "SBCS r3,r5 \n\t"
+ "SBCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "SBCS r3,r5 \n\t"
+ "SBCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "SBCS r0,r0 \n\t" // r0 := r0 - r0 - borrow = -borrow
+ "RSBS r0,r0,#0 \n\t" // r0 := borrow
+ ".syntax divided \n\t"
+ : "+r" (r0), "+r" (r1), "+r" (r2)
+ :
+ : "r3", "r4", "r5", "r6", "cc", "memory"
+#else
+ "LDMIA r1!,{r3-r6} \n\t"
+ "LDMIA r2!,{r7,r8,r12,lr} \n\t"
+ "SUBS r3,r7 \n\t"
+ "SBCS r4,r8 \n\t"
+ "SBCS r5,r12 \n\t"
+ "SBCS r6,lr \n\t"
+ "STMIA r0!,{r3-r6} \n\t"
+ "LDMIA r1!,{r3-r6} \n\t"
+ "LDMIA r2!,{r7,r8,r12,lr} \n\t"
+ "SBCS r3,r7 \n\t"
+ "SBCS r4,r8 \n\t"
+ "SBCS r5,r12 \n\t"
+ "SBCS r6,lr \n\t"
+ "STMIA r0!,{r3-r6} \n\t"
+ "SBCS r0,r0 \n\t" // r0 := r0 - r0 - borrow = -borrow
+ "RSBS r0,r0,#0 \n\t" // r0 := borrow
+ : "+r" (r0), "+r" (r1), "+r" (r2)
+ :
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r12", "lr", "cc", "memory"
+#endif
+ );
+ return (uECC_word_t) r0;
+}
+#else
uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right)
{
@@ -336,9 +636,127 @@ uECC_word_t uECC_vli_sub(uECC_word_t *result, const uECC_word_t *left,
}
return borrow;
}
+#endif
/* Computes result = left + right, returning carry, in constant time.
* Can modify in place. */
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
+static __asm uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
+ const uECC_word_t *right)
+{
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+#if defined __thumb__ && __TARGET_ARCH_THUMB < 4
+ PUSH {r4-r6,lr}
+ FRAME PUSH {r4-r6,lr}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ ADDS r3,r5
+ ADCS r4,r6
+ STMIA r0!,{r3,r4}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ ADCS r3,r5
+ ADCS r4,r6
+ STMIA r0!,{r3,r4}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ ADCS r3,r5
+ ADCS r4,r6
+ STMIA r0!,{r3,r4}
+ LDMIA r1!,{r3,r4}
+ LDMIA r2!,{r5,r6}
+ ADCS r3,r5
+ ADCS r4,r6
+ STMIA r0!,{r3,r4}
+ MOVS r0,#0 // does not affect C flag
+ ADCS r0,r0 // r0 := 0 + 0 + C = carry
+ POP {r4-r6,pc}
+#else
+ PUSH {r4-r8,lr}
+ FRAME PUSH {r4-r8,lr}
+ LDMIA r1!,{r3-r6}
+ LDMIA r2!,{r7,r8,r12,lr}
+ ADDS r3,r7
+ ADCS r4,r8
+ ADCS r5,r12
+ ADCS r6,lr
+ STMIA r0!,{r3-r6}
+ LDMIA r1!,{r3-r6}
+ LDMIA r2!,{r7,r8,r12,lr}
+ ADCS r3,r7
+ ADCS r4,r8
+ ADCS r5,r12
+ ADCS r6,lr
+ STMIA r0!,{r3-r6}
+ MOVS r0,#0 // does not affect C flag
+ ADCS r0,r0 // r0 := 0 + 0 + C = carry
+ POP {r4-r8,pc}
+#endif
+}
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
+static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
+ const uECC_word_t *right)
+{
+ register uECC_word_t *r0 asm ("r0") = result;
+ register const uECC_word_t *r1 asm ("r1") = left;
+ register const uECC_word_t *r2 asm ("r2") = right;
+
+ asm volatile (
+#if defined __thumb__ && !defined __thumb2__
+ ".syntax unified \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "ADDS r3,r5 \n\t"
+ "ADCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "ADCS r3,r5 \n\t"
+ "ADCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "ADCS r3,r5 \n\t"
+ "ADCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "LDMIA r1!,{r3,r4} \n\t"
+ "LDMIA r2!,{r5,r6} \n\t"
+ "ADCS r3,r5 \n\t"
+ "ADCS r4,r6 \n\t"
+ "STMIA r0!,{r3,r4} \n\t"
+ "MOVS r0,#0 \n\t" // does not affect C flag
+ "ADCS r0,r0 \n\t" // r0 := 0 + 0 + C = carry
+ ".syntax divided \n\t"
+ : "+r" (r0), "+r" (r1), "+r" (r2)
+ :
+ : "r3", "r4", "r5", "r6", "cc", "memory"
+#else
+ "LDMIA r1!,{r3-r6} \n\t"
+ "LDMIA r2!,{r7,r8,r12,lr} \n\t"
+ "ADDS r3,r7 \n\t"
+ "ADCS r4,r8 \n\t"
+ "ADCS r5,r12 \n\t"
+ "ADCS r6,lr \n\t"
+ "STMIA r0!,{r3-r6} \n\t"
+ "LDMIA r1!,{r3-r6} \n\t"
+ "LDMIA r2!,{r7,r8,r12,lr} \n\t"
+ "ADCS r3,r7 \n\t"
+ "ADCS r4,r8 \n\t"
+ "ADCS r5,r12 \n\t"
+ "ADCS r6,lr \n\t"
+ "STMIA r0!,{r3-r6} \n\t"
+ "MOVS r0,#0 \n\t" // does not affect C flag
+ "ADCS r0,r0 \n\t" // r0 := 0 + 0 + C = carry
+ : "+r" (r0), "+r" (r1), "+r" (r2)
+ :
+ : "r3", "r4", "r5", "r6", "r7", "r8", "r12", "lr", "cc", "memory"
+#endif
+ );
+ return (uECC_word_t) r0;
+}
+#else
static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right)
{
@@ -352,16 +770,83 @@ static uECC_word_t uECC_vli_add(uECC_word_t *result, const uECC_word_t *left,
}
return carry;
}
+#endif
cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right)
{
uECC_word_t tmp[NUM_ECC_WORDS];
- uECC_word_t neg = !!uECC_vli_sub(tmp, left, right);
+ uECC_word_t neg = uECC_vli_sub(tmp, left, right);
uECC_word_t equal = uECC_vli_isZero(tmp);
- return (!equal - 2 * neg);
+ return ((equal ^ 1) - 2 * neg);
}
/* Computes vli = vli >> 1. */
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
+static __asm void uECC_vli_rshift1(uECC_word_t *vli)
+{
+#if defined __thumb__ && __TARGET_ARCH_THUMB < 4
+// RRX instruction is not available, so although we
+// can use C flag, it's not that effective. Does at
+// least save one working register, meaning we don't need stack
+ MOVS r3,#0 // initial carry = 0
+ MOVS r2,#__cpp(4 * (NUM_ECC_WORDS - 1))
+01 LDR r1,[r0,r2]
+ LSRS r1,r1,#1 // r2 = word >> 1
+ ORRS r1,r3 // merge in the previous carry
+ STR r1,[r0,r2]
+ ADCS r3,r3 // put C into bottom bit of r3
+ LSLS r3,r3,#31 // shift it up to the top ready for next word
+ SUBS r2,r2,#4
+ BPL %B01
+ BX lr
+#else
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+// Smooth multiword operation, lots of 32-bit instructions
+ ADDS r0,#32
+ LDMDB r0,{r1-r3,ip}
+ LSRS ip,ip,#1
+ RRXS r3,r3
+ RRXS r2,r2
+ RRXS r1,r1
+ STMDB r0!,{r1-r3,ip}
+ LDMDB r0,{r1-r3,ip}
+ RRXS ip,ip
+ RRXS r3,r3
+ RRXS r2,r2
+ RRX r1,r1
+ STMDB r0!,{r1-r3,ip}
+ BX lr
+#endif
+}
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__ && defined __thumb2__
+static void uECC_vli_rshift1(uECC_word_t *vli)
+{
+ register uECC_word_t *r0 asm ("r0") = vli;
+#if NUM_ECC_WORDS != 8
+#error adjust ARM assembly to handle NUM_ECC_WORDS != 8
+#endif
+ asm volatile (
+ "ADDS r0,#32 \n\t"
+ "LDMDB r0,{r1-r3,ip} \n\t"
+ "LSRS ip,ip,#1 \n\t"
+ "RRXS r3,r3 \n\t"
+ "RRXS r2,r2 \n\t"
+ "RRXS r1,r1 \n\t"
+ "STMDB r0!,{r1-r3,ip} \n\t"
+ "LDMDB r0,{r1-r3,ip} \n\t"
+ "RRXS ip,ip \n\t"
+ "RRXS r3,r3 \n\t"
+ "RRXS r2,r2 \n\t"
+ "RRX r1,r1 \n\t"
+ "STMDB r0!,{r1-r3,ip} \n\t"
+ : "+r" (r0)
+ :
+ : "r1", "r2", "r3", "ip", "cc", "memory"
+ );
+}
+#else
static void uECC_vli_rshift1(uECC_word_t *vli)
{
uECC_word_t *end = vli;
@@ -374,29 +859,135 @@ static void uECC_vli_rshift1(uECC_word_t *vli)
carry = temp << (uECC_WORD_BITS - 1);
}
}
+#endif
-/* Compute a * b + r, where r is a double-word with high-order word r1 and
- * low-order word r0, and store the result in the same double-word (r1, r0),
- * with the carry bit stored in r2.
+/* Compute a * b + r, where r is a triple-word with high-order word r[2] and
+ * low-order word r[0], and store the result in the same triple-word.
*
- * (r2, r1, r0) = a * b + (r1, r0):
+ * r[2..0] = a * b + r[2..0]:
* [in] a, b: operands to be multiplied
- * [in] r0, r1: low and high-order words of operand to add
- * [out] r0, r1: low and high-order words of the result
- * [out] r2: carry
+ * [in] r: 3 words of operand to add
+ * [out] r: 3 words of result
*/
-static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t *r0,
- uECC_word_t *r1, uECC_word_t *r2)
+#if defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __CC_ARM
+static __asm void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t r[3])
+{
+#if defined __thumb__ && __TARGET_ARCH_THUMB < 4
+ PUSH {r4-r5}
+ FRAME PUSH {r4-r5}
+ // __ARM_common_mul_uu replacement - inline, faster, don't touch R2
+ // Separate operands into halfwords
+ UXTH r3,r0 // r3 := a.lo
+ LSRS r4,r0,#16 // r4 := a.hi
+ UXTH r5,r1 // r5 := b.lo
+ LSRS r1,r1,#16 // r1 := b.hi
+ // Multiply halfword pairs
+ MOVS r0,r3
+ MULS r0,r5,r0 // r0 := a.lo * b.lo
+ MULS r3,r1,r3 // r3 := a.lo * b.hi
+ MULS r5,r4,r5 // r5 := a.hi * b.lo
+ MULS r1,r4,r1 // r1 := a.hi * b.hi
+ // Split, shift and add a.lo * b.hi
+ LSRS r4,r3,#16 // r4 := (a.lo * b.hi).hi
+ LSLS r3,r3,#16 // r3 := (a.lo * b.hi).lo
+ ADDS r0,r0,r3 // r0 := a.lo * b.lo + (a.lo * b.hi).lo
+ ADCS r1,r4 // r1 := a.hi * b.hi + (a.lo * b.hi).hi + carry
+ // Split, shift and add a.hi * b.lo
+ LSRS r4,r5,#16 // r4 := (a.hi * b.lo).hi
+ LSLS r5,r5,#16 // r5 := (a.hi * b.lo).lo
+ ADDS r0,r0,r5 // r0 := a.lo * b.lo + (a.lo * b.hi).lo + (a.hi * b.lo).lo
+ ADCS r1,r4 // r1 := a.hi * b.hi + (a.lo * b.hi).hi + (a.hi * b.lo).hi + carries
+ // Finally add r[]
+ LDMIA r2!,{r3,r4,r5}
+ ADDS r3,r3,r0
+ ADCS r4,r1
+ MOVS r0,#0
+ ADCS r5,r0
+ SUBS r2,#12
+ STMIA r2!,{r3,r4,r5}
+ POP {r4-r5}
+ FRAME POP {r4-r5}
+ BX lr
+#else
+ UMULL r3,ip,r0,r1 // pre-ARMv6 requires Rd[Lo|Hi] != Rn
+ LDMIA r2,{r0,r1}
+ ADDS r0,r0,r3
+ LDR r3,[r2,#8]
+ ADCS r1,r1,ip
+ ADC r3,r3,#0
+ STMIA r2!,{r0,r1,r3}
+ BX lr
+#endif
+}
+#elif defined MBEDTLS_OPTIMIZE_TINYCRYPT_ASM && defined __GNUC__ && defined __arm__
+static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t r[3])
+{
+ register uECC_word_t r0 asm ("r0") = a;
+ register uECC_word_t r1 asm ("r1") = b;
+ register uECC_word_t *r2 asm ("r2") = r;
+ asm volatile (
+#if defined __thumb__ && !defined(__thumb2__)
+ ".syntax unified \n\t"
+ // __ARM_common_mul_uu replacement - inline, faster, don't touch R2
+ // Separate operands into halfwords
+ "UXTH r3,r0 \n\t" // r3 := a.lo
+ "LSRS r4,r0,#16 \n\t" // r4 := a.hi
+ "UXTH r5,r1 \n\t" // r5 := b.lo
+ "LSRS r1,r1,#16 \n\t" // r1 := b.hi
+ // Multiply halfword pairs
+ "MOVS r0,r3 \n\t"
+ "MULS r0,r5,r0 \n\t" // r0 := a.lo * b.lo
+ "MULS r3,r1,r3 \n\t" // r3 := a.lo * b.hi
+ "MULS r5,r4,r5 \n\t" // r5 := a.hi * b.lo
+ "MULS r1,r4,r1 \n\t" // r1 := a.hi * b.hi
+ // Split, shift and add a.lo * b.hi
+ "LSRS r4,r3,#16 \n\t" // r4 := (a.lo * b.hi).hi
+ "LSLS r3,r3,#16 \n\t" // r3 := (a.lo * b.hi).lo
+ "ADDS r0,r0,r3 \n\t" // r0 := a.lo * b.lo + (a.lo * b.hi).lo
+ "ADCS r1,r4 \n\t" // r1 := a.hi * b.hi + (a.lo * b.hi).hi + carry
+ // Split, shift and add a.hi * b.lo
+ "LSRS r4,r5,#16 \n\t" // r4 := (a.hi * b.lo).hi
+ "LSLS r5,r5,#16 \n\t" // r5 := (a.hi * b.lo).lo
+ "ADDS r0,r0,r5 \n\t" // r0 := a.lo * b.lo + (a.lo * b.hi).lo + (a.hi * b.lo).lo
+ "ADCS r1,r4 \n\t" // r1 := a.hi * b.hi + (a.lo * b.hi).hi + (a.hi * b.lo).hi + carries
+ // Finally add r[]
+ "LDMIA r2!,{r3,r4,r5} \n\t"
+ "ADDS r3,r3,r0 \n\t"
+ "ADCS r4,r1 \n\t"
+ "MOVS r0,#0 \n\t"
+ "ADCS r5,r0 \n\t"
+ "SUBS r2,#12 \n\t"
+ "STMIA r2!,{r3,r4,r5} \n\t"
+ ".syntax divided \n\t"
+ : "+r" (r0), "+r" (r1), "+r" (r2)
+ :
+ : "r3", "r4", "r5", "ip", "cc", "memory"
+#else
+ "UMULL r3,ip,r0,r1 \n\t" // pre-ARMv6 requires Rd[Lo|Hi] != Rn
+ "LDMIA r2,{r0,r1} \n\t"
+ "ADDS r0,r0,r3 \n\t"
+ "LDR r3,[r2,#8] \n\t"
+ "ADCS r1,r1,ip \n\t"
+ "ADC r3,r3,#0 \n\t"
+ "STMIA r2!,{r0,r1,r3} \n\t"
+ : "+r" (r0), "+r" (r1), "+r" (r2)
+ :
+ : "r3", "ip", "cc", "memory"
+#endif
+ );
+}
+#else
+static void muladd(uECC_word_t a, uECC_word_t b, uECC_word_t r[3])
{
uECC_dword_t p = (uECC_dword_t)a * b;
- uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0;
+ uECC_dword_t r01 = ((uECC_dword_t)(r[1]) << uECC_WORD_BITS) | r[0];
r01 += p;
- *r2 += (r01 < p);
- *r1 = r01 >> uECC_WORD_BITS;
- *r0 = (uECC_word_t)r01;
-
+ r[2] += (r01 < p);
+ r[1] = r01 >> uECC_WORD_BITS;
+ r[0] = (uECC_word_t)r01;
}
+#endif
/* State for implementing random delays in uECC_vli_mult_rnd().
*
@@ -453,16 +1044,14 @@ static void uECC_vli_mult_rnd(uECC_word_t *result, const uECC_word_t *left,
const uECC_word_t *right, ecc_wait_state_t *s)
{
- uECC_word_t r0 = 0;
- uECC_word_t r1 = 0;
- uECC_word_t r2 = 0;
+ uECC_word_t r[3] = { 0, 0, 0 };
wordcount_t i, k;
const uint8_t num_words = NUM_ECC_WORDS;
/* Fetch 8 bit worth of delay from the state; 0 if we have no state */
uint8_t delays = s ? s->delays[s->i++] : 0;
- uECC_word_t rr0 = 0, rr1 = 0;
- volatile uECC_word_t r;
+ uECC_word_t rr[3] = { 0, 0, 0 };
+ volatile uECC_word_t rdummy;
/* Mimic start of next loop: k in [0, 3] */
k = 0 + (delays & 0x03);
@@ -470,24 +1059,23 @@ static void uECC_vli_mult_rnd(uECC_word_t *result, const uECC_word_t *left,
/* k = 0 -> i in [1, 0] -> 0 extra muladd;
* k = 3 -> i in [1, 3] -> 3 extra muladd */
for (i = 1; i <= k; ++i) {
- muladd(left[i], right[k - i], &rr0, &rr1, &r2);
+ muladd(left[i], right[k - i], rr);
}
- r = rr0;
- rr0 = rr1;
- rr1 = r2;
- r2 = 0;
+ rdummy = rr[0];
+ rr[0] = rr[1];
+ rr[1] = rr[2];
+ rr[2] = 0;
/* Compute each digit of result in sequence, maintaining the carries. */
for (k = 0; k < num_words; ++k) {
-
for (i = 0; i <= k; ++i) {
- muladd(left[i], right[k - i], &r0, &r1, &r2);
+ muladd(left[i], right[k - i], r);
}
- result[k] = r0;
- r0 = r1;
- r1 = r2;
- r2 = 0;
+ result[k] = r[0];
+ r[0] = r[1];
+ r[1] = r[2];
+ r[2] = 0;
}
/* Mimic end of previous loop: k in [4, 7] */
@@ -496,12 +1084,12 @@ static void uECC_vli_mult_rnd(uECC_word_t *result, const uECC_word_t *left,
/* k = 4 -> i in [5, 4] -> 0 extra muladd;
* k = 7 -> i in [5, 7] -> 3 extra muladd */
for (i = 5; i <= k; ++i) {
- muladd(left[i], right[k - i], &rr0, &rr1, &r2);
+ muladd(left[i], right[k - i], rr);
}
- r = rr0;
- rr0 = rr1;
- rr1 = r2;
- r2 = 0;
+ rdummy = rr[0];
+ rr[0] = rr[1];
+ rr[1] = rr[2];
+ rr[2] = 0;
/* Mimic start of next loop: k in [8, 11] */
k = 11 - (delays & 0x03);
@@ -509,25 +1097,25 @@ static void uECC_vli_mult_rnd(uECC_word_t *result, const uECC_word_t *left,
/* k = 8 -> i in [5, 7] -> 3 extra muladd;
* k = 11 -> i in [8, 7] -> 0 extra muladd */
for (i = (k + 5) - num_words; i < num_words; ++i) {
- muladd(left[i], right[k - i], &rr0, &rr1, &r2);
+ muladd(left[i], right[k - i], rr);
}
- r = rr0;
- rr0 = rr1;
- rr1 = r2;
- r2 = 0;
+ rdummy = rr[0];
+ rr[0] = rr[1];
+ rr[1] = rr[2];
+ rr[2] = 0;
for (k = num_words; k < num_words * 2 - 1; ++k) {
for (i = (k + 1) - num_words; i < num_words; ++i) {
- muladd(left[i], right[k - i], &r0, &r1, &r2);
+ muladd(left[i], right[k - i], r);
}
- result[k] = r0;
- r0 = r1;
- r1 = r2;
- r2 = 0;
+ result[k] = r[0];
+ r[0] = r[1];
+ r[1] = r[2];
+ r[2] = 0;
}
- result[num_words * 2 - 1] = r0;
+ result[num_words * 2 - 1] = r[0];
/* Mimic end of previous loop: k in [12, 15] */
k = 15 - (delays & 0x03);
@@ -535,15 +1123,15 @@ static void uECC_vli_mult_rnd(uECC_word_t *result, const uECC_word_t *left,
/* k = 12 -> i in [5, 7] -> 3 extra muladd;
* k = 15 -> i in [8, 7] -> 0 extra muladd */
for (i = (k + 1) - num_words; i < num_words; ++i) {
- muladd(left[i], right[k - i], &rr0, &rr1, &r2);
+ muladd(left[i], right[k - i], rr);
}
- r = rr0;
- rr0 = rr1;
- rr1 = r2;
- r2 = 0;
+ rdummy = rr[0];
+ rr[0] = rr[1];
+ rr[1] = rr[2];
+ rr[2] = 0;
- /* avoid warning that r is set but not used */
- (void) r;
+ /* avoid warning that rdummy is set but not used */
+ (void) rdummy;
}
void uECC_vli_modAdd(uECC_word_t *result, const uECC_word_t *left,
@@ -585,6 +1173,12 @@ void uECC_vli_mmod(uECC_word_t *result, uECC_word_t *product,
wordcount_t word_shift = shift / uECC_WORD_BITS;
wordcount_t bit_shift = shift % uECC_WORD_BITS;
uECC_word_t carry = 0;
+
+ if(word_shift > NUM_ECC_WORDS)
+ {
+ mbedtls_platform_fault();
+ }
+
uECC_vli_clear(mod_multiple);
if (bit_shift > 0) {
for(index = 0; index < (uECC_word_t)num_words; ++index) {
@@ -1028,10 +1622,20 @@ static void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
static uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0,
uECC_word_t *k1)
{
+ wordcount_t num_n_words = NUM_ECC_WORDS;
bitcount_t num_n_bits = NUM_ECC_BITS;
+ /* With our constant NUM_ECC_BITS and NUM_ECC_WORDS the
+ * check (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) always would have "false" result (256 < 256),
+ * therefore Coverity warning may be detected. Removing of this line without changing the entire check will cause to
+ * array overrun.
+ * The entire check is not changed on purpose to be aligned with original tinycrypt
+ * implementation and to allow upstreaming to other curves if required.
+ * Coverity specific annotation may be added to silence warning if exists.
+ */
uECC_word_t carry = uECC_vli_add(k0, k, curve_n) ||
- uECC_vli_testBit(k0, num_n_bits);
+ (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
+ uECC_vli_testBit(k0, num_n_bits));
uECC_vli_add(k1, k0, curve_n);
@@ -1268,3 +1872,4 @@ int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key)
return ret;
}
+#endif /* MBEDTLS_USE_TINYCRYPT */
diff --git a/tinycrypt/ecc_dh.c b/tinycrypt/ecc_dh.c
index 6285cf357..b6b1898d3 100644
--- a/tinycrypt/ecc_dh.c
+++ b/tinycrypt/ecc_dh.c
@@ -66,6 +66,7 @@
#include MBEDTLS_CONFIG_FILE
#endif
+#if defined(MBEDTLS_USE_TINYCRYPT)
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dh.h>
#include <string.h>
@@ -195,3 +196,4 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
return UECC_FAULT_DETECTED;
}
+#endif /* MBEDTLS_USE_TINYCRYPT */
diff --git a/tinycrypt/ecc_dsa.c b/tinycrypt/ecc_dsa.c
index d432a2e6a..fe3952c2d 100644
--- a/tinycrypt/ecc_dsa.c
+++ b/tinycrypt/ecc_dsa.c
@@ -64,6 +64,7 @@
#include MBEDTLS_CONFIG_FILE
#endif
+#if defined(MBEDTLS_USE_TINYCRYPT)
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dsa.h>
#include "mbedtls/platform_util.h"
@@ -314,3 +315,4 @@ int uECC_verify(const uint8_t *public_key, const uint8_t *message_hash,
return UECC_FAILURE;
}
+#endif /* MBEDTLS_USE_TINYCRYPT */