diff options
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( ¤t_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 */ |