From 2afbc59293b23c4c9c25e715969eb6b29be007eb Mon Sep 17 00:00:00 2001 From: Jintao Lin Date: Thu, 14 May 2020 01:15:39 +0800 Subject: [PATCH] [mac] put transmission AES-CCM* to SubMac layer (#4919) In Thread 1.2, it is possible to receive an IEEE 802.15.4-2015 packet. Per specification, receiver should acknowledge this packet with an IEEE 802.15.4-2015 ACK(Enh-ACK). This Enh-ACK can include header IE with it and requires security enabled bit in FCF be set to true. It is impractical for the host to generate the Enh-ACK and send to RCP for transmission within AIFS time(192us). So RCP should prepare the Enh-ACK by itself, which requires it to fill in the frame counter and do the encryption/authentication. This commit tries to address the need of transmission security/authentication by including the following changes, - Move Key ID mode 1 AES-CCM* related functions from MAC layer to SubMac layer, which is mirrored in RCP. - Distribute the MAC key and MAC key ID to RCP in posix app using newly added spinel properties. - Make it possible for radio(either in radio driver or hardware) to do transmission AES-CCM* if the platform supports by adding radio capability OT_RADIO_CAPS_TRANSMIT_SEC. - Enable this for RCP mode on simulation platform. --- examples/apps/ncp/Makefile.am | 9 ++ .../cc2538/openthread-core-cc2538-config.h | 24 ++-- .../efr32mg12/openthread-core-efr32-config.h | 20 +++- .../efr32mg13/openthread-core-efr32-config.h | 20 +++- .../efr32mg21/openthread-core-efr32-config.h | 20 +++- .../kw41z/openthread-core-kw41z-config.h | 16 ++- .../openthread-core-nrf52811-config.h | 28 +++-- .../openthread-core-nrf52833-config.h | 28 +++-- .../openthread-core-nrf52840-config.h | 28 +++-- .../openthread-core-simulation-config.h | 38 +++--- include/openthread/link_raw.h | 21 ++++ include/openthread/platform/radio.h | 24 ++++ script/check-scan-build | 19 +-- script/check-simulation-build-autotools | 19 +-- src/core/CMakeLists.txt | 7 ++ src/core/Makefile.am | 2 + src/core/api/link_raw_api.cpp | 11 ++ src/core/config/link_raw.h | 48 -------- src/core/config/mac.h | 50 ++++++++ .../config/openthread-core-config-check.h | 30 ++++- src/core/crypto/aes_ccm.cpp | 15 +++ src/core/crypto/aes_ccm.hpp | 20 ++++ src/core/mac/link_raw.cpp | 15 +++ src/core/mac/link_raw.hpp | 19 +++ src/core/mac/mac.cpp | 44 ++++--- src/core/mac/mac.hpp | 14 +-- src/core/mac/mac_frame.cpp | 14 +-- src/core/mac/mac_frame.hpp | 29 +++++ src/core/mac/sub_mac.cpp | 110 ++++++++++++++++-- src/core/mac/sub_mac.hpp | 48 ++++++++ src/core/radio/radio.hpp | 21 ++++ src/core/radio/radio_platform.cpp | 17 +++ src/core/thread/key_manager.cpp | 40 +++---- src/core/thread/key_manager.hpp | 43 +------ src/core/thread/mle.cpp | 10 +- src/lib/spinel/radio_spinel.hpp | 22 ++++ src/lib/spinel/radio_spinel_impl.hpp | 34 +++++- src/lib/spinel/spinel.h | 23 ++++ src/ncp/ncp_base_dispatcher.cpp | 5 + src/ncp/ncp_base_radio.cpp | 46 +++++++- src/posix/platform/radio.cpp | 12 ++ tests/toranj/openthread-core-toranj-config.h | 20 +++- third_party/mbedtls/Makefile.am | 17 ++- 43 files changed, 822 insertions(+), 278 deletions(-) diff --git a/examples/apps/ncp/Makefile.am b/examples/apps/ncp/Makefile.am index 4881d06cf..d4359ac0b 100644 --- a/examples/apps/ncp/Makefile.am +++ b/examples/apps/ncp/Makefile.am @@ -54,6 +54,9 @@ SOURCES_COMMON += \ LDADD_MBEDTLS = \ $(NULL) +LDADD_MBEDTLS_RADIO = \ + $(NULL) + LDADD_DIAG = \ $(NULL) @@ -61,6 +64,10 @@ if OPENTHREAD_ENABLE_BUILTIN_MBEDTLS LDADD_MBEDTLS += \ $(top_builddir)/third_party/mbedtls/libmbedcrypto.a \ $(NULL) + +LDADD_MBEDTLS_RADIO += \ + $(top_builddir)/third_party/mbedtls/libmbedcrypto_radio.a \ + $(NULL) endif # OPENTHREAD_ENABLE_BUILTIN_MBEDTLS if OPENTHREAD_ENABLE_NCP_SPINEL_ENCRYPTER @@ -151,8 +158,10 @@ ot_rcp_LDADD = \ $(top_builddir)/src/ncp/libopenthread-rcp.a \ $(top_builddir)/src/core/libopenthread-radio.a \ $(LDADD_COMMON) \ + $(LDADD_MBEDTLS_RADIO) \ $(top_builddir)/src/core/libopenthread-radio.a \ $(LDADD_COMMON) \ + $(LDADD_MBEDTLS_RADIO) \ $(NULL) ot_rcp_LDFLAGS = \ diff --git a/examples/platforms/cc2538/openthread-core-cc2538-config.h b/examples/platforms/cc2538/openthread-core-cc2538-config.h index 587bac900..fabb6faae 100644 --- a/examples/platforms/cc2538/openthread-core-cc2538-config.h +++ b/examples/platforms/cc2538/openthread-core-cc2538-config.h @@ -43,36 +43,44 @@ #define OPENTHREAD_CONFIG_PLATFORM_INFO "CC2538" /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE * * Define to 1 if you want to enable software ACK timeout logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE * * Define to 1 if you want to enable software energy scanning logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1 /** * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE diff --git a/examples/platforms/efr32mg12/openthread-core-efr32-config.h b/examples/platforms/efr32mg12/openthread-core-efr32-config.h index d7eead986..d1cbde654 100644 --- a/examples/platforms/efr32mg12/openthread-core-efr32-config.h +++ b/examples/platforms/efr32mg12/openthread-core-efr32-config.h @@ -80,28 +80,36 @@ #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32" /* - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE * * Define to 1 if you want to enable software energy scanning logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 0 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0 /** * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE diff --git a/examples/platforms/efr32mg13/openthread-core-efr32-config.h b/examples/platforms/efr32mg13/openthread-core-efr32-config.h index d7eead986..d1cbde654 100644 --- a/examples/platforms/efr32mg13/openthread-core-efr32-config.h +++ b/examples/platforms/efr32mg13/openthread-core-efr32-config.h @@ -80,28 +80,36 @@ #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32" /* - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE * * Define to 1 if you want to enable software energy scanning logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 0 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0 /** * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE diff --git a/examples/platforms/efr32mg21/openthread-core-efr32-config.h b/examples/platforms/efr32mg21/openthread-core-efr32-config.h index 244e13823..a4e53d462 100644 --- a/examples/platforms/efr32mg21/openthread-core-efr32-config.h +++ b/examples/platforms/efr32mg21/openthread-core-efr32-config.h @@ -77,28 +77,36 @@ #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32" /* - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE * * Define to 1 if you want to enable software energy scanning logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1 /** * @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE diff --git a/examples/platforms/kw41z/openthread-core-kw41z-config.h b/examples/platforms/kw41z/openthread-core-kw41z-config.h index 9ae507bd6..923dc037b 100644 --- a/examples/platforms/kw41z/openthread-core-kw41z-config.h +++ b/examples/platforms/kw41z/openthread-core-kw41z-config.h @@ -71,20 +71,28 @@ #define RADIO_CONFIG_SRC_MATCH_ENTRY_NUM 128 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 /** * @def OPENTHREAD_CONFIG_NCP_UART_ENABLE diff --git a/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h b/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h index 0e9f3f2c8..6dc856cfd 100644 --- a/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h +++ b/examples/platforms/nrf528xx/nrf52811/openthread-core-nrf52811-config.h @@ -111,33 +111,43 @@ #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE * * Define to 1 if you want to enable software ACK timeout logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 #endif /** diff --git a/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h b/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h index 3fab30a50..995b1da62 100644 --- a/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h +++ b/examples/platforms/nrf528xx/nrf52833/openthread-core-nrf52833-config.h @@ -133,33 +133,43 @@ #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE * * Define to 1 if you want to enable software ACK timeout logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 #endif /** diff --git a/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h b/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h index be29d37c9..c70558a68 100644 --- a/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h +++ b/examples/platforms/nrf528xx/nrf52840/openthread-core-nrf52840-config.h @@ -133,33 +133,43 @@ #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE * * Define to 1 if you want to enable software ACK timeout logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 #endif /** diff --git a/examples/platforms/simulation/openthread-core-simulation-config.h b/examples/platforms/simulation/openthread-core-simulation-config.h index 50d783579..2e3a776a1 100644 --- a/examples/platforms/simulation/openthread-core-simulation-config.h +++ b/examples/platforms/simulation/openthread-core-simulation-config.h @@ -69,49 +69,53 @@ #if OPENTHREAD_RADIO /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE * * Define to 1 if you want to enable software ACK timeout logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE * * Define to 1 if you want to enable software energy scanning logic. * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). - * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 1 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). - * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 #endif /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. * */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 1 #endif #endif // OPENTHREAD_RADIO diff --git a/include/openthread/link_raw.h b/include/openthread/link_raw.h index 19832988b..f3297fc65 100644 --- a/include/openthread/link_raw.h +++ b/include/openthread/link_raw.h @@ -330,6 +330,27 @@ otError otLinkRawSrcMatchClearShortEntries(otInstance *aInstance); */ otError otLinkRawSrcMatchClearExtEntries(otInstance *aInstance); +/** + * Update MAC keys and key index. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aKeyIdMode The key ID mode. + * @param[in] aKeyId The key index. + * @param[in] aPrevKey The previous MAC key. + * @param[in] aCurrKey The current MAC key. + * @param[in] aNextKey The next MAC key. + * + * @retval OT_ERROR_NONE If successful. + * @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled. + * + */ +otError otLinkRawSetMacKey(otInstance * aInstance, + uint8_t aKeyIdMode, + uint8_t aKeyId, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey); + /** * @} * diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h index 7e4724810..1f08ff3dd 100644 --- a/include/openthread/platform/radio.h +++ b/include/openthread/platform/radio.h @@ -124,6 +124,7 @@ enum OT_RADIO_CAPS_TRANSMIT_RETRIES = 1 << 2, ///< Radio supports tx retry logic with collision avoidance (CSMA). OT_RADIO_CAPS_CSMA_BACKOFF = 1 << 3, ///< Radio supports CSMA backoff for frame transmission (but no retry). OT_RADIO_CAPS_SLEEP_TO_TX = 1 << 4, ///< Radio supports direct transition from sleep to TX with CSMA. + OT_RADIO_CAPS_TRANSMIT_SEC = 1 << 5, ///< Radio supports tx security. }; #define OT_PANID_BROADCAST 0xffff ///< IEEE 802.15.4 Broadcast PAN ID @@ -196,6 +197,7 @@ typedef struct otRadioFrame uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure. bool mIsARetx : 1; ///< True if this frame is a retransmission (ignored by radio driver). bool mCsmaCaEnabled : 1; ///< Set to true to enable CSMA-CA for this packet, false otherwise. + bool mIsSecurityProcessed : 1; ///< True if SubMac should skip the AES processing of this frame. } mTxInfo; /** @@ -433,6 +435,28 @@ bool otPlatRadioGetPromiscuous(otInstance *aInstance); */ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable); +/** + * Update MAC keys and key index + * + * This function is used when radio provides OT_RADIO_CAPS_TRANSMIT_SEC capability. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aKeyIdMode The key ID mode. + * @param[in] aKeyId Current MAC key index. + * @param[in] aKeySize The key size. + * @param[in] aPrevKey A pointer to the previous MAC key. + * @param[in] aCurrKey A pointer to the current MAC key. + * @param[in] aNextKey A pointer to the next MAC key. + * + */ +void otPlatRadioSetMacKey(otInstance * aInstance, + uint8_t aKeyIdMode, + uint8_t aKeyId, + uint8_t aKeySize, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey); + /** * @} * diff --git a/script/check-scan-build b/script/check-scan-build index 97bd6fd6e..65e5516ca 100755 --- a/script/check-scan-build +++ b/script/check-scan-build @@ -51,27 +51,28 @@ do_scan_build() "-DOPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1" "-DOPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1" "-DOPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1" + "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1" + "-DOPENTHREAD_CONFIG_JOINER_ENABLE=1" "-DOPENTHREAD_CONFIG_LEGACY_ENABLE=1" + "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1" + "-DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1" "-DOPENTHREAD_CONFIG_MAC_BEACON_RSP_WHEN_JOINABLE_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1" "-DOPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE=1" "-DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1" "-DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1" "-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE" - "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1" - "-DOPENTHREAD_CONFIG_JOINER_ENABLE=1" - "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1" - "-DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1" - "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1" "-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1" "-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE=1" "-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1" "-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1" "-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1" diff --git a/script/check-simulation-build-autotools b/script/check-simulation-build-autotools index ee388d534..3f67913f4 100755 --- a/script/check-simulation-build-autotools +++ b/script/check-simulation-build-autotools @@ -56,17 +56,22 @@ build_all_features() "-DOPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE=1" "-DOPENTHREAD_CONFIG_IP6_FRAGMENTATION_ENABLE=1" "-DOPENTHREAD_CONFIG_IP6_SLAAC_ENABLE=1" + "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1" + "-DOPENTHREAD_CONFIG_JOINER_ENABLE=1" "-DOPENTHREAD_CONFIG_LEGACY_ENABLE=1" + "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1" + "-DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1" "-DOPENTHREAD_CONFIG_MAC_BEACON_RSP_WHEN_JOINABLE_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1" "-DOPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE=1" + "-DOPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE=1" "-DOPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE=1" "-DOPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE=1" "-DOPENTHREAD_CONFIG_MPL_DYNAMIC_INTERVAL_ENABLE" - "-DOPENTHREAD_CONFIG_JAM_DETECTION_ENABLE=1" - "-DOPENTHREAD_CONFIG_JOINER_ENABLE=1" - "-DOPENTHREAD_CONFIG_LINK_RAW_ENABLE=1" - "-DOPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE=1" - "-DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1" "-DOPENTHREAD_CONFIG_NCP_UART_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE=1" "-DOPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE=1" @@ -74,10 +79,6 @@ build_all_features() "-DOPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE=1" "-DOPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE=1" "-DOPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE=1" - "-DOPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE=1" "-DOPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE=1" "-DOPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE=1" "-DOPENTHREAD_CONFIG_UDP_FORWARD_ENABLE=1" diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index bc5ac2a92..33c772ce9 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -231,6 +231,8 @@ target_sources(openthread-radio PRIVATE common/string.cpp common/tasklet.cpp common/timer.cpp + crypto/aes_ccm.cpp + crypto/aes_ecb.cpp diags/factory_diags.cpp mac/link_raw.cpp mac/mac_frame.cpp @@ -253,3 +255,8 @@ target_link_libraries(openthread-mtd PRIVATE ${OT_MBEDTLS} ) + +target_link_libraries(openthread-radio + PRIVATE + ${OT_MBEDTLS} +) diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 51a7b62a4..b7733746a 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -267,6 +267,8 @@ libopenthread_radio_a_SOURCES = \ common/string.cpp \ common/tasklet.cpp \ common/timer.cpp \ + crypto/aes_ccm.cpp \ + crypto/aes_ecb.cpp \ diags/factory_diags.cpp \ mac/link_raw.cpp \ mac/mac_frame.cpp \ diff --git a/src/core/api/link_raw_api.cpp b/src/core/api/link_raw_api.cpp index 0db29bd2c..f0b99beeb 100644 --- a/src/core/api/link_raw_api.cpp +++ b/src/core/api/link_raw_api.cpp @@ -221,6 +221,17 @@ exit: return error; } +otError otLinkRawSetMacKey(otInstance * aInstance, + uint8_t aKeyIdMode, + uint8_t aKeyId, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) +{ + return static_cast(aInstance)->Get().SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, + aNextKey); +} + #if OPENTHREAD_RADIO otDeviceRole otThreadGetDeviceRole(otInstance *aInstance) diff --git a/src/core/config/link_raw.h b/src/core/config/link_raw.h index 1b9dda2d7..6c2ceebeb 100644 --- a/src/core/config/link_raw.h +++ b/src/core/config/link_raw.h @@ -45,52 +45,4 @@ #define OPENTHREAD_CONFIG_LINK_RAW_ENABLE 0 #endif -/** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE - * - * Define to 1 to enable software ACK timeout logic. - * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). - * - */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 0 -#endif - -/** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE - * - * Define to 1 to enable software retransmission logic. - * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). - * - */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 0 -#endif - -/** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE - * - * Define to 1 to enable software CSMA-CA backoff logic. - * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). - * - */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 0 -#endif - -/** - * @def OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE - * - * Define to 1 to enable software energy scanning logic. - * - * Applicable only if raw link layer API is enabled (i.e., `OPENTHREAD_CONFIG_LINK_RAW_ENABLE` is set). - * - */ -#ifndef OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE -#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 0 -#endif - #endif // CONFIG_LINK_RAW_H_ diff --git a/src/core/config/mac.h b/src/core/config/mac.h index 9c36a6b80..c92436539 100644 --- a/src/core/config/mac.h +++ b/src/core/config/mac.h @@ -255,6 +255,56 @@ #define OPENTHREAD_CONFIG_MAC_RETX_POLL_PERIOD 1000 #endif +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE + * + * Define to 1 to enable software ACK timeout logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE + * + * Define to 1 to enable software retransmission logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE + * + * Define to 1 to enable software CSMA-CA backoff logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 to enable software transmission security logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE + * + * Define to 1 to enable software energy scanning logic. + * + */ +#ifndef OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE 0 +#endif + /** * @def OPENTHREAD_CONFIG_CSL_TRANSMITTER_ENABLE * diff --git a/src/core/config/openthread-core-config-check.h b/src/core/config/openthread-core-config-check.h index 2af9867f4..9cb88cd27 100644 --- a/src/core/config/openthread-core-config-check.h +++ b/src/core/config/openthread-core-config-check.h @@ -321,19 +321,41 @@ #endif #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT -#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT was replaced by OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE." +#error \ + "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE." +#endif + +#ifdef OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE +#error \ + "OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE." #endif #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT -#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT was replaced by OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE." +#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE." +#endif + +#ifdef OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE +#error "OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE." #endif #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF -#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF was replaced by OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE." +#error \ + "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_CSMA_BACKOFF was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE." +#endif + +#ifdef OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE +#error \ + "OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE." #endif #ifdef OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN -#error "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN was replaced by OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE." +#error \ + "OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE." +#endif + +#ifdef OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE +#error \ + "OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE was replaced by OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE." #endif #ifdef OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER diff --git a/src/core/crypto/aes_ccm.cpp b/src/core/crypto/aes_ccm.cpp index 78c24e3b1..a59e3f856 100644 --- a/src/core/crypto/aes_ccm.cpp +++ b/src/core/crypto/aes_ccm.cpp @@ -35,6 +35,7 @@ #include "common/code_utils.hpp" #include "common/debug.hpp" +#include "common/encoding.hpp" namespace ot { namespace Crypto { @@ -283,5 +284,19 @@ void AesCcm::Finalize(void *aTag, uint8_t *aTagLength) } } +void AesCcm::GenerateNonce(const Mac::ExtAddress &aAddress, + uint32_t aFrameCounter, + uint8_t aSecurityLevel, + uint8_t * aNonce) +{ + memcpy(aNonce, aAddress.m8, sizeof(Mac::ExtAddress)); + aNonce += sizeof(Mac::ExtAddress); + + Encoding::BigEndian::WriteUint32(aFrameCounter, aNonce); + aNonce += sizeof(uint32_t); + + aNonce[0] = aSecurityLevel; +} + } // namespace Crypto } // namespace ot diff --git a/src/core/crypto/aes_ccm.hpp b/src/core/crypto/aes_ccm.hpp index ba4099b5a..8682c8109 100644 --- a/src/core/crypto/aes_ccm.hpp +++ b/src/core/crypto/aes_ccm.hpp @@ -41,6 +41,7 @@ #include #include "crypto/aes_ecb.hpp" +#include "mac/mac_types.hpp" namespace ot { namespace Crypto { @@ -59,6 +60,11 @@ namespace Crypto { class AesCcm { public: + enum + { + kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). + }; + /** * This method sets the key. * @@ -116,6 +122,20 @@ public: */ void Finalize(void *aTag, uint8_t *aTagLength); + /** + * This static method generates IEEE 802.15.4 nonce byte sequence. + * + * @param[in] aAddress An extended address. + * @param[in] aFrameCounter A frame counter. + * @param[in] aSecurityLevel A security level. + * @param[out] aNonce A buffer (with `kNonceSize` bytes) to place the generated nonce. + * + */ + static void GenerateNonce(const Mac::ExtAddress &aAddress, + uint32_t aFrameCounter, + uint8_t aSecurityLevel, + uint8_t * aNonce); + private: enum { diff --git a/src/core/mac/link_raw.cpp b/src/core/mac/link_raw.cpp index 435dc56e2..993aa1549 100644 --- a/src/core/mac/link_raw.cpp +++ b/src/core/mac/link_raw.cpp @@ -205,6 +205,21 @@ void LinkRaw::InvokeEnergyScanDone(int8_t aEnergyScanMaxRssi) } } +otError LinkRaw::SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) +{ + otError error = OT_ERROR_NONE; + + VerifyOrExit(IsEnabled(), error = OT_ERROR_INVALID_STATE); + mSubMac.SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey); + +exit: + return error; +} + // LCOV_EXCL_START #if (OPENTHREAD_CONFIG_LOG_LEVEL >= OT_LOG_LEVEL_INFO) && (OPENTHREAD_CONFIG_LOG_MAC == 1) diff --git a/src/core/mac/link_raw.hpp b/src/core/mac/link_raw.hpp index 6e2181776..b9f2d5a4f 100644 --- a/src/core/mac/link_raw.hpp +++ b/src/core/mac/link_raw.hpp @@ -243,6 +243,25 @@ public: */ otError SetExtAddress(const ExtAddress &aExtAddress); + /** + * This method updates MAC keys and key index. + * + * @param[in] aKeyIdMode The key ID mode. + * @param[in] aKeyId The key index. + * @param[in] aPrevKey The previous MAC key. + * @param[in] aCurrKey The current MAC key. + * @param[in] aNextKey The next MAC key. + * + * @retval OT_ERROR_NONE If successful. + * @retval OT_ERROR_INVALID_STATE If the raw link-layer isn't enabled. + * + */ + otError SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey); + /** * This method records the status of a frame transmission attempt and is mainly used for logging failures. * diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 91c38ba4a..b1338c596 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -135,6 +135,7 @@ Mac::Mac(Instance &aInstance) SetEnabled(true); IgnoreError(mSubMac.Enable()); + Get().UpdateKeyMaterial(); SetExtendedPanId(static_cast(sExtendedPanidInit)); IgnoreError(SetNetworkName(sNetworkNameInit)); #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2) @@ -944,7 +945,7 @@ bool Mac::IsJoinable(void) const return (numUnsecurePorts != 0); } -void Mac::ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm) +void Mac::ProcessTransmitSecurity(TxFrame &aFrame) { KeyManager & keyManager = Get(); uint8_t keyIdMode; @@ -969,9 +970,6 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm) break; case Frame::kKeyIdMode1: - aFrame.SetAesKey(keyManager.GetCurrentMacKey()); - extAddress = &GetExtAddress(); - // If the frame is marked as a retransmission, `MeshForwarder` which // prepared the frame should set the frame counter and key id to the // same values used in the earlier transmit attempt. For a new frame (not @@ -982,9 +980,10 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm) { aFrame.SetFrameCounter(keyManager.GetMacFrameCounter()); keyManager.IncrementMacFrameCounter(); - aFrame.SetKeyId((keyManager.GetCurrentKeySequence() & 0x7f) + 1); } + // For MAC key ID mode 1, the AES CCM* is done at SubMac or Radio if supported + ExitNow(); break; case Frame::kKeyIdMode2: @@ -1004,10 +1003,12 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm) OT_UNREACHABLE_CODE(break); } - if (aProcessAesCcm) - { - aFrame.ProcessTransmitAesCcm(*extAddress); - } +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + // Transmit security will be processed after time IE content is updated. + VerifyOrExit(aFrame.GetTimeIeOffset() == 0, OT_NOOP); +#endif + + aFrame.ProcessTransmitAesCcm(*extAddress); exit: return; @@ -1015,13 +1016,12 @@ exit: void Mac::BeginTransmit(void) { - otError error = OT_ERROR_NONE; - bool applyTransmitSecurity = true; - bool processTransmitAesCcm = true; - TxFrame &sendFrame = mSubMac.GetTransmitFrame(); + otError error = OT_ERROR_NONE; + TxFrame &sendFrame = mSubMac.GetTransmitFrame(); VerifyOrExit(IsEnabled(), error = OT_ERROR_ABORT); sendFrame.SetIsARetransmission(false); + sendFrame.SetIsSecurityProcessed(false); switch (mOperation) { @@ -1075,7 +1075,7 @@ void Mac::BeginTransmit(void) case kOperationTransmitOutOfBandFrame: sendFrame.CopyFrom(*mOobFrame); - applyTransmitSecurity = false; + sendFrame.SetIsSecurityProcessed(true); break; default: @@ -1091,17 +1091,15 @@ void Mac::BeginTransmit(void) if (timeIeOffset != 0) { - // Transmit security will be processed after time IE content is updated. - processTransmitAesCcm = false; sendFrame.SetTimeSyncSeq(Get().GetTimeSyncSeq()); sendFrame.SetNetworkTimeOffset(Get().GetNetworkTimeOffset()); } } #endif - if (applyTransmitSecurity) + if (!sendFrame.IsSecurityProcessed()) { - ProcessTransmitSecurity(sendFrame, processTransmitAesCcm); + ProcessTransmitSecurity(sendFrame); } mBroadcastTransmitCount = 0; @@ -1429,7 +1427,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne uint8_t securityLevel; uint8_t keyIdMode; uint32_t frameCounter; - uint8_t nonce[KeyManager::kNonceSize]; + uint8_t nonce[Crypto::AesCcm::kNonceSize]; uint8_t tag[Frame::kMaxMicSize]; uint8_t tagLength; uint8_t keyid; @@ -1465,17 +1463,17 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne if (keyid == (keyManager.GetCurrentKeySequence() & 0x7f)) { keySequence = keyManager.GetCurrentKeySequence(); - macKey = keyManager.GetCurrentMacKey(); + macKey = mSubMac.GetCurrentMacKey(); } else if (keyid == ((keyManager.GetCurrentKeySequence() - 1) & 0x7f)) { keySequence = keyManager.GetCurrentKeySequence() - 1; - macKey = keyManager.GetTemporaryMacKey(keySequence); + macKey = mSubMac.GetPreviousMacKey(); } else if (keyid == ((keyManager.GetCurrentKeySequence() + 1) & 0x7f)) { keySequence = keyManager.GetCurrentKeySequence() + 1; - macKey = keyManager.GetTemporaryMacKey(keySequence); + macKey = mSubMac.GetNextMacKey(); } else { @@ -1514,7 +1512,7 @@ otError Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Ne OT_UNREACHABLE_CODE(break); } - KeyManager::GenerateNonce(*extAddress, frameCounter, securityLevel, nonce); + Crypto::AesCcm::GenerateNonce(*extAddress, frameCounter, securityLevel, nonce); tagLength = aFrame.GetFooterLength() - Frame::kFcsSize; aesCcm.SetKey(macKey, 16); diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 906bf29f1..8ec23cd49 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -709,19 +709,7 @@ private: }; #endif // OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE - /** - * This method processes transmit security on the frame which is going to be sent. - * - * This method prepares the frame, fills Mac auxiliary header, and perform AES CCM immediately in most cases - * (depends on @p aProcessAesCcm). If aProcessAesCcm is False, it probably means that some content in the frame - * will be updated just before transmission, so AES CCM will be performed after that (before transmission). - * - * @param[in] aFrame A reference to the MAC frame buffer which is going to be sent. - * @param[in] aProcessAesCcm TRUE to perform AES CCM immediately, FALSE otherwise. - * - */ - void ProcessTransmitSecurity(TxFrame &aFrame, bool aProcessAesCcm); - + void ProcessTransmitSecurity(TxFrame &aFrame); otError ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neighbor *aNeighbor); void UpdateIdleMode(void); void StartOperation(Operation aOperation); diff --git a/src/core/mac/mac_frame.cpp b/src/core/mac/mac_frame.cpp index ad77835f4..8c80ba919 100644 --- a/src/core/mac/mac_frame.cpp +++ b/src/core/mac/mac_frame.cpp @@ -37,10 +37,8 @@ #include "common/code_utils.hpp" #include "common/debug.hpp" - -#if OPENTHREAD_MTD || OPENTHREAD_FTD +#if !OPENTHREAD_RADIO || OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE #include "crypto/aes_ccm.hpp" -#include "thread/key_manager.hpp" #endif namespace ot { @@ -1034,12 +1032,12 @@ void TxFrame::CopyFrom(const TxFrame &aFromFrame) void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress) { -#if OPENTHREAD_RADIO +#if OPENTHREAD_RADIO && !OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE OT_UNUSED_VARIABLE(aExtAddress); #else uint32_t frameCounter = 0; uint8_t securityLevel; - uint8_t nonce[KeyManager::kNonceSize]; + uint8_t nonce[Crypto::AesCcm::kNonceSize]; uint8_t tagLength; Crypto::AesCcm aesCcm; otError error; @@ -1049,7 +1047,7 @@ void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress) SuccessOrExit(error = GetSecurityLevel(securityLevel)); SuccessOrExit(error = GetFrameCounter(frameCounter)); - KeyManager::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce); + Crypto::AesCcm::GenerateNonce(aExtAddress, frameCounter, securityLevel, nonce); aesCcm.SetKey(GetAesKey(), 16); tagLength = GetFooterLength() - Frame::kFcsSize; @@ -1061,9 +1059,11 @@ void TxFrame::ProcessTransmitAesCcm(const ExtAddress &aExtAddress) aesCcm.Payload(GetPayload(), GetPayload(), GetPayloadLength(), true); aesCcm.Finalize(GetFooter(), &tagLength); + SetIsSecurityProcessed(true); + exit: return; -#endif // OPENTHREAD_RADIO +#endif // OPENTHREAD_RADIO && !OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE } void TxFrame::GenerateImmAck(const RxFrame &aFrame, bool aIsFramePending) diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index cc9f16083..0401dcfe0 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -1200,6 +1200,27 @@ public: * */ void ProcessTransmitAesCcm(const ExtAddress &aExtAddress); + + /** + * This method indicates whether or not the frame has security processed. + * + * @retval TRUE The frame already has security processed. + * @retval FALSE The frame does not have security processed. + * + */ + bool IsSecurityProcessed(void) const { return mInfo.mTxInfo.mIsSecurityProcessed; } + + /** + * This method sets the security processed flag attribute. + * + * @param[in] aIsSecurityProcessed TRUE if the frame already has security processed. + * + */ + void SetIsSecurityProcessed(bool aIsSecurityProcessed) + { + mInfo.mTxInfo.mIsSecurityProcessed = aIsSecurityProcessed; + } + #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE /** * This method sets the Time IE offset. @@ -1209,6 +1230,14 @@ public: */ void SetTimeIeOffset(uint8_t aOffset) { mInfo.mTxInfo.mIeInfo->mTimeIeOffset = aOffset; } + /** + * This method gets the Time IE offset. + * + * @returns The Time IE offset, 0 means no Time IE. + * + */ + uint8_t GetTimeIeOffset(void) const { return mInfo.mTxInfo.mIeInfo->mTimeIeOffset; } + /** * This method sets the offset to network time. * diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index a8b0497c2..89b0917e7 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -59,9 +59,13 @@ SubMac::SubMac(Instance &aInstance) , mCallbacks(aInstance) , mPcapCallback(NULL) , mPcapCallbackContext(NULL) + , mKeyId(0) , mTimer(aInstance, &SubMac::HandleTimer, this) { mExtAddress.Clear(); + memset(mPrevKey, 0, sizeof(mPrevKey)); + memset(mCurrKey, 0, sizeof(mCurrKey)); + memset(mNextKey, 0, sizeof(mNextKey)); } otRadioCaps SubMac::GetCaps(void) const @@ -70,25 +74,29 @@ otRadioCaps SubMac::GetCaps(void) const #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE -#if OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE caps |= OT_RADIO_CAPS_ACK_TIMEOUT; #endif -#if OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE caps |= OT_RADIO_CAPS_CSMA_BACKOFF; #endif -#if OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE caps |= OT_RADIO_CAPS_TRANSMIT_RETRIES; #endif -#if OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE caps |= OT_RADIO_CAPS_ENERGY_SCAN; #endif +#if OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + caps |= OT_RADIO_CAPS_TRANSMIT_SEC; +#endif + #else caps = OT_RADIO_CAPS_ACK_TIMEOUT | OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES | - OT_RADIO_CAPS_ENERGY_SCAN; + OT_RADIO_CAPS_ENERGY_SCAN | OT_RADIO_CAPS_TRANSMIT_SEC; #endif return caps; @@ -214,6 +222,7 @@ otError SubMac::Send(void) break; } + ProcessTransmitSecurity(); mCsmaBackoffs = 0; mTransmitRetries = 0; StartCsmaBackoff(); @@ -222,6 +231,37 @@ exit: return error; } +void SubMac::ProcessTransmitSecurity(void) +{ + const ExtAddress *extAddress = NULL; + uint8_t keyIdMode; + + VerifyOrExit(ShouldHandleTransmitSecurity(), OT_NOOP); + VerifyOrExit(mTransmitFrame.GetSecurityEnabled(), OT_NOOP); + VerifyOrExit(!mTransmitFrame.IsSecurityProcessed(), OT_NOOP); + + SuccessOrExit(mTransmitFrame.GetKeyIdMode(keyIdMode)); + VerifyOrExit(keyIdMode == Frame::kKeyIdMode1, OT_NOOP); + + mTransmitFrame.SetAesKey(GetCurrentMacKey()); + if (!mTransmitFrame.IsARetransmission()) + { + mTransmitFrame.SetKeyId(mKeyId); + } + + extAddress = &GetExtAddress(); + +#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE + // Transmit security will be processed after time IE content is updated. + VerifyOrExit(mTransmitFrame.GetTimeIeOffset() == 0, OT_NOOP); +#endif + + mTransmitFrame.ProcessTransmitAesCcm(*extAddress); + +exit: + return; +} + void SubMac::StartCsmaBackoff(void) { uint32_t backoff; @@ -484,6 +524,24 @@ void SubMac::HandleTimer(void) } } +bool SubMac::ShouldHandleTransmitSecurity(void) const +{ + bool swTxSecurity = true; + + VerifyOrExit(!RadioSupportsTransmitSecurity(), swTxSecurity = false); + +#if OPENTHREAD_CONFIG_LINK_RAW_ENABLE + VerifyOrExit(Get().IsEnabled(), OT_NOOP); +#endif + +#if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO + swTxSecurity = OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE; +#endif + +exit: + return swTxSecurity; +} + bool SubMac::ShouldHandleCsmaBackOff(void) const { bool swCsma = true; @@ -495,7 +553,7 @@ bool SubMac::ShouldHandleCsmaBackOff(void) const #endif #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO - swCsma = OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE; + swCsma = OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE; #endif exit: @@ -513,7 +571,7 @@ bool SubMac::ShouldHandleAckTimeout(void) const #endif #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO - swAckTimeout = OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE; + swAckTimeout = OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE; #endif exit: @@ -531,7 +589,7 @@ bool SubMac::ShouldHandleRetries(void) const #endif #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO - swRetries = OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE; + swRetries = OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE; #endif exit: @@ -549,7 +607,7 @@ bool SubMac::ShouldHandleEnergyScan(void) const #endif #if OPENTHREAD_CONFIG_LINK_RAW_ENABLE || OPENTHREAD_RADIO - swEnergyScan = OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE; + swEnergyScan = OPENTHREAD_CONFIG_MAC_SOFTWARE_ENERGY_SCAN_ENABLE; #endif exit: @@ -565,6 +623,40 @@ void SubMac::SetState(State aState) } } +void SubMac::SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) +{ + switch (aKeyIdMode) + { + case Frame::kKeyIdMode0: + case Frame::kKeyIdMode2: + break; + case Frame::kKeyIdMode1: + OT_ASSERT(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL); + + mKeyId = aKeyId; + memcpy(mPrevKey, aPrevKey, sizeof(mPrevKey)); + memcpy(mCurrKey, aCurrKey, sizeof(mCurrKey)); + memcpy(mNextKey, aNextKey, sizeof(mNextKey)); + + break; + + default: + OT_ASSERT(false); + break; + } + + VerifyOrExit(!ShouldHandleTransmitSecurity(), OT_NOOP); + + Get().SetMacKey(aKeyIdMode, aKeyId, kMacKeySize, aPrevKey, aCurrKey, aNextKey); + +exit: + return; +} + // LCOV_EXCL_START const char *SubMac::StateToString(State aState) diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index bb05166f6..c1a21a0bf 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -82,6 +82,7 @@ public: enum { kInvalidRssiValue = 127, ///< Invalid Received Signal Strength Indicator (RSSI) value. + kMacKeySize = 16, ///< MAC Key size (bytes) }; /** @@ -347,6 +348,46 @@ public: */ int8_t GetNoiseFloor(void); + /** + * This method sets MAC keys and key index. + * + * @param[in] aKeyIdMode MAC key ID mode. + * @param[in] aKeyId The key ID. + * @param[in] aPrevKey A pointer to the previous MAC key. + * @param[in] aCurrKey A pointer to the current MAC key. + * @param[in] aNextKey A pointer to the next MAC key. + * + */ + void SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey); + + /** + * This method returns a pointer to the current MAC key. + * + * @returns A pointer to the current MAC key. + * + */ + const uint8_t *GetCurrentMacKey(void) const { return mCurrKey; } + + /** + * This method returns a pointer to the previous MAC key. + * + * @returns A pointer to the previous MAC key. + * + */ + const uint8_t *GetPreviousMacKey(void) const { return mPrevKey; } + + /** + * This method returns a pointer to the next MAC key. + * + * @returns A pointer to the next MAC key. + * + */ + const uint8_t *GetNextMacKey(void) const { return mNextKey; } + private: enum { @@ -378,15 +419,18 @@ private: return ((mRadioCaps & (OT_RADIO_CAPS_CSMA_BACKOFF | OT_RADIO_CAPS_TRANSMIT_RETRIES)) != 0); } + bool RadioSupportsTransmitSecurity(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_SEC) != 0); } bool RadioSupportsRetries(void) const { return ((mRadioCaps & OT_RADIO_CAPS_TRANSMIT_RETRIES) != 0); } bool RadioSupportsAckTimeout(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ACK_TIMEOUT) != 0); } bool RadioSupportsEnergyScan(void) const { return ((mRadioCaps & OT_RADIO_CAPS_ENERGY_SCAN) != 0); } + bool ShouldHandleTransmitSecurity(void) const; bool ShouldHandleCsmaBackOff(void) const; bool ShouldHandleAckTimeout(void) const; bool ShouldHandleRetries(void) const; bool ShouldHandleEnergyScan(void) const; + void ProcessTransmitSecurity(void); void StartCsmaBackoff(void); void BeginTransmit(void); void SampleRssi(void); @@ -415,6 +459,10 @@ private: Callbacks mCallbacks; otLinkPcapCallback mPcapCallback; void * mPcapCallbackContext; + uint8_t mPrevKey[kMacKeySize]; + uint8_t mCurrKey[kMacKeySize]; + uint8_t mNextKey[kMacKeySize]; + uint8_t mKeyId; #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE TimerMicro mTimer; #else diff --git a/src/core/radio/radio.hpp b/src/core/radio/radio.hpp index 88a252133..841fcd73c 100644 --- a/src/core/radio/radio.hpp +++ b/src/core/radio/radio.hpp @@ -247,6 +247,27 @@ public: */ void SetShortAddress(Mac::ShortAddress aShortAddress); + /** + * This method sets MAC key and key ID. + * + * @param[in] aKeyIdMode MAC key ID mode. + * @param[in] aKeyId Current MAC key index. + * @param[in] aKeySize MAC key size in bytes. + * @param[in] aPrevKey A pointer to the previous MAC key. + * @param[in] aCurrKey A pointer to the current MAC key. + * @param[in] aNextKey A pointer to the next MAC key. + * + */ + void SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + uint8_t aKeySize, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) + { + otPlatRadioSetMacKey(GetInstance(), aKeyIdMode, aKeyId, aKeySize, aPrevKey, aCurrKey, aNextKey); + } + /** * This method gets the radio's transmit power in dBm. * diff --git a/src/core/radio/radio_platform.cpp b/src/core/radio/radio_platform.cpp index 014ece13d..46fedf2bd 100644 --- a/src/core/radio/radio_platform.cpp +++ b/src/core/radio/radio_platform.cpp @@ -124,3 +124,20 @@ OT_TOOL_WEAK otRadioState otPlatRadioGetState(otInstance *aInstance) return OT_RADIO_STATE_INVALID; } + +OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance * aInstance, + uint8_t aKeyIdMode, + uint8_t aKeyId, + uint8_t aKeySize, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) +{ + OT_UNUSED_VARIABLE(aInstance); + OT_UNUSED_VARIABLE(aKeyIdMode); + OT_UNUSED_VARIABLE(aKeyId); + OT_UNUSED_VARIABLE(aKeySize); + OT_UNUSED_VARIABLE(aPrevKey); + OT_UNUSED_VARIABLE(aCurrKey); + OT_UNUSED_VARIABLE(aNextKey); +} diff --git a/src/core/thread/key_manager.cpp b/src/core/thread/key_manager.cpp index a01c6bc50..53fe5b424 100644 --- a/src/core/thread/key_manager.cpp +++ b/src/core/thread/key_manager.cpp @@ -85,7 +85,6 @@ KeyManager::KeyManager(Instance &aInstance) { mMasterKey = static_cast(kDefaultMasterKey); mPskc.Clear(); - ComputeKey(mKeySequence, mKey); } void KeyManager::Start(void) @@ -116,7 +115,7 @@ otError KeyManager::SetMasterKey(const MasterKey &aKey) Get().Update(mMasterKey, aKey, OT_CHANGED_MASTER_KEY | OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER)); mKeySequence = 0; - ComputeKey(mKeySequence, mKey); + UpdateKeyMaterial(); // reset parent frame counters parent = &Get().GetParent(); @@ -160,6 +159,21 @@ void KeyManager::ComputeKey(uint32_t aKeySequence, uint8_t *aKey) hmac.Finish(aKey); } +void KeyManager::UpdateKeyMaterial() +{ + uint8_t prevKey[Crypto::HmacSha256::kHashSize]; + uint8_t currKey[Crypto::HmacSha256::kHashSize]; + uint8_t nextKey[Crypto::HmacSha256::kHashSize]; + + ComputeKey(mKeySequence - 1, prevKey); + ComputeKey(mKeySequence, currKey); + ComputeKey(mKeySequence + 1, nextKey); + + memcpy(mMleKey, currKey, kMleKeySize); + Get().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prevKey + kMacKeyOffset, + currKey + kMacKeyOffset, nextKey + kMacKeyOffset); +} + void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence) { VerifyOrExit(aKeySequence != mKeySequence, Get().SignalIfFirst(OT_CHANGED_THREAD_KEY_SEQUENCE_COUNTER)); @@ -177,7 +191,7 @@ void KeyManager::SetCurrentKeySequence(uint32_t aKeySequence) } mKeySequence = aKeySequence; - ComputeKey(mKeySequence, mKey); + UpdateKeyMaterial(); mMacFrameCounter = 0; mMleFrameCounter = 0; @@ -188,12 +202,6 @@ exit: return; } -const uint8_t *KeyManager::GetTemporaryMacKey(uint32_t aKeySequence) -{ - ComputeKey(aKeySequence, mTemporaryKey); - return mTemporaryKey + kMacKeyOffset; -} - const uint8_t *KeyManager::GetTemporaryMleKey(uint32_t aKeySequence) { ComputeKey(aKeySequence, mTemporaryKey); @@ -279,18 +287,4 @@ void KeyManager::HandleKeyRotationTimer(void) } } -void KeyManager::GenerateNonce(const Mac::ExtAddress &aAddress, - uint32_t aFrameCounter, - uint8_t aSecurityLevel, - uint8_t * aNonce) -{ - memcpy(aNonce, aAddress.m8, sizeof(Mac::ExtAddress)); - aNonce += sizeof(Mac::ExtAddress); - - Encoding::BigEndian::WriteUint32(aFrameCounter, aNonce); - aNonce += sizeof(uint32_t); - - aNonce[0] = aSecurityLevel; -} - } // namespace ot diff --git a/src/core/thread/key_manager.hpp b/src/core/thread/key_manager.hpp index 90aa14cd5..6ab23c40b 100644 --- a/src/core/thread/key_manager.hpp +++ b/src/core/thread/key_manager.hpp @@ -193,11 +193,6 @@ private: class KeyManager : public InstanceLocator { public: - enum - { - kNonceSize = 13, ///< Size of IEEE 802.15.4 Nonce (bytes). - }; - /** * This constructor initializes the object. * @@ -282,31 +277,13 @@ public: */ void SetCurrentKeySequence(uint32_t aKeySequence); - /** - * This method returns a pointer to the current MAC key. - * - * @returns A pointer to the current MAC key. - * - */ - const uint8_t *GetCurrentMacKey(void) const { return mKey + kMacKeyOffset; } - /** * This method returns a pointer to the current MLE key. * * @returns A pointer to the current MLE key. * */ - const uint8_t *GetCurrentMleKey(void) const { return mKey; } - - /** - * This method returns a pointer to a temporary MAC key computed from the given key sequence. - * - * @param[in] aKeySequence The key sequence value. - * - * @returns A pointer to the temporary MAC key. - * - */ - const uint8_t *GetTemporaryMacKey(uint32_t aKeySequence); + const uint8_t *GetCurrentMleKey(void) const { return mMleKey; } /** * This method returns a pointer to a temporary MLE key computed from the given key sequence. @@ -538,18 +515,10 @@ public: bool IsThreadBeaconEnabled(void) const { return (mSecurityPolicyFlags & OT_SECURITY_POLICY_BEACONS) != 0; } /** - * This static method generates IEEE 802.15.4 nonce byte sequence. - * - * @param[in] aAddress An extended address. - * @param[in] aFrameCounter A frame counter. - * @param[in] aSecurityLevel A security level. - * @param[out] aNonce A buffer (with `kNonceSize` bytes) to place the generated nonce. + * This method updates the MAC keys and MLE key. * */ - static void GenerateNonce(const Mac::ExtAddress &aAddress, - uint32_t aFrameCounter, - uint8_t aSecurityLevel, - uint8_t * aNonce); + void UpdateKeyMaterial(void); private: enum @@ -558,6 +527,7 @@ private: kDefaultKeyRotationTime = 672, kDefaultKeySwitchGuardTime = 624, kMacKeyOffset = 16, + kMleKeySize = 16, kOneHourIntervalInMsec = 3600u * 1000u, }; @@ -573,9 +543,8 @@ private: MasterKey mMasterKey; uint32_t mKeySequence; - uint8_t mKey[Crypto::HmacSha256::kHashSize]; - - uint8_t mTemporaryKey[Crypto::HmacSha256::kHashSize]; + uint8_t mMleKey[kMleKeySize]; + uint8_t mTemporaryKey[Crypto::HmacSha256::kHashSize]; uint32_t mMacFrameCounter; uint32_t mMleFrameCounter; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 939833a15..c172cd60c 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -2519,7 +2519,7 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination) otError error = OT_ERROR_NONE; Header header; uint32_t keySequence; - uint8_t nonce[KeyManager::kNonceSize]; + uint8_t nonce[Crypto::AesCcm::kNonceSize]; uint8_t tag[4]; uint8_t tagLength; Crypto::AesCcm aesCcm; @@ -2538,8 +2538,8 @@ otError Mle::SendMessage(Message &aMessage, const Ip6::Address &aDestination) aMessage.Write(0, header.GetLength(), &header); - KeyManager::GenerateNonce(Get().GetExtAddress(), Get().GetMleFrameCounter(), - Mac::Frame::kSecEncMic32, nonce); + Crypto::AesCcm::GenerateNonce(Get().GetExtAddress(), Get().GetMleFrameCounter(), + Mac::Frame::kSecEncMic32, nonce); aesCcm.SetKey(Get().GetCurrentMleKey(), 16); error = aesCcm.Init(16 + 16 + header.GetHeaderLength(), aMessage.GetLength() - (header.GetLength() - 1), @@ -2609,7 +2609,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn const uint8_t * mleKey; uint32_t frameCounter; uint8_t messageTag[4]; - uint8_t nonce[KeyManager::kNonceSize]; + uint8_t nonce[Crypto::AesCcm::kNonceSize]; Mac::ExtAddress macAddr; Crypto::AesCcm aesCcm; uint16_t mleOffset; @@ -2674,7 +2674,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn aMessageInfo.GetPeerAddr().ToExtAddress(macAddr); frameCounter = header.GetFrameCounter(); - KeyManager::GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce); + Crypto::AesCcm::GenerateNonce(macAddr, frameCounter, Mac::Frame::kSecEncMic32, nonce); aesCcm.SetKey(mleKey, 16); SuccessOrExit(error = aesCcm.Init(sizeof(aMessageInfo.GetPeerAddr()) + sizeof(aMessageInfo.GetSockAddr()) + diff --git a/src/lib/spinel/radio_spinel.hpp b/src/lib/spinel/radio_spinel.hpp index 17d0adb3c..387896b94 100644 --- a/src/lib/spinel/radio_spinel.hpp +++ b/src/lib/spinel/radio_spinel.hpp @@ -597,6 +597,28 @@ public: */ void HandleReceivedFrame(void); + /** + * This method sets MAC key and key index to RCP. + * + * @param[in] aKeyIdMode The key ID mode. + * @param[in] aKeyId The key index. + * @param[in] aKeySize The key length. + * @param[in] aPrevKey The pointer to the previous MAC key. + * @param[in] aCurrKey The pointer to the current MAC key. + * @param[in] aNextKey The pointer to the next MAC key. + * + * @retval OT_ERROR_NONE Succeeded. + * @retval OT_ERROR_BUSY Failed due to another operation is on going. + * @retval OT_ERROR_RESPONSE_TIMEOUT Failed due to no response received from the transceiver. + * + */ + otError SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + uint8_t aKeySize, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey); + /** * This method checks whether the spinel interface is radio-only * diff --git a/src/lib/spinel/radio_spinel_impl.hpp b/src/lib/spinel/radio_spinel_impl.hpp index 1034ac1f0..2a8138872 100644 --- a/src/lib/spinel/radio_spinel_impl.hpp +++ b/src/lib/spinel/radio_spinel_impl.hpp @@ -1011,6 +1011,25 @@ exit: return error; } +template +otError RadioSpinel::SetMacKey(uint8_t aKeyIdMode, + uint8_t aKeyId, + uint8_t aKeySize, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) +{ + otError error; + + SuccessOrExit(error = Set(SPINEL_PROP_RCP_MAC_KEY, + SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_DATA_WLEN_S + SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_WLEN_S, + aKeyIdMode, aKeyId, aPrevKey, aKeySize, aCurrKey, aKeySize, aNextKey, aKeySize)); + +exit: + return error; +} + template otError RadioSpinel::GetIeeeEui64(uint8_t *aIeeeEui64) { @@ -1469,14 +1488,17 @@ otError RadioSpinel::Transmit(otRadioFrame &a otPlatRadioTxStarted(mInstance, mTransmitFrame); error = Request(true, SPINEL_CMD_PROP_VALUE_SET, SPINEL_PROP_STREAM_RAW, - SPINEL_DATATYPE_DATA_WLEN_S // Frame data - SPINEL_DATATYPE_UINT8_S // Channel - SPINEL_DATATYPE_UINT8_S // MaxCsmaBackoffs - SPINEL_DATATYPE_UINT8_S // MaxFrameRetries - SPINEL_DATATYPE_BOOL_S, // CsmaCaEnabled + SPINEL_DATATYPE_DATA_WLEN_S // Frame data + SPINEL_DATATYPE_UINT8_S // Channel + SPINEL_DATATYPE_UINT8_S // MaxCsmaBackoffs + SPINEL_DATATYPE_UINT8_S // MaxFrameRetries + SPINEL_DATATYPE_BOOL_S // CsmaCaEnabled + SPINEL_DATATYPE_BOOL_S // IsARetx + SPINEL_DATATYPE_BOOL_S, // SkipAes mTransmitFrame->mPsdu, mTransmitFrame->mLength, mTransmitFrame->mChannel, mTransmitFrame->mInfo.mTxInfo.mMaxCsmaBackoffs, mTransmitFrame->mInfo.mTxInfo.mMaxFrameRetries, - mTransmitFrame->mInfo.mTxInfo.mCsmaCaEnabled); + mTransmitFrame->mInfo.mTxInfo.mCsmaCaEnabled, mTransmitFrame->mInfo.mTxInfo.mIsARetx, + mTransmitFrame->mInfo.mTxInfo.mIsSecurityProcessed); if (error == OT_ERROR_NONE) { diff --git a/src/lib/spinel/spinel.h b/src/lib/spinel/spinel.h index c15968d1d..6b978c60f 100644 --- a/src/lib/spinel/spinel.h +++ b/src/lib/spinel/spinel.h @@ -1137,6 +1137,7 @@ typedef uint32_t spinel_capability_t; * Interface | 0x100 - 0x1FF | Interface (e.g., UART) * PIB | 0x400 - 0x4FF | 802.15.4 PIB * Counter | 0x500 - 0x7FF | Counters (MAC, IP, etc). + * RCP | 0x800 - 0x8FF | RCP specific property * Nest | 0x3BC0 - 0x3BFF | Nest (legacy) * Vendor | 0x3C00 - 0x3FFF | Vendor specific * Debug | 0x4000 - 0x43FF | Debug related @@ -2953,6 +2954,10 @@ enum * (use Thread stack default if not specified) * `b` : Set to true to enable CSMA-CA for this packet, false otherwise. * (default true). + * `b` : Set to true to indicate it is a retransmission packet, false otherwise. + * (default false). + * `b` : Set to true to indicate that SubMac should skip AES processing, false otherwise. + * (default false). * */ SPINEL_PROP_STREAM_RAW = SPINEL_PROP_STREAM__BEGIN + 1, @@ -3931,6 +3936,24 @@ enum SPINEL_PROP_CNTR__END = 0x800, + SPINEL_PROP_RCP__BEGIN = 0x800, + + /// MAC Key + /** Format: `CCddd`. + * + * `C`: MAC key ID mode + * `C`: MAC key ID + * `d`: previous MAC key material data + * `d`: current MAC key material data + * `d`: next MAC key material data + * + * The Spinel property is used to set/get MAC key materials to and from RCP. + * + */ + SPINEL_PROP_RCP_MAC_KEY = SPINEL_PROP_RCP__BEGIN + 0, + + SPINEL_PROP_RCP__END = 0x900, + SPINEL_PROP_NEST__BEGIN = 0x3BC0, SPINEL_PROP_NEST_STREAM_MFG = SPINEL_PROP_NEST__BEGIN + 0, diff --git a/src/ncp/ncp_base_dispatcher.cpp b/src/ncp/ncp_base_dispatcher.cpp index c959b2ab3..0cc987049 100644 --- a/src/ncp/ncp_base_dispatcher.cpp +++ b/src/ncp/ncp_base_dispatcher.cpp @@ -411,6 +411,11 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey) #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM), #endif +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD +#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE + OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_KEY), +#endif +#if OPENTHREAD_MTD || OPENTHREAD_FTD OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER), #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_ENABLE), diff --git a/src/ncp/ncp_base_radio.cpp b/src/ncp/ncp_base_radio.cpp index eefba4146..121fb8249 100644 --- a/src/ncp/ncp_base_radio.cpp +++ b/src/ncp/ncp_base_radio.cpp @@ -357,6 +357,8 @@ otError NcpBase::DecodeStreamRawTxRequest(otRadioFrame &aFrame) const uint8_t *payloadPtr; uint16_t payloadLen; bool csmaEnable; + bool isARetx; + bool isSecurityProcessed; SuccessOrExit(error = mDecoder.ReadDataWithLen(payloadPtr, payloadLen)); VerifyOrExit(payloadLen <= OT_RADIO_FRAME_MAX_SIZE, error = OT_ERROR_PARSE); @@ -370,9 +372,11 @@ otError NcpBase::DecodeStreamRawTxRequest(otRadioFrame &aFrame) SuccessOrExit(error = mDecoder.ReadUint8(aFrame.mChannel)); // Set the default value for all optional parameters. - aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT; - aFrame.mInfo.mTxInfo.mMaxFrameRetries = OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT; - aFrame.mInfo.mTxInfo.mCsmaCaEnabled = true; + aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs = OPENTHREAD_CONFIG_MAC_MAX_CSMA_BACKOFFS_DIRECT; + aFrame.mInfo.mTxInfo.mMaxFrameRetries = OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT; + aFrame.mInfo.mTxInfo.mCsmaCaEnabled = true; + aFrame.mInfo.mTxInfo.mIsARetx = false; + aFrame.mInfo.mTxInfo.mIsSecurityProcessed = false; // All the next parameters are optional. Note that even if the // decoder fails to parse any of optional parameters we still want to @@ -382,7 +386,11 @@ otError NcpBase::DecodeStreamRawTxRequest(otRadioFrame &aFrame) SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxCsmaBackoffs)); SuccessOrExit(mDecoder.ReadUint8(aFrame.mInfo.mTxInfo.mMaxFrameRetries)); SuccessOrExit(mDecoder.ReadBool(csmaEnable)); - aFrame.mInfo.mTxInfo.mCsmaCaEnabled = csmaEnable; + SuccessOrExit(mDecoder.ReadBool(isARetx)); + SuccessOrExit(mDecoder.ReadBool(isSecurityProcessed)); + aFrame.mInfo.mTxInfo.mCsmaCaEnabled = csmaEnable; + aFrame.mInfo.mTxInfo.mIsARetx = isARetx; + aFrame.mInfo.mTxInfo.mIsSecurityProcessed = isSecurityProcessed; exit: return error; @@ -421,6 +429,36 @@ exit: return error; } +template <> otError NcpBase::HandlePropertySet(void) +{ + otError error = OT_ERROR_NONE; + uint8_t keyIdMode; + uint8_t keyId; + uint16_t keySize; + const uint8_t *prevKey; + const uint8_t *currKey; + const uint8_t *nextKey; + + SuccessOrExit(error = mDecoder.ReadUint8(keyIdMode)); + VerifyOrExit(keyIdMode == Mac::Frame::kKeyIdMode1, error = OT_ERROR_INVALID_ARGS); + + SuccessOrExit(error = mDecoder.ReadUint8(keyId)); + + SuccessOrExit(error = mDecoder.ReadDataWithLen(prevKey, keySize)); + VerifyOrExit(keySize == Mac::SubMac::kMacKeySize, error = OT_ERROR_INVALID_ARGS); + + SuccessOrExit(error = mDecoder.ReadDataWithLen(currKey, keySize)); + VerifyOrExit(keySize == Mac::SubMac::kMacKeySize, error = OT_ERROR_INVALID_ARGS); + + SuccessOrExit(error = mDecoder.ReadDataWithLen(nextKey, keySize)); + VerifyOrExit(keySize == Mac::SubMac::kMacKeySize, error = OT_ERROR_INVALID_ARGS); + + error = otLinkRawSetMacKey(mInstance, keyIdMode, keyId, prevKey, currKey, nextKey); + +exit: + return error; +} + } // namespace Ncp } // namespace ot diff --git a/src/posix/platform/radio.cpp b/src/posix/platform/radio.cpp index 52b874015..fa8130d4f 100644 --- a/src/posix/platform/radio.cpp +++ b/src/posix/platform/radio.cpp @@ -474,3 +474,15 @@ otRadioState otPlatRadioGetState(otInstance *aInstance) OT_UNUSED_VARIABLE(aInstance); return sRadioSpinel.GetState(); } + +void otPlatRadioSetMacKey(otInstance * aInstance, + uint8_t aKeyIdMode, + uint8_t aKeyId, + uint8_t aKeySize, + const uint8_t *aPrevKey, + const uint8_t *aCurrKey, + const uint8_t *aNextKey) +{ + SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, aKeySize, aPrevKey, aCurrKey, aNextKey)); + OT_UNUSED_VARIABLE(aInstance); +} diff --git a/tests/toranj/openthread-core-toranj-config.h b/tests/toranj/openthread-core-toranj-config.h index 02ecd3b9f..0f424e6c4 100644 --- a/tests/toranj/openthread-core-toranj-config.h +++ b/tests/toranj/openthread-core-toranj-config.h @@ -424,26 +424,34 @@ #if OPENTHREAD_RADIO /** - * @def OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE * * Define to 1 if you want to enable software ACK timeout logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_ACK_TIMEOUT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE * * Define to 1 if you want to enable software retransmission logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_RETRANSMIT_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_RETRANSMIT_ENABLE 1 /** - * @def OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE * * Define to 1 if you want to enable software CSMA-CA backoff logic. * */ -#define OPENTHREAD_CONFIG_SOFTWARE_CSMA_BACKOFF_ENABLE 1 +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE 1 + +/** + * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE + * + * Define to 1 if you want to enable software transmission security logic. + * + */ +#define OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE 1 #endif // OPENTHREAD_RADIO diff --git a/third_party/mbedtls/Makefile.am b/third_party/mbedtls/Makefile.am index 0a84a1507..087e01dbf 100644 --- a/third_party/mbedtls/Makefile.am +++ b/third_party/mbedtls/Makefile.am @@ -21,7 +21,10 @@ EXTRA_DIST = \ repo/include \ $(NULL) -lib_LIBRARIES = libmbedcrypto.a +lib_LIBRARIES = \ + libmbedcrypto.a \ + libmbedcrypto_radio.a \ + $(NULL) # Do not enable -Wconversion for mbedtls override CFLAGS := $(filter-out -Wconversion,$(CFLAGS)) @@ -86,6 +89,18 @@ libmbedcrypto_a_SOURCES = \ repo/library/x509_crt.c \ $(NULL) +libmbedcrypto_radio_a_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/core \ + -I$(MBEDTLS_SRCDIR)/include \ + $(MBEDTLS_CPPFLAGS) \ + $(NULL) + +libmbedcrypto_radio_a_SOURCES = \ + repo/library/aes.c \ + repo/library/platform_util.c \ + $(NULL) + if OPENTHREAD_BUILD_COVERAGE Dash = - CLEANFILES = $(shell find $(top_builddir)/third_party/mbedtls $(Dash)name "*.gcda" $(Dash)o $(Dash)name "*.gcno")