Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openthread updates #1445

Merged
merged 8 commits into from
Jan 18, 2024
7 changes: 7 additions & 0 deletions dts/bindings/options/openthread,config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ description: |
compatible = "openthread,config";
diag-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>,
<&gpio1 0 GPIO_ACTIVE_LOW>;
bootloader-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
};
};

Expand All @@ -21,3 +22,9 @@ properties:
description: |
This enables access to diagnostic GPIO pins. Each field consists of
GPIO pin's configuration: controller's phandle, pin number and configuration flags.

bootloader-gpios:
type: phandle-array
description: |
This enables resetting to bootloader by triggering given GPIO pin. Property represents
chosen GPIO pin's configuration: controller's phandle, pin number and configuration flags.
567 changes: 92 additions & 475 deletions modules/openthread/CMakeLists.txt

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions modules/openthread/Kconfig.features
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ config OPENTHREAD_THREAD_VERSION_1_3
bool "Version 1.3"
config OPENTHREAD_THREAD_VERSION_1_3_1
bool "Version 1.3.1"
endchoice
endchoice # OPENTHREAD_STACK_VERSION

config OPENTHREAD_THREAD_VERSION
string
Expand Down Expand Up @@ -249,6 +249,31 @@ config OPENTHREAD_OTNS
config OPENTHREAD_PING_SENDER
bool "Ping sender support"

config OPENTHREAD_PLATFORM_KEY_REF
Damian-Nordic marked this conversation as resolved.
Show resolved Hide resolved
bool "Platform cryptographic key reference support"
help
Enable usage of cryptographic key references instead of literal keys.
This requires a crypto backend library that supports key references.

choice OPENTHREAD_PLATFORM_BOOTLOADER_MODE_CHOICE
prompt "Platform bootloader mode configuration"
optional

config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION
bool "Bootloader mode support with boot mode retention API"
depends on RETENTION_BOOT_MODE && REBOOT
select OPENTHREAD_PLATFORM_BOOTLOADER_MODE

config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO
bool "Bootloader mode support with GPIO pin trigger"
select OPENTHREAD_PLATFORM_BOOTLOADER_MODE
endchoice # OPENTHREAD_PLATFORM_BOOTLOADER_MODE

config OPENTHREAD_PLATFORM_BOOTLOADER_MODE
bool
help
Platform bootloader mode support

config OPENTHREAD_PLATFORM_NETIF
bool "Platform netif support"

Expand All @@ -270,7 +295,7 @@ config OPENTHREAD_POWER_SUPPLY_EXTERNAL_STABLE

config OPENTHREAD_POWER_SUPPLY_EXTERNAL_UNSTABLE
bool "OT_POWER_SUPPLY_EXTERNAL_UNSTABLE"
endchoice
endchoice # OPENTHREAD_POWER_SUPPLY_CHOICE

config OPENTHREAD_POWER_SUPPLY
string
Expand Down
1 change: 1 addition & 0 deletions modules/openthread/Kconfig.thread
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ config OPENTHREAD_DEFAULT_TX_POWER

config OPENTHREAD_BLE_TCAT_THREAD_STACK_SIZE
int "Openthread default TCAT stack size"
default 5120 if OPENTHREAD_CRYPTO_PSA
default 4200
help
Openthread default TCAT stack size.
Expand Down
83 changes: 19 additions & 64 deletions modules/openthread/platform/crypto_psa.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ static psa_key_type_t toPsaKeyType(otCryptoKeyType aType)
return PSA_KEY_TYPE_AES;
case OT_CRYPTO_KEY_TYPE_HMAC:
return PSA_KEY_TYPE_HMAC;
case OT_CRYPTO_KEY_TYPE_ECDSA:
return PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
default:
return PSA_KEY_TYPE_NONE;
}
Expand All @@ -53,6 +55,8 @@ static psa_algorithm_t toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm)
return PSA_ALG_ECB_NO_PADDING;
case OT_CRYPTO_KEY_ALG_HMAC_SHA_256:
return PSA_ALG_HMAC(PSA_ALG_SHA_256);
case OT_CRYPTO_KEY_ALG_ECDSA:
return PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256);
default:
/*
* There is currently no constant like PSA_ALG_NONE, but 0 is used
Expand Down Expand Up @@ -82,16 +86,21 @@ static psa_key_usage_t toPsaKeyUsage(int aUsage)
usage |= PSA_KEY_USAGE_SIGN_HASH;
}

if (aUsage & OT_CRYPTO_KEY_USAGE_VERIFY_HASH) {
usage |= PSA_KEY_USAGE_VERIFY_HASH;
}

return usage;
}

static bool checkKeyUsage(int aUsage)
{
/* Check if only supported flags have been passed */
int supported_flags = OT_CRYPTO_KEY_USAGE_EXPORT |
OT_CRYPTO_KEY_USAGE_ENCRYPT |
OT_CRYPTO_KEY_USAGE_DECRYPT |
OT_CRYPTO_KEY_USAGE_SIGN_HASH;
OT_CRYPTO_KEY_USAGE_ENCRYPT |
OT_CRYPTO_KEY_USAGE_DECRYPT |
OT_CRYPTO_KEY_USAGE_SIGN_HASH |
OT_CRYPTO_KEY_USAGE_VERIFY_HASH;

return (aUsage & ~supported_flags) == 0;
}
Expand All @@ -102,31 +111,6 @@ static bool checkContext(otCryptoContext *aContext, size_t aMinSize)
return aContext != NULL && aContext->mContext != NULL && aContext->mContextSize >= aMinSize;
}

static void ensureKeyIsLoaded(otCryptoKeyRef aKeyRef)
{
/*
* The workaround below will no longer be need after updating TF-M version used in Zephyr
* to 1.5.0 (see upstream commit 42e77b561fcfe19819ff1e63cb7c0b672ee8ba41).
* In the recent versions of TF-M the concept of key handles and psa_open_key()/
* psa_close_key() APIs have been being deprecated, but the version currently used in Zephyr
* is in the middle of that transition. Consequently, psa_destroy_key() and lots of other
* functions will fail when a key ID that they take as a parameter is not loaded from the
* persistent storage. That may occur when a given persistent key is created via
* psa_generate_key() or psa_import_key(), and then the device reboots.
*
* Use psa_open_key() when the key has not been loaded yet to work around the issue.
*/
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = psa_get_key_attributes(aKeyRef, &attributes);
psa_key_id_t key_handle;

if (status == PSA_ERROR_INVALID_HANDLE) {
psa_open_key(aKeyRef, &key_handle);
}

psa_reset_key_attributes(&attributes);
}

void otPlatCryptoInit(void)
{
psa_crypto_init();
Expand Down Expand Up @@ -186,15 +170,11 @@ otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef,
return OT_ERROR_INVALID_ARGS;
}

ensureKeyIsLoaded(aKeyRef);

return psaToOtError(psa_export_key(aKeyRef, aBuffer, aBufferLen, aKeyLen));
}

otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef)
{
ensureKeyIsLoaded(aKeyRef);

return psaToOtError(psa_destroy_key(aKeyRef));
}

Expand All @@ -203,7 +183,6 @@ bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;

ensureKeyIsLoaded(aKeyRef);
status = psa_get_key_attributes(aKeyRef, &attributes);
psa_reset_key_attributes(&attributes);

Expand Down Expand Up @@ -246,7 +225,6 @@ otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey
return OT_ERROR_INVALID_ARGS;
}

ensureKeyIsLoaded(aKey->mKeyRef);
operation = aContext->mContext;
status = psa_mac_sign_setup(operation, aKey->mKeyRef, PSA_ALG_HMAC(PSA_ALG_SHA_256));

Expand Down Expand Up @@ -314,45 +292,22 @@ otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput,
{
const size_t block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES);
psa_status_t status = PSA_SUCCESS;
psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT;
psa_key_id_t *key_ref;
size_t cipher_length;

if (aInput == NULL || aOutput == NULL || !checkContext(aContext, sizeof(psa_key_id_t))) {
return OT_ERROR_INVALID_ARGS;
}

/*
* The code below can be simplified after updating TF-M version used in Zephyr to 1.5.0
* (see upstream commit: 045ec4abfc73152a0116684ba9127d0a97cc8d34), using
* psa_cipher_encrypt() function which will replace the setup-update-finish sequence below.
*/
key_ref = aContext->mContext;
ensureKeyIsLoaded(*key_ref);
status = psa_cipher_encrypt_setup(&operation, *key_ref, PSA_ALG_ECB_NO_PADDING);

if (status != PSA_SUCCESS) {
goto out;
}

status = psa_cipher_update(&operation,
aInput,
block_size,
aOutput,
block_size,
&cipher_length);
status = psa_cipher_encrypt(*key_ref,
PSA_ALG_ECB_NO_PADDING,
aInput,
block_size,
aOutput,
block_size,
&cipher_length);

if (status != PSA_SUCCESS) {
goto out;
}

status = psa_cipher_finish(&operation,
aOutput + cipher_length,
block_size - cipher_length,
&cipher_length);

out:
psa_cipher_abort(&operation);
return psaToOtError(status);
}

Expand Down
73 changes: 72 additions & 1 deletion modules/openthread/platform/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
#include <openthread/instance.h>
#include <openthread/platform/misc.h>

#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION)

#include <zephyr/retention/bootmode.h>

#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO)

BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(openthread_config),
"`openthread,config` compatible node not found");
BUILD_ASSERT(DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), bootloader_gpios),
"`bootloader-gpios` property missing from `openthread,config` compatible node");

#include <zephyr/drivers/gpio.h>

static const struct gpio_dt_spec bootloader_gpio =
GPIO_DT_SPEC_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config),
bootloader_gpios);
#endif

#include "platform-zephyr.h"

void otPlatReset(otInstance *aInstance)
Expand All @@ -19,6 +37,54 @@ void otPlatReset(otInstance *aInstance)
sys_reboot(SYS_REBOOT_WARM);
}

#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE)
otError otPlatResetToBootloader(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);

#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION)
if (bootmode_set(BOOT_MODE_TYPE_BOOTLOADER)) {
return OT_ERROR_NOT_CAPABLE;
}
sys_reboot(SYS_REBOOT_WARM);

#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO)
/*
* To enable resetting to bootloader by triggering gpio pin,
* select `CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO=y`,
* and in Devicetree create `openthread` node in `/options/` path with
* `compatible = "openthread,config"` property and `bootloader-gpios` property,
* which should represent GPIO pin's configuration,
* containing controller phandle, pin number and pin flags. e.g:
*
* options {
* openthread {
* compatible = "openthread,config";
* bootloader-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
* };
* };
*
* Note: in below implementation, chosen GPIO pin is configured as output
* and initialized to active state (logical value ‘1’).
* Configuring pin flags in `bootloader-gpios` allows to choose
* if pin should be active in high or in low state.
*/

if (!gpio_is_ready_dt(&bootloader_gpio)) {
return OT_ERROR_NOT_CAPABLE;
}
gpio_pin_configure_dt(&bootloader_gpio, GPIO_OUTPUT_ACTIVE);

#endif

/*
* Return OT_ERROR_NOT_CAPABLE if resetting has been unsuccessful (invalid configuration or
* triggering reset had no effect)
*/
return OT_ERROR_NOT_CAPABLE;
}
#endif /* defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) */

otPlatResetReason otPlatGetResetReason(otInstance *aInstance)
{
ARG_UNUSED(aInstance);
Expand All @@ -33,5 +99,10 @@ void otPlatWakeHost(void)

void otPlatAssertFail(const char *aFilename, int aLineNumber)
{
__ASSERT(false, "OpenThread ASSERT @ %s:%d", aFilename, aLineNumber);
/*
* The code below is used instead of __ASSERT(false) to print the actual assert
* location instead of __FILE__:__LINE__, which would point to this function.
*/
__ASSERT_PRINT("OpenThread ASSERT @ %s:%d\n", aFilename, aLineNumber);
__ASSERT_POST_ACTION();
}
21 changes: 0 additions & 21 deletions modules/openthread/platform/openthread-core-zephyr-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,16 +396,6 @@
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
#endif

/**
* @def OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
*
* Set to 1 if you want to enable key reference usage support.
*
*/
#ifdef CONFIG_OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 1
#endif

/**
* @def OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE
*
Expand Down Expand Up @@ -448,17 +438,6 @@
#define OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE 0
#endif

/**
* @def OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
*
* In Zephyr, power calibration is handled by Radio Driver, so it can't be handled on OT level.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
#define OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE 0
#endif


/**
* @def OPENTHREAD_CONFIG_RADIO_STATS
*
Expand Down
10 changes: 2 additions & 8 deletions subsys/net/l2/openthread/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -324,21 +324,15 @@ config OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE
config OPENTHREAD_CRYPTO_PSA
bool "ARM PSA crypto API"
depends on MBEDTLS_PSA_CRYPTO_C || BUILD_WITH_TFM
select OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE
select OPENTHREAD_PLATFORM_KEY_REF
select OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE
help
Enable crypto backend library implementation based on ARM PSA crypto
API instead of the default, using mbedTLS.

config OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE
bool "Cryptographic key reference support"
help
Enable usage of cryptographic key references instead of literal keys
This requires a crypto backend library that supports key references.

config OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE
bool "Make MAC keys exportable"
depends on OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE
depends on OPENTHREAD_PLATFORM_KEY_REF
help
Enable the creation of exportable MAC keys in the OpenThread Key Manager.

Expand Down