From 465944b3963c54f1e58e780505734c4950a608f5 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Wed, 5 Jun 2019 16:37:52 +0100 Subject: [PATCH 01/13] mbed-crypto: Update to Mbed Crypto 1.1.0d1 --- features/mbedtls/mbed-crypto/VERSION.txt | 2 +- features/mbedtls/mbed-crypto/importer/Makefile | 2 +- .../COMPONENT_PSA_SRV_IMPL/psa_crypto.c | 9 +++++++++ features/mbedtls/mbed-crypto/src/dhm.c | 16 ++++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/features/mbedtls/mbed-crypto/VERSION.txt b/features/mbedtls/mbed-crypto/VERSION.txt index 9f6d3d3f0f..1c7cde3079 100644 --- a/features/mbedtls/mbed-crypto/VERSION.txt +++ b/features/mbedtls/mbed-crypto/VERSION.txt @@ -1 +1 @@ -mbedcrypto-1.1.0d0 +mbedcrypto-1.1.0d1 diff --git a/features/mbedtls/mbed-crypto/importer/Makefile b/features/mbedtls/mbed-crypto/importer/Makefile index 88fc2f120f..6e04195818 100644 --- a/features/mbedtls/mbed-crypto/importer/Makefile +++ b/features/mbedtls/mbed-crypto/importer/Makefile @@ -29,7 +29,7 @@ # Set the Mbed Crypto release to import (this can/should be edited before # import) -CRYPTO_RELEASE ?= mbedcrypto-1.1.0d0 +CRYPTO_RELEASE ?= mbedcrypto-1.1.0d1 CRYPTO_REPO_URL ?= git@github.com:ARMmbed/mbed-crypto.git # Translate between Mbed Crypto namespace and Mbed OS namespace diff --git a/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/psa_crypto.c b/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/psa_crypto.c index c9ee8c9901..3c318727fd 100644 --- a/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/psa_crypto.c +++ b/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/psa_crypto.c @@ -4639,6 +4639,15 @@ psa_status_t psa_crypto_init( void ) /* Initialize the random generator. */ global_data.entropy_init( &global_data.entropy ); +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ + defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) + /* The PSA entropy injection feature depends on using NV seed as an entropy + * source. Add NV seed as an entropy source for PSA entropy injection. */ + mbedtls_entropy_add_source( &global_data.entropy, + mbedtls_nv_seed_poll, NULL, + MBEDTLS_ENTROPY_BLOCK_SIZE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif mbedtls_ctr_drbg_init( &global_data.ctr_drbg ); global_data.rng_state = RNG_INITIALIZED; status = mbedtls_to_psa_error( diff --git a/features/mbedtls/mbed-crypto/src/dhm.c b/features/mbedtls/mbed-crypto/src/dhm.c index fb6937e854..8255632a99 100644 --- a/features/mbedtls/mbed-crypto/src/dhm.c +++ b/features/mbedtls/mbed-crypto/src/dhm.c @@ -649,12 +649,28 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) #if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PEM_PARSE_C) static const char mbedtls_test_dhm_params[] = "-----BEGIN DH PARAMETERS-----\r\n" "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" "-----END DH PARAMETERS-----\r\n"; +#else /* MBEDTLS_PEM_PARSE_C */ +static const char mbedtls_test_dhm_params[] = { + 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, + 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, + 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, + 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, + 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, + 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, + 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, + 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, + 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, + 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, + 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, + 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 }; +#endif /* MBEDTLS_PEM_PARSE_C */ static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); From 14ed96e72cd241e9356103522876442b06dabe4a Mon Sep 17 00:00:00 2001 From: adbridge Date: Fri, 7 Jun 2019 10:50:24 +0100 Subject: [PATCH 02/13] Re-enable complilation for wifi and nanostack examples --- tools/test/examples/examples.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/test/examples/examples.json b/tools/test/examples/examples.json index 7fd021d37f..14ada1e10a 100644 --- a/tools/test/examples/examples.json +++ b/tools/test/examples/examples.json @@ -117,8 +117,8 @@ "targets" : [], "toolchains" : [], "exporters": [], - "compile" : false, - "export": false, + "compile" : true, + "export": true, "auto-update" : true }, { @@ -130,9 +130,9 @@ "targets" : ["K66F", "NUCLEO_F429ZI"], "toolchains" : [], "exporters": [], - "compile" : false, - "export": false, - "auto-update" : false + "compile" : true, + "export": true, + "auto-update" : true }, { "name": "mbed-os-example-cellular", From 29446548f5fc17adf689bc6299f6a4ec2e8979db Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Wed, 29 May 2019 14:59:20 +0100 Subject: [PATCH 03/13] Default to Cordio BLE stack for NRF52* targets The BLE stack from SoftDevice is not actively maintained and has issues when used with Nordic SDK v15. --- targets/targets.json | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/targets/targets.json b/targets/targets.json index 8a525f8fd4..56bddbe805 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -7088,6 +7088,7 @@ "MBED_TICKLESS", "MBED_MPU_CUSTOM" ], + "features": ["BLE"], "device_has": [ "ANALOGIN", "FLASH", @@ -7115,9 +7116,10 @@ "NRF5x", "NRF52", "SDK_15_0", - "NORDIC_SOFTDEVICE", - "SOFTDEVICE_COMMON", - "SOFTDEVICE_S132_FULL" + "CORDIO", + "CORDIO_LL", + "SOFTDEVICE_NONE", + "NORDIC_CORDIO" ], "config": { "lf_clock_src": { @@ -7213,7 +7215,7 @@ "WSF_MAX_HANDLERS=10", "MBED_MPU_CUSTOM" ], - "features": ["CRYPTOCELL310"], + "features": ["CRYPTOCELL310", "BLE"], "device_has": [ "ANALOGIN", "FLASH", @@ -7242,9 +7244,10 @@ "NRF5x", "NRF52", "SDK_15_0", - "NORDIC_SOFTDEVICE", - "SOFTDEVICE_COMMON", - "SOFTDEVICE_S140_FULL" + "CORDIO", + "CORDIO_LL", + "SOFTDEVICE_NONE", + "NORDIC_CORDIO" ], "config": { "lf_clock_src": { From ad91527023edd964457f001fc690db8369f7794b Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Tue, 4 Jun 2019 10:42:43 +0100 Subject: [PATCH 04/13] critical_section tests: do not check APP interrupts on NRF52 APP interrupts are masked on SoftDevice BLE stack only, but we have switched to Cordio stack on NRF52 targets. --- TESTS/mbed_hal/critical_section/main.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/TESTS/mbed_hal/critical_section/main.cpp b/TESTS/mbed_hal/critical_section/main.cpp index c3ae160e33..b380972858 100644 --- a/TESTS/mbed_hal/critical_section/main.cpp +++ b/TESTS/mbed_hal/critical_section/main.cpp @@ -28,12 +28,9 @@ using utest::v1::Case; bool test_are_interrupts_enabled(void) { - // NRF5x targets don't disable interrupts when in critical section, instead they mask application interrupts this is due to BLE stack - // (BLE to be operational requires some interrupts to be always enabled) -#if defined(TARGET_NRF52) - // check if APP interrupts are masked for NRF52 boards - return (((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0) || ((NVIC->ISER[1] & __NRF_NVIC_APP_IRQS_1) != 0)); -#elif defined(TARGET_NRF51) + // NRF51 targets don't disable interrupts when in critical section, instead they mask application interrupts. + // This is due to SoftDevice BLE stack (BLE to be operational requires some interrupts to be always enabled) +#if defined(TARGET_NRF51) // check if APP interrupts are masked for other NRF51 boards return ((NVIC->ISER[0] & __NRF_NVIC_APP_IRQS_0) != 0); #else From 060734074881bf07b2547d5e18fbe2c00964e98b Mon Sep 17 00:00:00 2001 From: Lingkai Dong Date: Wed, 5 Jun 2019 09:43:36 +0100 Subject: [PATCH 05/13] NORDIC_CORDIC pal_crypto: check if cryptocell310 is enabled The config "cryptocell310-acceleration" is set by MCU_NRF52840 but individual targets may have crytocell310 feature disabled. --- .../TARGET_NRF5x/stack/sources/pal_crypto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c index fb87796ae7..adf87e670d 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c @@ -23,7 +23,7 @@ #include "pal_types.h" #include "pal_bb_ble.h" -#if defined(NRF52840_XXAA) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION +#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION #include "crys_rsa_kg.h" #include "crys_dh.h" #include "ssi_pal_types.h" @@ -34,7 +34,7 @@ /* Nordic specific definitions. */ #include "nrf_ecb.h" #include "nrf.h" -#if defined(NRF52840_XXAA) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION +#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION #include "nrf52840.h" #endif #include @@ -690,7 +690,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf) return TRUE; } -#if defined(NRF52840_XXAA) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION +#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION /*************************************************************************************************/ /*! * \brief Execute the CCM-Mode encryption algorithm. From 3b66065a1029112e4091c1607c915280fd7a2aa5 Mon Sep 17 00:00:00 2001 From: paul-szczepanek-arm <33840200+paul-szczepanek-arm@users.noreply.github.com> Date: Fri, 7 Jun 2019 13:50:30 +0100 Subject: [PATCH 06/13] exculde test --- .../targets/TARGET_CORDIO/TESTS/cordio_hci/transport/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/TESTS/cordio_hci/transport/main.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/TESTS/cordio_hci/transport/main.cpp index 3aaadbb453..e5ee4bc235 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/TESTS/cordio_hci/transport/main.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/TESTS/cordio_hci/transport/main.cpp @@ -33,6 +33,10 @@ using ble::vendor::cordio::CordioHCITransportDriver; extern ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver(); +#if CORDIO_ZERO_COPY_HCI +#error [NOT_SUPPORTED] Test not relevant for zero copy hci. +#endif + namespace ble { namespace vendor { namespace cordio { From 3a2bd249c6766e525a01a04b9563c8084f2016ad Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Tue, 11 Jun 2019 13:00:12 +0300 Subject: [PATCH 07/13] Fix ARMC5 compilation Minor tweaks to fix ARM C 5 compatibility. Pushing "ns_list.h" include to first makes sure "ns_types.h" is included first, meaning it gets to define `__STDC_LIMIT_MACROS` before the first include of , which ensures that UINT8_MAX etc are defined. --- features/netsocket/NetworkInterface.cpp | 2 +- platform/SingletonPtr.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/features/netsocket/NetworkInterface.cpp b/features/netsocket/NetworkInterface.cpp index e189218a81..48d463b590 100644 --- a/features/netsocket/NetworkInterface.cpp +++ b/features/netsocket/NetworkInterface.cpp @@ -14,12 +14,12 @@ * limitations under the License. */ +#include "ns_list.h" #include "netsocket/NetworkInterface.h" #include "netsocket/NetworkStack.h" #include "platform/Callback.h" #include "platform/mbed_error.h" #include -#include "ns_list.h" // Default network-interface state void NetworkInterface::set_as_default() diff --git a/platform/SingletonPtr.h b/platform/SingletonPtr.h index 9d2cc669ce..2bbb0a89b8 100644 --- a/platform/SingletonPtr.h +++ b/platform/SingletonPtr.h @@ -131,8 +131,8 @@ struct SingletonPtr { // This is zero initialized when in global scope mutable void *_ptr; -#if __cplusplus >= 201103L - // Align data appropriately +#if __cplusplus >= 201103L && !defined __CC_ARM + // Align data appropriately (ARM Compiler 5 does not support alignas in C++11 mode) alignas(T) mutable char _data[sizeof(T)]; #else // Force data to be 8 byte aligned From 1b124e03ca32874b66cfe6655203ee4d5af5c383 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Tue, 11 Jun 2019 17:13:27 +0300 Subject: [PATCH 08/13] ns_list: avoid UINT_FAST8_MAX Prevent compilation issues when someone has included before a header file that needs to include . Some toolchains like ARM C 5 will not provide UINT_FAST8_MAX in C++ unless __STDC_LIMIT_MACROS is defined, and if this was not defined the first time was included, it's too late. We can get the maximum value for our unsigned list offset by casting -1 to it, thanks to modulo arithmetic. --- .../nanostack-libservice/mbed-client-libservice/ns_list.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/frameworks/nanostack-libservice/mbed-client-libservice/ns_list.h b/features/frameworks/nanostack-libservice/mbed-client-libservice/ns_list.h index 0030d56dea..a4799fb4f3 100644 --- a/features/frameworks/nanostack-libservice/mbed-client-libservice/ns_list.h +++ b/features/frameworks/nanostack-libservice/mbed-client-libservice/ns_list.h @@ -148,7 +148,7 @@ union \ { \ ns_list_t slist; \ NS_FUNNY_COMPARE_OK \ - NS_STATIC_ASSERT(link_offset <= UINT_FAST8_MAX, "link offset too large") \ + NS_STATIC_ASSERT(link_offset <= (ns_list_offset_t) -1, "link offset too large") \ NS_FUNNY_COMPARE_RESTORE \ char (*offset)[link_offset + 1]; \ entry_type *type; \ From 0ebc05385f3657c1f8f97f4ebb5dfc1f10c60756 Mon Sep 17 00:00:00 2001 From: "desmond.chen" Date: Tue, 4 Jun 2019 14:51:32 +0800 Subject: [PATCH 09/13] Fix nrf52 enabled uart count and enable uart0/1 --- .../TARGET_MCU_NRF52832/config/sdk_config.h | 4 ++-- .../TARGET_MCU_NRF52840/config/sdk_config.h | 8 ++++---- .../TARGET_NRF5x/TARGET_NRF52/serial_api.c | 15 ++++++++++----- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/config/sdk_config.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/config/sdk_config.h index b4ff429d4c..d3fedc8023 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/config/sdk_config.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52832/config/sdk_config.h @@ -4152,11 +4152,11 @@ // NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver //========================================================== #ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 +#define NRFX_UARTE_ENABLED 1 #endif // NRFX_UARTE0_ENABLED - Enable UARTE0 instance #ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 +#define NRFX_UARTE0_ENABLED 1 #endif // NRFX_UARTE1_ENABLED - Enable UARTE1 instance diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h index 57ec3c5ca0..4826baa2f5 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/TARGET_MCU_NRF52840/config/sdk_config.h @@ -4152,16 +4152,16 @@ // NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver //========================================================== #ifndef NRFX_UARTE_ENABLED -#define NRFX_UARTE_ENABLED 0 +#define NRFX_UARTE_ENABLED 1 #endif // NRFX_UARTE0_ENABLED - Enable UARTE0 instance #ifndef NRFX_UARTE0_ENABLED -#define NRFX_UARTE0_ENABLED 0 +#define NRFX_UARTE0_ENABLED 1 #endif // NRFX_UARTE1_ENABLED - Enable UARTE1 instance #ifndef NRFX_UARTE1_ENABLED -#define NRFX_UARTE1_ENABLED 0 +#define NRFX_UARTE1_ENABLED 1 #endif // NRFX_UARTE_DEFAULT_CONFIG_HWFC - Hardware Flow Control @@ -5615,7 +5615,7 @@ // UART1_ENABLED - Enable UART1 instance //========================================================== #ifndef UART1_ENABLED -#define UART1_ENABLED 0 +#define UART1_ENABLED 1 #endif // diff --git a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c index 089318ce01..3ca874f3c3 100644 --- a/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c +++ b/targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c @@ -41,6 +41,7 @@ #include "hal/serial_api.h" #include "nrf_uarte.h" +#include "nrfx_uarte.h" #include "nrfx_uart.h" #include "nrf_atfifo.h" #include "app_util_platform.h" @@ -166,12 +167,12 @@ typedef enum { /** * UARTE state. One for each instance. */ -static nordic_uart_state_t nordic_nrf5_uart_state[NRFX_UART_ENABLED_COUNT] = { 0 }; +static nordic_uart_state_t nordic_nrf5_uart_state[NRFX_UARTE_ENABLED_COUNT] = { 0 }; /** * Array with UARTE register pointers for easy access. */ -static NRF_UARTE_Type *nordic_nrf5_uart_register[NRFX_UART_ENABLED_COUNT] = { +static NRF_UARTE_Type *nordic_nrf5_uart_register[NRFX_UARTE_ENABLED_COUNT] = { NRF_UARTE0, #if UART1_ENABLED NRF_UARTE1, @@ -193,6 +194,10 @@ NRF_ATFIFO_DEF(nordic_nrf5_uart_fifo_1, uint8_t, UART1_FIFO_BUFFER_SIZE); */ static uint8_t nordic_nrf5_uart_swi_mask_tx_0 = 0; static uint8_t nordic_nrf5_uart_swi_mask_rx_0 = 0; +#if UART1_ENABLED +static uint8_t nordic_nrf5_uart_swi_mask_tx_1 = 0; +static uint8_t nordic_nrf5_uart_swi_mask_rx_1 = 0; +#endif /** * Global variables expected by mbed_retarget.cpp for STDOUT. @@ -881,7 +886,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) nordic_nrf5_uart_state[1].owner = NULL; /* Allocate a PPI channel for flow control */ - ret = nrf_drv_ppi_channel_alloc(&nordic_nrf5_uart_state[1].ppi_rts); + ret = nrfx_ppi_channel_alloc(&nordic_nrf5_uart_state[1].ppi_rts); MBED_ASSERT(ret == NRF_SUCCESS); /* Clear RTS */ @@ -891,8 +896,8 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) nrf_uarte_int_disable(nordic_nrf5_uart_register[1], 0xFFFFFFFF); NVIC_SetVector(UARTE1_IRQn, (uint32_t) nordic_nrf5_uart1_handler); - NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(UARTE1_IRQn), APP_IRQ_PRIORITY_HIGHEST); - NRFX_IRQ_ENABLE(nrfx_get_irq_number(UARTE1_IRQn)); + NRFX_IRQ_PRIORITY_SET(UARTE1_IRQn, APP_IRQ_PRIORITY_HIGHEST); + NRFX_IRQ_ENABLE(UARTE1_IRQn); #endif } From 0689c589fcfe7249836959f14f271ed65754f940 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 10 Jun 2019 09:55:36 +0100 Subject: [PATCH 10/13] mbedtls: Update to Mbed Crypto 1.1.0d2 --- features/mbedtls/mbed-crypto/VERSION.txt | 2 +- features/mbedtls/mbed-crypto/importer/Makefile | 2 +- features/mbedtls/mbed-crypto/inc/psa/crypto_platform.h | 2 +- features/mbedtls/mbed-crypto/inc/psa/crypto_sizes.h | 2 +- .../COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h | 2 +- .../platform/TARGET_PSA/COMPONENT_SPE/crypto_struct_spe.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/mbedtls/mbed-crypto/VERSION.txt b/features/mbedtls/mbed-crypto/VERSION.txt index 1c7cde3079..bf56729412 100644 --- a/features/mbedtls/mbed-crypto/VERSION.txt +++ b/features/mbedtls/mbed-crypto/VERSION.txt @@ -1 +1 @@ -mbedcrypto-1.1.0d1 +mbedcrypto-1.1.0d2 diff --git a/features/mbedtls/mbed-crypto/importer/Makefile b/features/mbedtls/mbed-crypto/importer/Makefile index 6e04195818..29821dced6 100644 --- a/features/mbedtls/mbed-crypto/importer/Makefile +++ b/features/mbedtls/mbed-crypto/importer/Makefile @@ -29,7 +29,7 @@ # Set the Mbed Crypto release to import (this can/should be edited before # import) -CRYPTO_RELEASE ?= mbedcrypto-1.1.0d1 +CRYPTO_RELEASE ?= mbedcrypto-1.1.0d2 CRYPTO_REPO_URL ?= git@github.com:ARMmbed/mbed-crypto.git # Translate between Mbed Crypto namespace and Mbed OS namespace diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto_platform.h b/features/mbedtls/mbed-crypto/inc/psa/crypto_platform.h index 42cdad32a4..86af08f91b 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto_platform.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto_platform.h @@ -38,7 +38,7 @@ /* Include the Mbed TLS configuration file, the way Mbed TLS does it * in each of its header files. */ #if !defined(MBEDTLS_CONFIG_FILE) -#include "../mbedtls/config.h" +#include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif diff --git a/features/mbedtls/mbed-crypto/inc/psa/crypto_sizes.h b/features/mbedtls/mbed-crypto/inc/psa/crypto_sizes.h index 3cb0c73ab7..f360fd627c 100644 --- a/features/mbedtls/mbed-crypto/inc/psa/crypto_sizes.h +++ b/features/mbedtls/mbed-crypto/inc/psa/crypto_sizes.h @@ -45,7 +45,7 @@ /* Include the Mbed TLS configuration file, the way Mbed TLS does it * in each of its header files. */ #if !defined(MBEDTLS_CONFIG_FILE) -#include "../mbedtls/config.h" +#include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif diff --git a/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h b/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h index 88503572f3..53da2a8f26 100644 --- a/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h +++ b/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_PSA_SRV_IMPL/COMPONENT_NSPE/crypto_struct.h @@ -38,7 +38,7 @@ /* Include the Mbed TLS configuration file, the way Mbed TLS does it * in each of its header files. */ #if !defined(MBEDTLS_CONFIG_FILE) -#include "../mbedtls/config.h" +#include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif diff --git a/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_SPE/crypto_struct_spe.h b/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_SPE/crypto_struct_spe.h index 88503572f3..53da2a8f26 100644 --- a/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_SPE/crypto_struct_spe.h +++ b/features/mbedtls/mbed-crypto/platform/TARGET_PSA/COMPONENT_SPE/crypto_struct_spe.h @@ -38,7 +38,7 @@ /* Include the Mbed TLS configuration file, the way Mbed TLS does it * in each of its header files. */ #if !defined(MBEDTLS_CONFIG_FILE) -#include "../mbedtls/config.h" +#include "mbedtls/config.h" #else #include MBEDTLS_CONFIG_FILE #endif From c0b4343f264a39a7f3696755a93caf0cb6cc27ae Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 10 Jun 2019 13:05:46 +0100 Subject: [PATCH 11/13] mbedtls: Update to Mbed TLS 2.18.0-rc3 --- features/mbedtls/VERSION.txt | 2 +- features/mbedtls/importer/Makefile | 2 +- features/mbedtls/inc/mbedtls/check_config.h | 17 + features/mbedtls/inc/mbedtls/config.h | 95 ++- features/mbedtls/inc/mbedtls/error.h | 4 +- features/mbedtls/inc/mbedtls/ssl.h | 234 +++++++- features/mbedtls/inc/mbedtls/ssl_internal.h | 79 ++- features/mbedtls/src/Makefile | 56 +- features/mbedtls/src/error.c | 2 + features/mbedtls/src/ssl_cli.c | 129 +++- features/mbedtls/src/ssl_srv.c | 141 ++++- features/mbedtls/src/ssl_tls.c | 633 +++++++++++++++++--- features/mbedtls/src/version_features.c | 3 + 13 files changed, 1202 insertions(+), 195 deletions(-) diff --git a/features/mbedtls/VERSION.txt b/features/mbedtls/VERSION.txt index 968b5c7050..59b0f61b1a 100644 --- a/features/mbedtls/VERSION.txt +++ b/features/mbedtls/VERSION.txt @@ -1 +1 @@ -mbedtls-2.18.0-rc2 +mbedtls-2.18.0-rc3 diff --git a/features/mbedtls/importer/Makefile b/features/mbedtls/importer/Makefile index f89698fb81..6c048a1205 100644 --- a/features/mbedtls/importer/Makefile +++ b/features/mbedtls/importer/Makefile @@ -27,7 +27,7 @@ # # Set the mbed TLS release to import (this can/should be edited before import) -MBED_TLS_RELEASE ?= mbedtls-2.18.0-rc2 +MBED_TLS_RELEASE ?= mbedtls-2.18.0-rc3 MBED_TLS_REPO_URL ?= git@github.com:ARMmbed/mbedtls-restricted.git # Translate between mbed TLS namespace and mbed namespace diff --git a/features/mbedtls/inc/mbedtls/check_config.h b/features/mbedtls/inc/mbedtls/check_config.h index 0fa74f0611..04c8eba26c 100644 --- a/features/mbedtls/inc/mbedtls/check_config.h +++ b/features/mbedtls/inc/mbedtls/check_config.h @@ -641,6 +641,23 @@ #error "MBEDTLS_SSL_DTLS_ANTI_REPLAY defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) +#error "MBEDTLS_SSL_DTLS_CONNECTION_ID defined, but not all prerequisites" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + defined(MBEDTLS_SSL_CID_IN_LEN_MAX) && \ + MBEDTLS_SSL_CID_IN_LEN_MAX > 255 +#error "MBEDTLS_SSL_CID_IN_LEN_MAX too large (max 255)" +#endif + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) && \ + MBEDTLS_SSL_CID_OUT_LEN_MAX > 255 +#error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)" +#endif + #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) #error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" diff --git a/features/mbedtls/inc/mbedtls/config.h b/features/mbedtls/inc/mbedtls/config.h index 7dedffb1d6..261cf37407 100644 --- a/features/mbedtls/inc/mbedtls/config.h +++ b/features/mbedtls/inc/mbedtls/config.h @@ -1342,6 +1342,34 @@ */ #define MBEDTLS_SSL_ALL_ALERT_MESSAGES +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID + * + * Enable support for the DTLS Connection ID extension + * (version draft-ietf-tls-dtls-connection-id-05, + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) + * which allows to identify DTLS connections across changes + * in the underlying transport. + * + * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, + * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`. + * See the corresponding documentation for more information. + * + * \warning The Connection ID extension is still in draft state. + * We make no stability promises for the availability + * or the shape of the API controlled by this option. + * + * The maximum lengths of outgoing and incoming CIDs can be configured + * through the options + * - MBEDTLS_SSL_CID_OUT_LEN_MAX + * - MBEDTLS_SSL_CID_IN_LEN_MAX. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment to enable the Connection ID extension. + */ +//#define MBEDTLS_SSL_DTLS_CONNECTION_ID + /** * \def MBEDTLS_SSL_ASYNC_PRIVATE * @@ -1742,18 +1770,27 @@ /** * \def MBEDTLS_USE_PSA_CRYPTO * - * Make the X.509 and TLS library use PSA for cryptographic operations, see - * #MBEDTLS_PSA_CRYPTO_C. + * Make the X.509 and TLS library use PSA for cryptographic operations, and + * enable new APIs for using keys handled by PSA Crypto. * - * Note: this option is still in progress, the full X.509 and TLS modules are - * not covered yet, but parts that are not ported to PSA yet will still work - * as usual, so enabling this option should not break backwards compatibility. + * \note Development of this option is currently in progress, and parts + * of the X.509 and TLS modules are not ported to PSA yet. However, these parts + * will still continue to work as usual, so enabling this option should not + * break backwards compatibility. * - * \warning Support for PSA is still an experimental feature. - * Any public API that depends on this option may change - * at any time until this warning is removed. + * \warning The PSA Crypto API is in beta stage. While you're welcome to + * experiment using it, incompatible API changes are still possible, and some + * parts may not have reached the same quality as the rest of Mbed TLS yet. + * + * \warning This option enables new Mbed TLS APIs that are dependent on the + * PSA Crypto API, so can't come with the same stability guarantees as the + * rest of the Mbed TLS APIs. You're welcome to experiment with them, but for + * now, access to these APIs is opt-in (via enabling the present option), in + * order to clearly differentiate them from the stable Mbed TLS APIs. * * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * Uncomment this to enable internal use of PSA Crypto and new associated APIs. */ //#define MBEDTLS_USE_PSA_CRYPTO @@ -2789,19 +2826,16 @@ * * Enable the Platform Security Architecture cryptography API. * - * \note This option only has an effect when the build option - * USE_CRYPTO_SUBMODULE is also in use. - * - * \warning This feature is experimental and available on an opt-in basis only. - * PSA APIs are subject to change at any time. The implementation comes with - * less assurance and support than the rest of Mbed TLS. + * \warning The PSA Crypto API is still beta status. While you're welcome to + * experiment using it, incompatible API changes are still possible, and some + * parts may not have reached the same quality as the rest of Mbed TLS yet. * * Module: crypto/library/psa_crypto.c * * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C * */ -//#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_C /** * \def MBEDTLS_PSA_CRYPTO_STORAGE_C @@ -3323,6 +3357,37 @@ */ //#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 +/** \def MBEDTLS_SSL_CID_IN_LEN_MAX + * + * The maximum length of CIDs used for incoming DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX + * + * The maximum length of CIDs used for outgoing DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * when using the Connection ID extension in DTLS 1.2. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + * + */ +//#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 + /** \def MBEDTLS_SSL_OUT_CONTENT_LEN * * Maximum length (in bytes) of outgoing plaintext fragments. diff --git a/features/mbedtls/inc/mbedtls/error.h b/features/mbedtls/inc/mbedtls/error.h index bee0fe485a..765fd42f86 100644 --- a/features/mbedtls/inc/mbedtls/error.h +++ b/features/mbedtls/inc/mbedtls/error.h @@ -100,8 +100,8 @@ * ECP 4 10 (Started from top) * MD 5 5 * HKDF 5 1 (Started from top) - * CIPHER 6 8 - * SSL 6 23 (Started from top) + * CIPHER 6 8 (Started from 0x6080) + * SSL 6 24 (Started from top, plus 0x6000) * SSL 7 32 * * Module dependent error code (5 bits 0x.00.-0x.F8.) diff --git a/features/mbedtls/inc/mbedtls/ssl.h b/features/mbedtls/inc/mbedtls/ssl.h index 208b6c61df..5f9862b204 100644 --- a/features/mbedtls/inc/mbedtls/ssl.h +++ b/features/mbedtls/inc/mbedtls/ssl.h @@ -126,6 +126,7 @@ #define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */ #define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */ #define MBEDTLS_ERR_SSL_EARLY_MESSAGE -0x6480 /**< Internal-only message signaling that a message arrived early. */ +#define MBEDTLS_ERR_SSL_UNEXPECTED_CID -0x6000 /**< An encrypted DTLS-frame with an unexpected CID was received. */ #define MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS -0x7000 /**< A cryptographic operation is in progress. Try again later. */ /* @@ -160,6 +161,9 @@ #define MBEDTLS_SSL_EXTENDED_MS_DISABLED 0 #define MBEDTLS_SSL_EXTENDED_MS_ENABLED 1 +#define MBEDTLS_SSL_CID_DISABLED 0 +#define MBEDTLS_SSL_CID_ENABLED 1 + #define MBEDTLS_SSL_ETM_DISABLED 0 #define MBEDTLS_SSL_ETM_ENABLED 1 @@ -256,6 +260,21 @@ #define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 #endif +/* + * Maximum length of CIDs for incoming and outgoing messages. + */ +#if !defined(MBEDTLS_SSL_CID_IN_LEN_MAX) +#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 +#endif + +#if !defined(MBEDTLS_SSL_CID_OUT_LEN_MAX) +#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 +#endif + +#if !defined(MBEDTLS_SSL_CID_PADDING_GRANULARITY) +#define MBEDTLS_SSL_CID_PADDING_GRANULARITY 16 +#endif + /* \} name SECTION: Module settings */ /* @@ -303,6 +322,7 @@ #define MBEDTLS_SSL_MSG_ALERT 21 #define MBEDTLS_SSL_MSG_HANDSHAKE 22 #define MBEDTLS_SSL_MSG_APPLICATION_DATA 23 +#define MBEDTLS_SSL_MSG_CID 25 #define MBEDTLS_SSL_ALERT_LEVEL_WARNING 1 #define MBEDTLS_SSL_ALERT_LEVEL_FATAL 2 @@ -372,6 +392,11 @@ #define MBEDTLS_TLS_EXT_SESSION_TICKET 35 +/* The value of the CID extension is still TBD as of + * draft-ietf-tls-dtls-connection-id-05 + * (https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) */ +#define MBEDTLS_TLS_EXT_CID 254 /* TBD */ + #define MBEDTLS_TLS_EXT_ECJPAKE_KKPP 256 /* experimental */ #define MBEDTLS_TLS_EXT_RENEGOTIATION_INFO 0xFF01 @@ -940,6 +965,10 @@ struct mbedtls_ssl_config void *p_export_keys; /*!< context for key export callback */ #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + size_t cid_len; /*!< The length of CIDs for incoming DTLS records. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_X509_CRT_PARSE_C) const mbedtls_x509_crt_profile *cert_profile; /*!< verification profile */ mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s) */ @@ -1086,6 +1115,11 @@ struct mbedtls_ssl_config unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in Certificate Request messages? */ #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + unsigned int ignore_unexpected_cid : 1; /*!< Determines whether DTLS + * record with unexpected CID + * should lead to failure. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ }; @@ -1159,6 +1193,10 @@ struct mbedtls_ssl_context TLS: maintained by us DTLS: read from peer */ unsigned char *in_hdr; /*!< start of record header */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + unsigned char *in_cid; /*!< The start of the CID; + * (the end is marked by in_len). */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ unsigned char *in_len; /*!< two-bytes message length field */ unsigned char *in_iv; /*!< ivlen-byte IV */ unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ @@ -1195,6 +1233,10 @@ struct mbedtls_ssl_context unsigned char *out_buf; /*!< output buffer */ unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ unsigned char *out_hdr; /*!< start of record header */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + unsigned char *out_cid; /*!< The start of the CID; + * (the end is marked by in_len). */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ unsigned char *out_len; /*!< two-bytes message length field */ unsigned char *out_iv; /*!< ivlen-byte IV */ unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ @@ -1252,6 +1294,21 @@ struct mbedtls_ssl_context char own_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ char peer_verify_data[MBEDTLS_SSL_VERIFY_DATA_MAX_LEN]; /*!< previous handshake verify data */ #endif /* MBEDTLS_SSL_RENEGOTIATION */ + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* CID configuration to use in subsequent handshakes. */ + + /*! The next incoming CID, chosen by the user and applying to + * all subsequent handshakes. This may be different from the + * CID currently used in case the user has re-configured the CID + * after an initial handshake. */ + unsigned char own_cid[ MBEDTLS_SSL_CID_IN_LEN_MAX ]; + uint8_t own_cid_len; /*!< The length of \c own_cid. */ + uint8_t negotiate_cid; /*!< This indicates whether the CID extension should + * be negotiated in the next handshake or not. + * Possible values are #MBEDTLS_SSL_CID_ENABLED + * and #MBEDTLS_SSL_CID_DISABLED. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ }; #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) @@ -1476,6 +1533,142 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, mbedtls_ssl_recv_timeout_t *f_recv_timeout ); #if defined(MBEDTLS_SSL_PROTO_DTLS) + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + + +/** + * \brief Configure the use of the Connection ID (CID) + * extension in the next handshake. + * + * Reference: draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * The DTLS CID extension allows the reliable association of + * DTLS records to DTLS connections across changes in the + * underlying transport (changed IP and Port metadata) by + * adding explicit connection identifiers (CIDs) to the + * headers of encrypted DTLS records. The desired CIDs are + * configured by the application layer and are exchanged in + * new `ClientHello` / `ServerHello` extensions during the + * handshake, where each side indicates the CID it wants the + * peer to use when writing encrypted messages. The CIDs are + * put to use once records get encrypted: the stack discards + * any incoming records that don't include the configured CID + * in their header, and adds the peer's requested CID to the + * headers of outgoing messages. + * + * This API enables or disables the use of the CID extension + * in the next handshake and sets the value of the CID to + * be used for incoming messages. + * + * \param ssl The SSL context to configure. This must be initialized. + * \param enable This value determines whether the CID extension should + * be used or not. Possible values are: + * - MBEDTLS_SSL_CID_ENABLED to enable the use of the CID. + * - MBEDTLS_SSL_CID_DISABLED (default) to disable the use + * of the CID. + * \param own_cid The address of the readable buffer holding the CID we want + * the peer to use when sending encrypted messages to us. + * This may be \c NULL if \p own_cid_len is \c 0. + * This parameter is unused if \p enabled is set to + * MBEDTLS_SSL_CID_DISABLED. + * \param own_cid_len The length of \p own_cid. + * This parameter is unused if \p enabled is set to + * MBEDTLS_SSL_CID_DISABLED. + * + * \note The value of \p own_cid_len must match the value of the + * \c len parameter passed to mbedtls_ssl_conf_cid() + * when configuring the ::mbedtls_ssl_config that \p ssl + * is bound to. + * + * \note This CID configuration applies to subsequent handshakes + * performed on the SSL context \p ssl, but does not trigger + * one. You still have to call `mbedtls_ssl_handshake()` + * (for the initial handshake) or `mbedtls_ssl_renegotiate()` + * (for a renegotiation handshake) explicitly after a + * successful call to this function to run the handshake. + * + * \note This call cannot guarantee that the use of the CID + * will be successfully negotiated in the next handshake, + * because the peer might not support it. Specifically: + * - On the Client, enabling the use of the CID through + * this call implies that the `ClientHello` in the next + * handshake will include the CID extension, thereby + * offering the use of the CID to the server. Only if + * the `ServerHello` contains the CID extension, too, + * the CID extension will actually be put to use. + * - On the Server, enabling the use of the CID through + * this call implies that that the server will look for + * the CID extension in a `ClientHello` from the client, + * and, if present, reply with a CID extension in its + * `ServerHello`. + * + * \note To check whether the use of the CID was negotiated + * after the subsequent handshake has completed, please + * use the API mbedtls_ssl_get_peer_cid(). + * + * \warning If the use of the CID extension is enabled in this call + * and the subsequent handshake negotiates its use, Mbed TLS + * will silently drop every packet whose CID does not match + * the CID configured in \p own_cid. It is the responsibility + * of the user to adapt the underlying transport to take care + * of CID-based demultiplexing before handing datagrams to + * Mbed TLS. + * + * \return \c 0 on success. In this case, the CID configuration + * applies to the next handshake. + * \return A negative error code on failure. + */ +int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, + int enable, + unsigned char const *own_cid, + size_t own_cid_len ); + +/** + * \brief Get information about the use of the CID extension + * in the current connection. + * + * \param ssl The SSL context to query. + * \param enabled The address at which to store whether the CID extension + * is currently in use or not. If the CID is in use, + * `*enabled` is set to MBEDTLS_SSL_CID_ENABLED; + * otherwise, it is set to MBEDTLS_SSL_CID_DISABLED. + * \param peer_cid The address of the buffer in which to store the CID + * chosen by the peer (if the CID extension is used). + * This may be \c NULL in case the value of peer CID + * isn't needed. If it is not \c NULL, \p peer_cid_len + * must not be \c NULL. + * \param peer_cid_len The address at which to store the size of the CID + * chosen by the peer (if the CID extension is used). + * This is also the number of Bytes in \p peer_cid that + * have been written. + * This may be \c NULL in case the length of the peer CID + * isn't needed. If it is \c NULL, \p peer_cid must be + * \c NULL, too. + * + * \note This applies to the state of the CID negotiated in + * the last complete handshake. If a handshake is in + * progress, this function will attempt to complete + * the handshake first. + * + * \note If CID extensions have been exchanged but both client + * and server chose to use an empty CID, this function + * sets `*enabled` to #MBEDTLS_SSL_CID_DISABLED + * (the rationale for this is that the resulting + * communication is the same as if the CID extensions + * hadn't been used). + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, + int *enabled, + unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ], + size_t *peer_cid_len ); + +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + /** * \brief Set the Maximum Tranport Unit (MTU). * Special value: 0 means unset (no limit). @@ -2123,6 +2316,45 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, const int *ciphersuites ); +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0 +#define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1 +/** + * \brief Specify the length of Connection IDs for incoming + * encrypted DTLS records, as well as the behaviour + * on unexpected CIDs. + * + * By default, the CID length is set to \c 0, + * and unexpected CIDs are silently ignored. + * + * \param conf The SSL configuration to modify. + * \param len The length in Bytes of the CID fields in encrypted + * DTLS records using the CID mechanism. This must + * not be larger than #MBEDTLS_SSL_CID_OUT_LEN_MAX. + * \param ignore_other_cids This determines the stack's behaviour when + * receiving a record with an unexpected CID. + * Possible values are: + * - #MBEDTLS_SSL_UNEXPECTED_CID_IGNORE + * In this case, the record is silently ignored. + * - #MBEDTLS_SSL_UNEXPECTED_CID_FAIL + * In this case, the stack fails with the specific + * error code #MBEDTLS_ERR_SSL_UNEXPECTED_CID. + * + * \note The CID specification allows implementations to either + * use a common length for all incoming connection IDs or + * allow variable-length incoming IDs. Mbed TLS currently + * requires a common length for all connections sharing the + * same SSL configuration; this allows simpler parsing of + * record headers. + * + * \return \c 0 on success. + * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p own_cid_len + * is too large. + */ +int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, size_t len, + int ignore_other_cids ); +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + /** * \brief Set the list of allowed ciphersuites and the * preference order for a specific version of the protocol. @@ -2992,7 +3224,7 @@ void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_ * (Default: 2^48 - 1) * * Renegotiation is automatically triggered when a record - * counter (outgoing or ingoing) crosses the defined + * counter (outgoing or incoming) crosses the defined * threshold. The default value is meant to prevent the * connection from being closed when the counter is about to * reached its maximal value (it is not allowed to wrap). diff --git a/features/mbedtls/inc/mbedtls/ssl_internal.h b/features/mbedtls/inc/mbedtls/ssl_internal.h index 9c4be53f73..c2bc3b7879 100644 --- a/features/mbedtls/inc/mbedtls/ssl_internal.h +++ b/features/mbedtls/inc/mbedtls/ssl_internal.h @@ -175,10 +175,17 @@ #define MBEDTLS_SSL_PADDING_ADD 0 #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#define MBEDTLS_SSL_MAX_CID_EXPANSION MBEDTLS_SSL_CID_PADDING_GRANULARITY +#else +#define MBEDTLS_SSL_MAX_CID_EXPANSION 0 +#endif + #define MBEDTLS_SSL_PAYLOAD_OVERHEAD ( MBEDTLS_SSL_COMPRESSION_ADD + \ MBEDTLS_MAX_IV_LENGTH + \ MBEDTLS_SSL_MAC_ADD + \ - MBEDTLS_SSL_PADDING_ADD \ + MBEDTLS_SSL_PADDING_ADD + \ + MBEDTLS_SSL_MAX_CID_EXPANSION \ ) #define MBEDTLS_SSL_IN_PAYLOAD_LEN ( MBEDTLS_SSL_PAYLOAD_OVERHEAD + \ @@ -231,11 +238,23 @@ implicit sequence number. */ #define MBEDTLS_SSL_HEADER_LEN 13 +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) #define MBEDTLS_SSL_IN_BUFFER_LEN \ ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) ) +#else +#define MBEDTLS_SSL_IN_BUFFER_LEN \ + ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_IN_PAYLOAD_LEN ) \ + + ( MBEDTLS_SSL_CID_IN_LEN_MAX ) ) +#endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) #define MBEDTLS_SSL_OUT_BUFFER_LEN \ ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) ) +#else +#define MBEDTLS_SSL_OUT_BUFFER_LEN \ + ( ( MBEDTLS_SSL_HEADER_LEN ) + ( MBEDTLS_SSL_OUT_PAYLOAD_LEN ) \ + + ( MBEDTLS_SSL_CID_OUT_LEN_MAX ) ) +#endif #ifdef MBEDTLS_ZLIB_SUPPORT /* Compression buffer holds both IN and OUT buffers, so should be size of the larger */ @@ -372,6 +391,18 @@ struct mbedtls_ssl_handshake_params unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter for resending messages */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* The state of CID configuration in this handshake. */ + + uint8_t cid_in_use; /*!< This indicates whether the use of the CID extension + * has been negotiated. Possible values are + * #MBEDTLS_SSL_CID_ENABLED and + * #MBEDTLS_SSL_CID_DISABLED. */ + unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; /*! The peer's CID */ + uint8_t peer_cid_len; /*!< The length of + * \c peer_cid. */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + struct { size_t total_bytes_buffered; /*!< Cumulative size of heap allocated @@ -597,6 +628,13 @@ struct mbedtls_ssl_transform mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ int minor_ver; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + uint8_t in_cid_len; + uint8_t out_cid_len; + unsigned char in_cid [ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; + unsigned char out_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ]; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + /* * Session specific compression layer */ @@ -626,17 +664,27 @@ struct mbedtls_ssl_transform * make space for the fixed IV. * */ +#if MBEDTLS_SSL_CID_OUT_LEN_MAX > MBEDTLS_SSL_CID_IN_LEN_MAX +#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_OUT_LEN_MAX +#else +#define MBEDTLS_SSL_CID_LEN_MAX MBEDTLS_SSL_CID_IN_LEN_MAX +#endif + typedef struct { - uint8_t ctr[8]; /*!< Record sequence number */ - uint8_t type; /*!< Record type */ - uint8_t ver[2]; /*!< SSL/TLS version */ + uint8_t ctr[8]; /* Record sequence number */ + uint8_t type; /* Record type */ + uint8_t ver[2]; /* SSL/TLS version */ - unsigned char *buf; /*!< Memory buffer enclosing the record content */ - size_t buf_len; /*!< Buffer length */ - size_t data_offset; /*!< Offset of record content */ - size_t data_len; /*!< Length of record content */ + unsigned char *buf; /* Memory buffer enclosing the record content */ + size_t buf_len; /* Buffer length */ + size_t data_offset; /* Offset of record content */ + size_t data_len; /* Length of record content */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + uint8_t cid_len; /* Length of the CID (0 if not present) */ + unsigned char cid[ MBEDTLS_SSL_CID_LEN_MAX ]; /* The CID */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ } mbedtls_record; #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -880,15 +928,14 @@ void mbedtls_ssl_write_version( int major, int minor, int transport, void mbedtls_ssl_read_version( int *major, int *minor, int transport, const unsigned char ver[2] ); -static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl ) +static inline size_t mbedtls_ssl_in_hdr_len( const mbedtls_ssl_context *ssl ) { -#if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - return( 13 ); -#else - ((void) ssl); -#endif - return( 5 ); + return( (size_t) ( ssl->in_iv - ssl->in_hdr ) ); +} + +static inline size_t mbedtls_ssl_out_hdr_len( const mbedtls_ssl_context *ssl ) +{ + return( (size_t) ( ssl->out_iv - ssl->out_hdr ) ); } static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) diff --git a/features/mbedtls/src/Makefile b/features/mbedtls/src/Makefile index d10fc41f4a..60f3ae0d34 100644 --- a/features/mbedtls/src/Makefile +++ b/features/mbedtls/src/Makefile @@ -64,36 +64,11 @@ endif endif -ifdef USE_CRYPTO_SUBMODULE + # Look in crypto for libmbedcrypto. LOCAL_LDFLAGS += -L../crypto/library LOCAL_CFLAGS += -I../crypto/include CRYPTO := ../crypto/library/ -else -OBJS_CRYPTO= aes.o aesni.o arc4.o \ - aria.o asn1parse.o asn1write.o \ - base64.o bignum.o blowfish.o \ - camellia.o ccm.o chacha20.o \ - chachapoly.o cipher.o cipher_wrap.o \ - cmac.o ctr_drbg.o des.o \ - dhm.o ecdh.o ecdsa.o \ - ecjpake.o ecp.o \ - ecp_curves.o entropy.o entropy_poll.o \ - error.o gcm.o havege.o \ - hkdf.o \ - hmac_drbg.o md.o md2.o \ - md4.o md5.o md_wrap.o \ - memory_buffer_alloc.o nist_kw.o \ - oid.o padlock.o pem.o \ - pk.o pk_wrap.o pkcs12.o \ - pkcs5.o pkparse.o pkwrite.o \ - platform.o platform_util.o poly1305.o \ - ripemd160.o rsa_internal.o rsa.o \ - sha1.o sha256.o sha512.o \ - threading.o timing.o version.o \ - version_features.o xtea.o -CRYPTO := -endif OBJS_X509= certs.o pkcs11.o x509.o \ x509_create.o x509_crl.o x509_crt.o \ @@ -173,37 +148,8 @@ libmbedx509.dll: $(OBJS_X509) libmbedcrypto.dll echo " LD $@" $(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_X509) -lws2_32 -lwinmm -lgdi32 -L. -lmbedcrypto -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS) -# crypto -ifdef USE_CRYPTO_SUBMODULE libmbedcrypto.%: $(MAKE) CRYPTO_INCLUDES:="-I../../include -I../include" -C ../crypto/library $@ -else -libmbedcrypto.a: $(OBJS_CRYPTO) - echo " AR $@" - $(AR) $(ARFLAGS) $@ $(OBJS_CRYPTO) -ifdef APPLE_BUILD -ifneq ($(APPLE_BUILD),0) - echo " RL $@" - $(RL) $(RLFLAGS) $@ -endif -endif - -libmbedcrypto.$(SOEXT_CRYPTO): $(OBJS_CRYPTO) - echo " LD $@" - $(CC) -shared -Wl,-soname,$@ $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_CRYPTO) - -libmbedcrypto.so: libmbedcrypto.$(SOEXT_CRYPTO) - echo " LN $@ -> $<" - ln -sf $< $@ - -libmbedcrypto.dylib: $(OBJS_CRYPTO) - echo " LD $@" - $(CC) -dynamiclib $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@ $(OBJS_CRYPTO) - -libmbedcrypto.dll: $(OBJS_CRYPTO) - echo " LD $@" - $(CC) -shared -Wl,-soname,$@ -Wl,--out-implib,$@.a -o $@ $(OBJS_CRYPTO) -lws2_32 -lwinmm -lgdi32 -static-libgcc $(LOCAL_LDFLAGS) $(LDFLAGS) -endif .c.o: echo " CC $<" diff --git a/features/mbedtls/src/error.c b/features/mbedtls/src/error.c index 608423b1f5..e401a841c1 100644 --- a/features/mbedtls/src/error.c +++ b/features/mbedtls/src/error.c @@ -523,6 +523,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" ); if( use_ret == -(MBEDTLS_ERR_SSL_EARLY_MESSAGE) ) mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that a message arrived early" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_CID) ) + mbedtls_snprintf( buf, buflen, "SSL - An encrypted DTLS-frame with an unexpected CID was received" ); if( use_ret == -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) ) mbedtls_snprintf( buf, buflen, "SSL - A cryptographic operation is in progress. Try again later" ); #endif /* MBEDTLS_SSL_TLS_C */ diff --git a/features/mbedtls/src/ssl_cli.c b/features/mbedtls/src/ssl_cli.c index 78059054a0..f1bf7046a8 100644 --- a/features/mbedtls/src/ssl_cli.c +++ b/features/mbedtls/src/ssl_cli.c @@ -475,6 +475,54 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + size_t ext_len; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + + /* + * Quoting draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * struct { + * opaque cid<0..2^8-1>; + * } ConnectionId; + */ + + *olen = 0; + if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || + ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) + { + return; + } + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding CID extension" ) ); + + /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX + * which is at most 255, so the increment cannot overflow. */ + if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* Add extension ID + size */ + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID ) & 0xFF ); + ext_len = (size_t) ssl->own_cid_len + 1; + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + + *p++ = (uint8_t) ssl->own_cid_len; + memcpy( p, ssl->own_cid, ssl->own_cid_len ); + + *olen = ssl->own_cid_len + 5; +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, unsigned char *buf, @@ -1085,6 +1133,11 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; @@ -1242,6 +1295,62 @@ static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t peer_cid_len; + + if( /* CID extension only makes sense in DTLS */ + ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || + /* The server must only send the CID extension if we have offered it. */ + ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension unexpected" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + if( len == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + peer_cid_len = *buf++; + len--; + + if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + if( len != peer_cid_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "CID extension invalid" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; + ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; + memcpy( ssl->handshake->peer_cid, buf, peer_cid_len ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "Server CID", buf, peer_cid_len ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, @@ -1549,8 +1658,6 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); - buf = ssl->in_msg; - if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) { /* No alert on a read error. */ @@ -1558,6 +1665,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) return( ret ); } + buf = ssl->in_msg; + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) { #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -1893,6 +2002,20 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) break; #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + case MBEDTLS_TLS_EXT_CID: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) ); + + if( ( ret = ssl_parse_cid_ext( ssl, + ext + 4, + ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) ); @@ -3171,7 +3294,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) } /* Copy ECPoint structure to outgoing message buffer. */ - ssl->out_msg[header_len] = own_pubkey_ecpoint_len; + ssl->out_msg[header_len] = (unsigned char) own_pubkey_ecpoint_len; memcpy( ssl->out_msg + header_len + 1, own_pubkey_ecpoint, own_pubkey_ecpoint_len ); content_len = own_pubkey_ecpoint_len + 1; diff --git a/features/mbedtls/src/ssl_srv.c b/features/mbedtls/src/ssl_srv.c index 33a38a652c..a19179a252 100644 --- a/features/mbedtls/src/ssl_srv.c +++ b/features/mbedtls/src/ssl_srv.c @@ -475,6 +475,78 @@ static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +static int ssl_parse_cid_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t peer_cid_len; + + /* CID extension only makes sense in DTLS */ + if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Quoting draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * struct { + * opaque cid<0..2^8-1>; + * } ConnectionId; + */ + + if( len < 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + peer_cid_len = *buf++; + len--; + + if( len != peer_cid_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Ignore CID if the user has disabled its use. */ + if( ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED ) + { + /* Leave ssl->handshake->cid_in_use in its default + * value of MBEDTLS_SSL_CID_DISABLED. */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Client sent CID extension, but CID disabled" ) ); + return( 0 ); + } + + if( peer_cid_len > MBEDTLS_SSL_CID_OUT_LEN_MAX ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->handshake->cid_in_use = MBEDTLS_SSL_CID_ENABLED; + ssl->handshake->peer_cid_len = (uint8_t) peer_cid_len; + memcpy( ssl->handshake->peer_cid, buf, peer_cid_len ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use of CID extension negotiated" ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "Client CID", buf, peer_cid_len ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, const unsigned char *buf, @@ -1280,7 +1352,7 @@ read_record_header: return( ssl_parse_client_hello_v2( ssl ) ); #endif - MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); + MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_in_hdr_len( ssl ) ); /* * SSLv3/TLS Client Hello @@ -1369,7 +1441,7 @@ read_record_header: } if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) + mbedtls_ssl_in_hdr_len( ssl ) + msg_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); @@ -1378,7 +1450,7 @@ read_record_header: /* Done reading this record, get ready for the next one */ #if defined(MBEDTLS_SSL_PROTO_DTLS) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) - ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); + ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len( ssl ); else #endif ssl->in_left = 0; @@ -1823,6 +1895,16 @@ read_record_header: break; #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + case MBEDTLS_TLS_EXT_CID: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found CID extension" ) ); + + ret = ssl_parse_cid_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); @@ -2100,6 +2182,54 @@ static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +static void ssl_write_cid_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + size_t ext_len; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_OUT_CONTENT_LEN; + + *olen = 0; + + /* Skip writing the extension if we don't want to use it or if + * the client hasn't offered it. */ + if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_DISABLED ) + return; + + /* ssl->own_cid_len is at most MBEDTLS_SSL_CID_IN_LEN_MAX + * which is at most 255, so the increment cannot overflow. */ + if( end < p || (size_t)( end - p ) < (unsigned)( ssl->own_cid_len + 5 ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding CID extension" ) ); + + /* + * Quoting draft-ietf-tls-dtls-connection-id-05 + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05 + * + * struct { + * opaque cid<0..2^8-1>; + * } ConnectionId; + */ + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_CID ) & 0xFF ); + ext_len = (size_t) ssl->own_cid_len + 1; + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + + *p++ = (uint8_t) ssl->own_cid_len; + memcpy( p, ssl->own_cid, ssl->own_cid_len ); + + *olen = ssl->own_cid_len + 5; +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, unsigned char *buf, @@ -2621,6 +2751,11 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) ext_len += olen; #endif +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl_write_cid_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + #if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); ext_len += olen; diff --git a/features/mbedtls/src/ssl_tls.c b/features/mbedtls/src/ssl_tls.c index d25dffd07c..d9e777d8a7 100644 --- a/features/mbedtls/src/ssl_tls.c +++ b/features/mbedtls/src/ssl_tls.c @@ -110,14 +110,106 @@ static int ssl_check_timer( mbedtls_ssl_context *ssl ) static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, mbedtls_ssl_transform *transform ); -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ); +static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ); #define SSL_DONT_FORCE_FLUSH 0 #define SSL_FORCE_FLUSH 1 #if defined(MBEDTLS_SSL_PROTO_DTLS) +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +/* Top-level Connection ID API */ + +int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, + size_t len, + int ignore_other_cid ) +{ + if( len > MBEDTLS_SSL_CID_IN_LEN_MAX ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_FAIL && + ignore_other_cid != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + conf->ignore_unexpected_cid = ignore_other_cid; + conf->cid_len = len; + return( 0 ); +} + +int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, + int enable, + unsigned char const *own_cid, + size_t own_cid_len ) +{ + if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + ssl->negotiate_cid = enable; + if( enable == MBEDTLS_SSL_CID_DISABLED ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Disable use of CID extension." ) ); + return( 0 ); + } + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Enable use of CID extension." ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "Own CID", own_cid, own_cid_len ); + + if( own_cid_len != ssl->conf->cid_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "CID length %u does not match CID length %u in config", + (unsigned) own_cid_len, + (unsigned) ssl->conf->cid_len ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + memcpy( ssl->own_cid, own_cid, own_cid_len ); + /* Truncation is not an issue here because + * MBEDTLS_SSL_CID_IN_LEN_MAX at most 255. */ + ssl->own_cid_len = (uint8_t) own_cid_len; + + return( 0 ); +} + +int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, + int *enabled, + unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ], + size_t *peer_cid_len ) +{ + *enabled = MBEDTLS_SSL_CID_DISABLED; + + if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM || + ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* We report MBEDTLS_SSL_CID_DISABLED in case the CID extensions + * were used, but client and server requested the empty CID. + * This is indistinguishable from not using the CID extension + * in the first place. */ + if( ssl->transform_in->in_cid_len == 0 && + ssl->transform_in->out_cid_len == 0 ) + { + return( 0 ); + } + + if( peer_cid_len != NULL ) + { + *peer_cid_len = ssl->transform_in->out_cid_len; + if( peer_cid != NULL ) + { + memcpy( peer_cid, ssl->transform_in->out_cid, + ssl->transform_in->out_cid_len ); + } + } + + *enabled = MBEDTLS_SSL_CID_ENABLED; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + /* Forward declarations for functions related to message buffering. */ static void ssl_buffering_free( mbedtls_ssl_context *ssl ); static void ssl_buffering_free_slot( mbedtls_ssl_context *ssl, @@ -729,7 +821,7 @@ static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char * #endif #endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ -#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) && \ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \ defined(MBEDTLS_USE_PSA_CRYPTO) static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) { @@ -749,7 +841,7 @@ static int ssl_use_opaque_psk( mbedtls_ssl_context const *ssl ) return( 0 ); } #endif /* MBEDTLS_USE_PSA_CRYPTO && - MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) static mbedtls_tls_prf_types tls_prf_get_type( mbedtls_ssl_tls_prf_cb *tls_prf ) @@ -861,7 +953,8 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); -#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) && \ + defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) transform->encrypt_then_mac = session->encrypt_then_mac; #endif transform->minor_ver = ssl->minor_ver; @@ -883,6 +976,26 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* Copy own and peer's CID if the use of the CID + * extension has been negotiated. */ + if( ssl->handshake->cid_in_use == MBEDTLS_SSL_CID_ENABLED ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Copy CIDs into SSL transform" ) ); + + transform->in_cid_len = ssl->own_cid_len; + memcpy( transform->in_cid, ssl->own_cid, ssl->own_cid_len ); + MBEDTLS_SSL_DEBUG_BUF( 3, "Incoming CID", transform->in_cid, + transform->in_cid_len ); + + transform->out_cid_len = ssl->handshake->peer_cid_len; + memcpy( transform->out_cid, ssl->handshake->peer_cid, + ssl->handshake->peer_cid_len ); + MBEDTLS_SSL_DEBUG_BUF( 3, "Outgoing CID", transform->out_cid, + transform->out_cid_len ); + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + /* * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions */ @@ -1878,14 +1991,125 @@ static void ssl_read_memory( unsigned char *p, size_t len ) * Encryption/decryption functions */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +/* This functions transforms a DTLS plaintext fragment and a record content + * type into an instance of the DTLSInnerPlaintext structure: + * + * struct { + * opaque content[DTLSPlaintext.length]; + * ContentType real_type; + * uint8 zeros[length_of_padding]; + * } DTLSInnerPlaintext; + * + * Input: + * - `content`: The beginning of the buffer holding the + * plaintext to be wrapped. + * - `*content_size`: The length of the plaintext in Bytes. + * - `max_len`: The number of Bytes available starting from + * `content`. This must be `>= *content_size`. + * - `rec_type`: The desired record content type. + * + * Output: + * - `content`: The beginning of the resulting DTLSInnerPlaintext structure. + * - `*content_size`: The length of the resulting DTLSInnerPlaintext structure. + * + * Returns: + * - `0` on success. + * - A negative error code if `max_len` didn't offer enough space + * for the expansion. + */ +static int ssl_cid_build_inner_plaintext( unsigned char *content, + size_t *content_size, + size_t remaining, + uint8_t rec_type ) +{ + size_t len = *content_size; + size_t pad = ( MBEDTLS_SSL_CID_PADDING_GRANULARITY - + ( len + 1 ) % MBEDTLS_SSL_CID_PADDING_GRANULARITY ) % + MBEDTLS_SSL_CID_PADDING_GRANULARITY; + + /* Write real content type */ + if( remaining == 0 ) + return( -1 ); + content[ len ] = rec_type; + len++; + remaining--; + + if( remaining < pad ) + return( -1 ); + memset( content + len, 0, pad ); + len += pad; + remaining -= pad; + + *content_size = len; + return( 0 ); +} + +/* This function parses a DTLSInnerPlaintext structure. + * See ssl_cid_build_inner_plaintext() for details. */ +static int ssl_cid_parse_inner_plaintext( unsigned char const *content, + size_t *content_size, + uint8_t *rec_type ) +{ + size_t remaining = *content_size; + + /* Determine length of padding by skipping zeroes from the back. */ + do + { + if( remaining == 0 ) + return( -1 ); + remaining--; + } while( content[ remaining ] == 0 ); + + *content_size = remaining; + *rec_type = content[ remaining ]; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +/* `add_data` must have size 13 Bytes if the CID extension is disabled, + * and 13 + 1 + CID-length Bytes if the CID extension is enabled. */ static void ssl_extract_add_data_from_record( unsigned char* add_data, + size_t *add_data_len, mbedtls_record *rec ) { + /* Quoting RFC 5246 (TLS 1.2): + * + * additional_data = seq_num + TLSCompressed.type + + * TLSCompressed.version + TLSCompressed.length; + * + * For the CID extension, this is extended as follows + * (quoting draft-ietf-tls-dtls-connection-id-05, + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05): + * + * additional_data = seq_num + DTLSPlaintext.type + + * DTLSPlaintext.version + + * cid + + * cid_length + + * length_of_DTLSInnerPlaintext; + */ + memcpy( add_data, rec->ctr, sizeof( rec->ctr ) ); add_data[8] = rec->type; memcpy( add_data + 9, rec->ver, sizeof( rec->ver ) ); - add_data[11] = ( rec->data_len >> 8 ) & 0xFF; - add_data[12] = rec->data_len & 0xFF; + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( rec->cid_len != 0 ) + { + memcpy( add_data + 11, rec->cid, rec->cid_len ); + add_data[11 + rec->cid_len + 0] = rec->cid_len; + add_data[11 + rec->cid_len + 1] = ( rec->data_len >> 8 ) & 0xFF; + add_data[11 + rec->cid_len + 2] = ( rec->data_len >> 0 ) & 0xFF; + *add_data_len = 13 + 1 + rec->cid_len; + } + else +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + { + add_data[11 + 0] = ( rec->data_len >> 8 ) & 0xFF; + add_data[11 + 1] = ( rec->data_len >> 0 ) & 0xFF; + *add_data_len = 13; + } } int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, @@ -1897,7 +2121,8 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, mbedtls_cipher_mode_t mode; int auth_done = 0; unsigned char * data; - unsigned char add_data[13]; + unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_OUT_LEN_MAX ]; + size_t add_data_len; size_t post_avail; /* The SSL context is only used for debugging purposes! */ @@ -1923,17 +2148,21 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 1, ( "no transform provided to encrypt_buf" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - if( rec == NULL || - rec->buf == NULL || - rec->buf_len < rec->data_offset || - rec->buf_len - rec->data_offset < rec->data_len ) + if( rec == NULL + || rec->buf == NULL + || rec->buf_len < rec->data_offset + || rec->buf_len - rec->data_offset < rec->data_len +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + || rec->cid_len != 0 +#endif + ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad record structure provided to encrypt_buf" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); data = rec->buf + rec->data_offset; + post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", data, rec->data_len ); @@ -1947,6 +2176,37 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* + * Add CID information + */ + rec->cid_len = transform->out_cid_len; + memcpy( rec->cid, transform->out_cid, transform->out_cid_len ); + MBEDTLS_SSL_DEBUG_BUF( 3, "CID", rec->cid, rec->cid_len ); + + if( rec->cid_len != 0 ) + { + /* + * Wrap plaintext into DTLSInnerPlaintext structure. + * See ssl_cid_build_inner_plaintext() for more information. + * + * Note that this changes `rec->data_len`, and hence + * `post_avail` needs to be recalculated afterwards. + */ + if( ssl_cid_build_inner_plaintext( data, + &rec->data_len, + post_avail, + rec->type ) != 0 ) + { + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + rec->type = MBEDTLS_SSL_MSG_CID; + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + + post_avail = rec->buf_len - ( rec->data_len + rec->data_offset ); + /* * Add MAC before if needed */ @@ -1980,10 +2240,10 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, { unsigned char mac[MBEDTLS_SSL_MAC_ADD]; - ssl_extract_add_data_from_record( add_data, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, - sizeof( add_data ) ); + add_data_len ); mbedtls_md_hmac_update( &transform->md_ctx_enc, data, rec->data_len ); mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); @@ -2086,14 +2346,14 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - ssl_extract_add_data_from_record( add_data, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (internal)", iv, transform->ivlen ); MBEDTLS_SSL_DEBUG_BUF( 4, "IV used (transmitted)", data - explicit_iv_len, explicit_iv_len ); MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", - add_data, 13 ); + add_data, add_data_len ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " "including 0 bytes of padding", rec->data_len ) ); @@ -2104,7 +2364,7 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, if( ( ret = mbedtls_cipher_auth_encrypt( &transform->cipher_ctx_enc, iv, transform->ivlen, - add_data, 13, /* add data */ + add_data, add_data_len, /* add data */ data, rec->data_len, /* source */ data, &rec->data_len, /* destination */ data + rec->data_len, transform->taglen ) ) != 0 ) @@ -2240,14 +2500,14 @@ int mbedtls_ssl_encrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); } - ssl_extract_add_data_from_record( add_data, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, - sizeof( add_data ) ); + add_data_len ); mbedtls_md_hmac_update( &transform->md_ctx_enc, add_data, - sizeof( add_data ) ); + add_data_len ); mbedtls_md_hmac_update( &transform->md_ctx_enc, data, rec->data_len ); mbedtls_md_hmac_finish( &transform->md_ctx_enc, mac ); @@ -2292,7 +2552,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, size_t padlen = 0, correct = 1; #endif unsigned char* data; - unsigned char add_data[13]; + unsigned char add_data[13 + 1 + MBEDTLS_SSL_CID_IN_LEN_MAX ]; + size_t add_data_len; #if !defined(MBEDTLS_DEBUG_C) ((void) ssl); @@ -2316,6 +2577,17 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, data = rec->buf + rec->data_offset; mode = mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_dec ); +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* + * Match record's CID with incoming CID. + */ + if( rec->cid_len != transform->in_cid_len || + memcmp( rec->cid, transform->in_cid, rec->cid_len ) != 0 ) + { + return( MBEDTLS_ERR_SSL_UNEXPECTED_CID ); + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + #if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) if( mode == MBEDTLS_MODE_STREAM ) { @@ -2390,9 +2662,9 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, rec->data_offset += explicit_iv_len; rec->data_len -= explicit_iv_len + transform->taglen; - ssl_extract_add_data_from_record( add_data, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", - add_data, 13 ); + add_data, add_data_len ); memcpy( transform->iv_dec + transform->fixed_ivlen, data - explicit_iv_len, explicit_iv_len ); @@ -2407,7 +2679,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, */ if( ( ret = mbedtls_cipher_auth_decrypt( &transform->cipher_ctx_dec, iv, transform->ivlen, - add_data, 13, + add_data, add_data_len, data, rec->data_len, data, &olen, data + rec->data_len, @@ -2491,10 +2763,12 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, /* Safe due to the check data_len >= minlen + maclen + 1 above. */ rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record( add_data, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); - MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, 13 ); - mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, 13 ); + MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", add_data, + add_data_len ); + mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, + add_data_len ); mbedtls_md_hmac_update( &transform->md_ctx_dec, data, rec->data_len ); mbedtls_md_hmac_finish( &transform->md_ctx_dec, mac_expect ); @@ -2698,7 +2972,7 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, */ rec->data_len -= transform->maclen; - ssl_extract_add_data_from_record( add_data, rec ); + ssl_extract_add_data_from_record( add_data, &add_data_len, rec ); #if defined(MBEDTLS_SSL_PROTO_SSL3) if( transform->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) @@ -2768,15 +3042,17 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, case MBEDTLS_MD_SHA1: case MBEDTLS_MD_SHA256: /* 8 bytes of message size, 64-byte compression blocks */ - extra_run = ( 13 + rec->data_len + padlen + 8 ) / 64 - - ( 13 + rec->data_len + 8 ) / 64; + extra_run = + ( add_data_len + rec->data_len + padlen + 8 ) / 64 - + ( add_data_len + rec->data_len + 8 ) / 64; break; #endif #if defined(MBEDTLS_SHA512_C) case MBEDTLS_MD_SHA384: /* 16 bytes of message size, 128-byte compression blocks */ - extra_run = ( 13 + rec->data_len + padlen + 16 ) / 128 - - ( 13 + rec->data_len + 16 ) / 128; + extra_run = + ( add_data_len + rec->data_len + padlen + 16 ) / 128 - + ( add_data_len + rec->data_len + 16 ) / 128; break; #endif default: @@ -2786,7 +3062,8 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, extra_run &= correct * 0xFF; - mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, 13 ); + mbedtls_md_hmac_update( &transform->md_ctx_dec, add_data, + add_data_len ); mbedtls_md_hmac_update( &transform->md_ctx_dec, data, rec->data_len ); /* Make sure we access everything even when padlen > 0. This @@ -2847,6 +3124,16 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( rec->cid_len != 0 ) + { + ret = ssl_cid_parse_inner_plaintext( data, &rec->data_len, + &rec->type ); + if( ret != 0 ) + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); return( 0 ); @@ -3245,7 +3532,7 @@ int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) while( ssl->out_left > 0 ) { MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", - mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); + mbedtls_ssl_out_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); buf = ssl->out_hdr - ssl->out_left; ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); @@ -3851,7 +4138,9 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) unsigned i; size_t protected_record_size; - ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + /* Skip writing the record content type to after the encryption, + * as it may change when using the CID extension. */ + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, ssl->conf->transport, ssl->out_hdr + 1 ); @@ -3874,6 +4163,11 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) ssl->conf->transport, rec.ver ); rec.type = ssl->out_msgtype; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* The CID is set by mbedtls_ssl_encrypt_buf(). */ + rec.cid_len = 0; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + if( ( ret = mbedtls_ssl_encrypt_buf( ssl, ssl->transform_out, &rec, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { @@ -3887,12 +4181,17 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } + /* Update the record content type and CID. */ + ssl->out_msgtype = rec.type; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID ) + memcpy( ssl->out_cid, rec.cid, rec.cid_len ); +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ ssl->out_msglen = len = rec.data_len; ssl->out_len[0] = (unsigned char)( rec.data_len >> 8 ); ssl->out_len[1] = (unsigned char)( rec.data_len ); } - protected_record_size = len + mbedtls_ssl_hdr_len( ssl ); + protected_record_size = len + mbedtls_ssl_out_hdr_len( ssl ); #if defined(MBEDTLS_SSL_PROTO_DTLS) /* In case of DTLS, double-check that we don't exceed @@ -3911,6 +4210,9 @@ int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl, uint8_t force_flush ) } #endif /* MBEDTLS_SSL_PROTO_DTLS */ + /* Now write the potentially updated record content type. */ + ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " "version = [%d:%d], msglen = %d", ssl->out_hdr[0], ssl->out_hdr[1], @@ -4515,6 +4817,19 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ +static int ssl_check_record_type( uint8_t record_type ) +{ + if( record_type != MBEDTLS_SSL_MSG_HANDSHAKE && + record_type != MBEDTLS_SSL_MSG_ALERT && + record_type != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && + record_type != MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + return( 0 ); +} + /* * ContentType type; * ProtocolVersion version; @@ -4537,23 +4852,40 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) { int major_ver, minor_ver; + int ret; - MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); + /* Parse and validate record content type and version */ ssl->in_msgtype = ssl->in_hdr[0]; - ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 ); - MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " - "version = [%d:%d], msglen = %d", - ssl->in_msgtype, - major_ver, minor_ver, ssl->in_msglen ) ); - /* Check record type */ - if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && - ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT && - ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && - ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->in_msgtype == MBEDTLS_SSL_MSG_CID && + ssl->conf->cid_len != 0 ) + { + /* Shift pointers to account for record header including CID + * struct { + * ContentType special_type = tls12_cid; + * ProtocolVersion version; + * uint16 epoch; + * uint48 sequence_number; + * opaque cid[cid_length]; // Additional field compared to + * // default DTLS record format + * uint16 length; + * opaque enc_content[DTLSCiphertext.length]; + * } DTLSCiphertext; + */ + + /* So far, we only support static CID lengths + * fixed in the configuration. */ + ssl->in_len = ssl->in_cid + ssl->conf->cid_len; + ssl->in_iv = ssl->in_msg = ssl->in_len + 2; + } + else +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + if( ssl_check_record_type( ssl->in_msgtype ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); @@ -4581,7 +4913,24 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } - /* Check length against the size of our buffer */ + /* Now that the total length of the record header is known, ensure + * that the current datagram is large enough to hold it. + * This would fail, for example, if we received a datagram of + * size 13 + n Bytes where n is less than the size of incoming CIDs. */ + ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } + MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_in_hdr_len( ssl ) ); + + /* Parse and validate record length + * This must happen after the CID parsing because + * its position in the record header depends on + * the presence of a CID. */ + + ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; if( ssl->in_msglen > MBEDTLS_SSL_IN_BUFFER_LEN - (size_t)( ssl->in_msg - ssl->in_buf ) ) { @@ -4589,6 +4938,11 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INVALID_RECORD ); } + MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->in_msgtype, + major_ver, minor_ver, ssl->in_msglen ) ); + /* * DTLS-related tests. * Check epoch before checking length constraint because @@ -4654,20 +5008,6 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); } #endif - - /* Drop unexpected ApplicationData records, - * except at the beginning of renegotiations */ - if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && - ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && - ssl->state == MBEDTLS_SSL_SERVER_HELLO ) -#endif - ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); - return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); - } } #endif /* MBEDTLS_SSL_PROTO_DTLS */ @@ -4724,7 +5064,7 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) int ret, done = 0; MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", - ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ); + ssl->in_hdr, mbedtls_ssl_in_hdr_len( ssl ) + ssl->in_msglen ); #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_read != NULL ) @@ -4751,6 +5091,10 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) - ( ssl->in_iv - ssl->in_buf ); rec.data_len = ssl->in_msglen; rec.data_offset = 0; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID ) + rec.cid_len = (uint8_t)( ssl->in_len - ssl->in_cid ); + memcpy( rec.cid, ssl->in_cid, rec.cid_len ); +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ memcpy( &rec.ctr[0], ssl->in_ctr, 8 ); mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, @@ -4760,15 +5104,35 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) &rec ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && + ssl->conf->ignore_unexpected_cid + == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) ); + ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + return( ret ); } - if( ssl->in_iv + rec.data_offset != ssl->in_msg ) + if( ssl->in_msgtype != rec.type ) { - /* Should never happen */ - return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + MBEDTLS_SSL_DEBUG_MSG( 4, ( "record type after decrypt (before %d): %d", + ssl->in_msgtype, rec.type ) ); } + /* The record content type may change during decryption, + * so re-read it. */ + ssl->in_msgtype = rec.type; + /* Also update the input buffer, because unfortunately + * the server-side ssl_parse_client_hello() reparses the + * record header when receiving a ClientHello initiating + * a renegotiation. */ + ssl->in_hdr[0] = rec.type; + ssl->in_msg = rec.buf + rec.data_offset; ssl->in_msglen = rec.data_len; ssl->in_len[0] = (unsigned char)( rec.data_len >> 8 ); ssl->in_len[1] = (unsigned char)( rec.data_len ); @@ -4776,6 +5140,21 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", ssl->in_msg, ssl->in_msglen ); +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + /* We have already checked the record content type + * in ssl_parse_record_header(), failing or silently + * dropping the record in the case of an unknown type. + * + * Since with the use of CIDs, the record content type + * might change during decryption, re-check the record + * content type, but treat a failure as fatal this time. */ + if( ssl_check_record_type( ssl->in_msgtype ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + if( ssl->in_msglen > MBEDTLS_SSL_IN_CONTENT_LEN ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); @@ -4802,8 +5181,10 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) if( ssl->nb_zero > 3 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " - "messages, possible DoS attack" ) ); - /* Q: Is that the right error code? */ + "messages, possible DoS attack" ) ); + /* Treat the records as if they were not properly authenticated, + * thereby failing the connection if we see more than allowed + * by the configured bad MAC threshold. */ return( MBEDTLS_ERR_SSL_INVALID_MAC ); } } @@ -5535,7 +5916,16 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) return( ret ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ - if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) + /* Reset in pointers to default state for TLS/DTLS records, + * assuming no CID and no offset between record content and + * record plaintext. */ + ssl_update_in_pointers( ssl ); + + /* Ensure that we have enough space available for the default form + * of TLS / DTLS record headers (5 Bytes for TLS, 13 Bytes for DTLS, + * with no space for CIDs counted in). */ + ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_in_hdr_len( ssl ) ); + if( ret != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); @@ -5561,7 +5951,7 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) { /* Skip unexpected record (but not whole datagram) */ ssl->next_record_offset = ssl->in_msglen - + mbedtls_ssl_hdr_len( ssl ); + + mbedtls_ssl_in_hdr_len( ssl ); MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " "(header)" ) ); @@ -5587,7 +5977,7 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) * Read and optionally decrypt the message contents */ if( ( ret = mbedtls_ssl_fetch_input( ssl, - mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) + mbedtls_ssl_in_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); return( ret ); @@ -5597,7 +5987,7 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_DTLS) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { - ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl ); + ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_in_hdr_len( ssl ); if( ssl->next_record_offset < ssl->in_left ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) ); @@ -5613,8 +6003,7 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { /* Silently discard invalid records */ - if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD || - ret == MBEDTLS_ERR_SSL_INVALID_MAC ) + if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) { /* Except when waiting for Finished as a bad mac here * probably means something went wrong in the handshake @@ -5780,13 +6169,29 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) } #if defined(MBEDTLS_SSL_PROTO_DTLS) - if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && - ssl->handshake != NULL && - ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { - ssl_handshake_wrapup_free_hs_transform( ssl ); - } + /* Drop unexpected ApplicationData records, + * except at the beginning of renegotiations */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && + ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->state == MBEDTLS_SSL_SERVER_HELLO ) #endif + ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); + return( MBEDTLS_ERR_SSL_NON_FATAL ); + } + + if( ssl->handshake != NULL && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + { + ssl_handshake_wrapup_free_hs_transform( ssl ); + } + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ return( 0 ); } @@ -6757,7 +7162,7 @@ int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) #endif /* MBEDTLS_SSL_PROTO_DTLS */ memset( ssl->in_ctr, 0, 8 ); - ssl_update_in_pointers( ssl, ssl->transform_negotiate ); + ssl_update_in_pointers( ssl ); #if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) if( mbedtls_ssl_hw_record_activate != NULL ) @@ -7682,14 +8087,24 @@ static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { ssl->out_ctr = ssl->out_hdr + 3; - ssl->out_len = ssl->out_hdr + 11; - ssl->out_iv = ssl->out_hdr + 13; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl->out_cid = ssl->out_ctr + 8; + ssl->out_len = ssl->out_cid; + if( transform != NULL ) + ssl->out_len += transform->out_cid_len; +#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + ssl->out_len = ssl->out_ctr + 8; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + ssl->out_iv = ssl->out_len + 2; } else #endif { ssl->out_ctr = ssl->out_hdr - 8; ssl->out_len = ssl->out_hdr + 3; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl->out_cid = ssl->out_len; +#endif ssl->out_iv = ssl->out_hdr + 5; } @@ -7711,32 +8126,47 @@ static void ssl_update_out_pointers( mbedtls_ssl_context *ssl, * and the caller has to make sure there's space for this. */ -static void ssl_update_in_pointers( mbedtls_ssl_context *ssl, - mbedtls_ssl_transform *transform ) +static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ) { + /* This function sets the pointers to match the case + * of unprotected TLS/DTLS records, with both ssl->in_iv + * and ssl->in_msg pointing to the beginning of the record + * content. + * + * When decrypting a protected record, ssl->in_msg + * will be shifted to point to the beginning of the + * record plaintext. + */ + #if defined(MBEDTLS_SSL_PROTO_DTLS) if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) { + /* This sets the header pointers to match records + * without CID. When we receive a record containing + * a CID, the fields are shifted accordingly in + * ssl_parse_record_header(). */ ssl->in_ctr = ssl->in_hdr + 3; - ssl->in_len = ssl->in_hdr + 11; - ssl->in_iv = ssl->in_hdr + 13; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl->in_cid = ssl->in_ctr + 8; + ssl->in_len = ssl->in_cid; /* Default: no CID */ +#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + ssl->in_len = ssl->in_ctr + 8; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + ssl->in_iv = ssl->in_len + 2; } else #endif { ssl->in_ctr = ssl->in_hdr - 8; ssl->in_len = ssl->in_hdr + 3; +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + ssl->in_cid = ssl->in_len; +#endif ssl->in_iv = ssl->in_hdr + 5; } - /* Offset in_msg from in_iv to allow space for explicit IV, if used. */ - if( transform != NULL && - ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) - { - ssl->in_msg = ssl->in_iv + transform->ivlen - transform->fixed_ivlen; - } - else - ssl->in_msg = ssl->in_iv; + /* This will be adjusted at record decryption time. */ + ssl->in_msg = ssl->in_iv; } /* @@ -7769,7 +8199,7 @@ static void ssl_reset_in_out_pointers( mbedtls_ssl_context *ssl ) /* Derive other internal pointers. */ ssl_update_out_pointers( ssl, NULL /* no transform enabled */ ); - ssl_update_in_pointers ( ssl, NULL /* no transform enabled */ ); + ssl_update_in_pointers ( ssl ); } int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, @@ -8914,8 +9344,10 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) const mbedtls_ssl_transform *transform = ssl->transform_out; unsigned block_size; + size_t out_hdr_len = mbedtls_ssl_out_hdr_len( ssl ); + if( transform == NULL ) - return( (int) mbedtls_ssl_hdr_len( ssl ) ); + return( (int) out_hdr_len ); #if defined(MBEDTLS_ZLIB_SUPPORT) if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) @@ -8958,7 +9390,12 @@ int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) ); +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + if( transform->out_cid_len != 0 ) + transform_expansion += MBEDTLS_SSL_MAX_CID_EXPANSION; +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + + return( (int)( out_hdr_len + transform_expansion ) ); } #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) diff --git a/features/mbedtls/src/version_features.c b/features/mbedtls/src/version_features.c index b36893e33d..5a5f9d6c06 100644 --- a/features/mbedtls/src/version_features.c +++ b/features/mbedtls/src/version_features.c @@ -447,6 +447,9 @@ static const char *features[] = { #if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) "MBEDTLS_SSL_ALL_ALERT_MESSAGES", #endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) + "MBEDTLS_SSL_DTLS_CONNECTION_ID", +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) "MBEDTLS_SSL_ASYNC_PRIVATE", #endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ From 23d66c1c25457e6fd11cf0e89c8786a1da040285 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 10 Jun 2019 17:06:28 +0100 Subject: [PATCH 12/13] mbedtls: PSA entropy is compatible with other entropy When using Mbed Crypto's PSA Entropy Injection feature on Mbed OS, it is not required to opt out of having entropy sources added to your entropy contexts by default (via MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES). As integrated in Mbed OS, MBEDTLS_PSA_INJECT_ENTROPY is compatible with actual entropy sources. PSA entropy injection is implemented using the standard Mbed TLS NV Seed feature, and is as compatible with other entropy sources as the standard Mbed TLS NV Seed feature which does support entropy mixing. --- features/mbedtls/inc/mbedtls/check_config.h | 5 ----- features/mbedtls/platform/inc/platform_mbed.h | 6 +----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/features/mbedtls/inc/mbedtls/check_config.h b/features/mbedtls/inc/mbedtls/check_config.h index 04c8eba26c..2a3be64f9f 100644 --- a/features/mbedtls/inc/mbedtls/check_config.h +++ b/features/mbedtls/inc/mbedtls/check_config.h @@ -541,11 +541,6 @@ #error "MBEDTLS_PSA_INJECT_ENTROPY defined, but not all prerequisites" #endif -#if defined(MBEDTLS_PSA_INJECT_ENTROPY) && \ - !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) -#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with actual entropy sources" -#endif - #if defined(MBEDTLS_PSA_ITS_FILE_C) && \ !defined(MBEDTLS_FS_IO) #error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites" diff --git a/features/mbedtls/platform/inc/platform_mbed.h b/features/mbedtls/platform/inc/platform_mbed.h index 9b790e823a..f03a410be2 100644 --- a/features/mbedtls/platform/inc/platform_mbed.h +++ b/features/mbedtls/platform/inc/platform_mbed.h @@ -34,11 +34,7 @@ #endif /* Automatically enable the Mbed Crypto entropy injection API if - * MBEDTLS_ENTROPY_NV_SEED is enabled. WARNING: the current implementation of - * the Mbed Crypto entropy injection API is incompatible with other entropy - * sources. When MBEDTLS_ENTROPY_NV_SEED is used on PSA target, the NV Seed is - * the sole source of entropy and all other entropy sources are ignored. */ -#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * MBEDTLS_ENTROPY_NV_SEED is enabled. */ #define MBEDTLS_PSA_INJECT_ENTROPY #endif // (defined(TARGET_PSA) && defined(MBEDTLS_ENTROPY_NV_SEED)) From bf676c126484123753a2f7bcaaf6eb8efe348c83 Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Tue, 11 Jun 2019 16:23:33 +0100 Subject: [PATCH 13/13] psa: Avoid re-definition of MBEDTLS_PSA_CRYPTO_C Mbed TLS now enables PSA APIs by default on all targets. It's not necessary to explicitly enable MBEDTLS_PSA_CRYPTO_C, as that can be gotten from the Mbed TLS config.h. However, many PSA targets depend on `-DMBEDTLS_PSA_CRYPTO_C` being defined by the Mbed OS json configuration system and are not yet properly including the Mbed TLS configuration; for these PSA targets, warnings may remain until this issue is fixed. Avoiding re-definition will eliminate warnings like the following, when building mbed-os-example-blinky: Compile [ 14.5%]: pal_client_api_empty_intf.c [Warning] pal_client_api_intf.h@35,0: "PSA_SUCCESS" redefined Compile [ 14.6%]: pal_client_api_intf.c Compile [ 14.7%]: DeviceKey.cpp Compile [ 14.9%]: pal_internal_trusted_storage_intf.c [Warning] pal_internal_trusted_storage_intf.c@45,9: 'psa_its_set' is deprecated: PS specific types should not be used [-Wdeprecated-declarations] Compile [ 15.3%]: val_attestation.c [Warning] client.h@40,0: "PSA_VERSION_NONE" redefined <..> Compile [ 33.3%]: asn1parse.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 33.5%]: aes.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 33.6%]: asn1write.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 33.7%]: psa_crypto.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 33.8%]: blowfish.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 33.9%]: camellia.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.0%]: base64.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.2%]: ccm.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.3%]: chacha20.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.4%]: chachapoly.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.5%]: cipher_wrap.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.6%]: cmac.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.7%]: cipher.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 34.9%]: bignum.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 35.0%]: des.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 35.1%]: dhm.c [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 35.2%]: ctr_drbg.c <..> Compile [ 70.9%]: EthernetInterface.cpp [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 71.0%]: InternetSocket.cpp Compile [ 71.1%]: L3IPInterface.cpp [Warning] config.h@2838,0: "MBEDTLS_PSA_CRYPTO_C" redefined Compile [ 71.2%]: NetworkInterface.cpp --- targets/targets.json | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/targets/targets.json b/targets/targets.json index 56bddbe805..21c7c2dca1 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1485,7 +1485,7 @@ "PSA" ], "is_disk_virtual": true, - "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "MBEDTLS_PSA_CRYPTO_C"], + "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED"], "inherits": ["Target"], "detect_code": ["0240"], "device_has": [ @@ -1773,7 +1773,7 @@ "PSA" ], "is_disk_virtual": true, - "macros": ["CPU_MK66FN2M0VMD18", "FSL_RTOS_MBED", "MBEDTLS_PSA_CRYPTO_C"], + "macros": ["CPU_MK66FN2M0VMD18", "FSL_RTOS_MBED"], "inherits": ["Target"], "detect_code": ["0311"], "device_has": [ @@ -2812,8 +2812,7 @@ "components_add": ["FLASHIAP"], "macros_add": [ "USB_STM_HAL", - "USBHOST_OTHER", - "MBEDTLS_PSA_CRYPTO_C" + "USBHOST_OTHER" ], "device_has_add": [ "ANALOGOUT", @@ -4558,9 +4557,6 @@ "device_has_remove": [], "extra_labels_add": ["PSA"], "components_add": ["SD", "FLASHIAP"], - "macros_add": [ - "MBEDTLS_PSA_CRYPTO_C" - ], "config": { "stdio_uart_tx_help": { "help": "Value: D8(default) or D1" @@ -8650,6 +8646,7 @@ "device_name": "GD32F450ZI", "detect_code": ["1702"], "macros_add": ["GD32F450"], + "bootloader_supported": true, "release_versions": ["5"], "overrides": { "network-default-interface-type": "ETHERNET"