[crypto] adding ARM PSA (Platform Security Architecture) support (#6862)

- New format for MAC keys, as a union between literal key and keyrefs.
- Modified key_manager to handle both literal keys or keyrefs.
- Modified MAC and sub_mac modules to handle both Literal Keys or keyrefs.
- Updated Crypto Modules to use abstracted APIs.
- New CLIs to handle networkkey and pskc references.
This commit is contained in:
hemanth-silabs
2021-09-08 14:47:46 -07:00
committed by GitHub
parent 88c2f0f7ed
commit cf452fbf7c
71 changed files with 2687 additions and 402 deletions
+2
View File
@@ -237,12 +237,14 @@ LOCAL_SRC_FILES := \
src/core/common/uptime.cpp \
src/core/crypto/aes_ccm.cpp \
src/core/crypto/aes_ecb.cpp \
src/core/crypto/crypto_platform.cpp \
src/core/crypto/ecdsa.cpp \
src/core/crypto/hkdf_sha256.cpp \
src/core/crypto/hmac_sha256.cpp \
src/core/crypto/mbedtls.cpp \
src/core/crypto/pbkdf2_cmac.cpp \
src/core/crypto/sha256.cpp \
src/core/crypto/storage.cpp \
src/core/diags/factory_diags.cpp \
src/core/mac/channel_mask.cpp \
src/core/mac/data_poll_handler.cpp \
@@ -59,6 +59,7 @@ set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
add_library(openthread-simulation
alarm.c
crypto.c
diag.c
entropy.c
flash.c
@@ -41,6 +41,7 @@ libopenthread_simulation_a_CPPFLAGS = \
PLATFORM_SOURCES = \
alarm.c \
crypto.c \
diag.c \
entropy.c \
flash.c \
+84
View File
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "platform-simulation.h"
#include <stdio.h>
#include <stdlib.h>
#include <openthread/config.h>
#include <openthread/platform/crypto.h>
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
// crypto key storage stubs
otError otPlatCryptoImportKey(otCryptoKeyRef * aKeyRef,
otCryptoKeyType aKeyType,
otCryptoKeyAlgorithm aKeyAlgorithm,
int aKeyUsage,
otCryptoKeyStorage aKeyPersistence,
const uint8_t * aKey,
size_t aKeyLen)
{
OT_UNUSED_VARIABLE(aKeyRef);
OT_UNUSED_VARIABLE(aKeyType);
OT_UNUSED_VARIABLE(aKeyAlgorithm);
OT_UNUSED_VARIABLE(aKeyUsage);
OT_UNUSED_VARIABLE(aKeyPersistence);
OT_UNUSED_VARIABLE(aKey);
OT_UNUSED_VARIABLE(aKeyLen);
return OT_ERROR_NOT_IMPLEMENTED;
}
otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen)
{
OT_UNUSED_VARIABLE(aKeyRef);
OT_UNUSED_VARIABLE(aBuffer);
OT_UNUSED_VARIABLE(aBufferLen);
OT_UNUSED_VARIABLE(aKeyLen);
return OT_ERROR_NOT_IMPLEMENTED;
}
otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef)
{
OT_UNUSED_VARIABLE(aKeyRef);
return OT_ERROR_NOT_IMPLEMENTED;
}
bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
{
OT_UNUSED_VARIABLE(aKeyRef);
return false;
}
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
+20 -17
View File
@@ -149,11 +149,12 @@ otRadioCaps gRadioCaps =
OT_RADIO_CAPS_NONE;
#endif
static uint32_t sMacFrameCounter;
static uint8_t sKeyId;
static struct otMacKey sPrevKey;
static struct otMacKey sCurrKey;
static struct otMacKey sNextKey;
static uint32_t sMacFrameCounter;
static uint8_t sKeyId;
static otMacKeyMaterial sPrevKey;
static otMacKeyMaterial sCurrKey;
static otMacKeyMaterial sNextKey;
static otRadioKeyType sKeyType;
static void ReverseExtAddress(otExtAddress *aReversed, const otExtAddress *aOrigin)
{
@@ -605,8 +606,8 @@ static otError radioProcessTransmitSecurity(otRadioFrame *aFrame)
{
otError error = OT_ERROR_NONE;
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
struct otMacKey *key = NULL;
uint8_t keyId;
otMacKeyMaterial *key = NULL;
uint8_t keyId;
otEXPECT(otMacFrameIsSecurityEnabled(aFrame) && otMacFrameIsKeyIdMode1(aFrame) &&
!aFrame->mInfo.mTxInfo.mIsSecurityProcessed);
@@ -1195,22 +1196,24 @@ uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
}
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKey *aPrevKey,
const otMacKey *aCurrKey,
const otMacKey *aNextKey)
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey,
otRadioKeyType aKeyType)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aKeyIdMode);
otEXPECT(aPrevKey != NULL && aCurrKey != NULL && aNextKey != NULL);
sKeyId = aKeyId;
memcpy(sPrevKey.m8, aPrevKey->m8, OT_MAC_KEY_SIZE);
memcpy(sCurrKey.m8, aCurrKey->m8, OT_MAC_KEY_SIZE);
memcpy(sNextKey.m8, aNextKey->m8, OT_MAC_KEY_SIZE);
sKeyId = aKeyId;
sKeyType = aKeyType;
memcpy(&sPrevKey, aPrevKey, sizeof(otMacKeyMaterial));
memcpy(&sCurrKey, aCurrKey, sizeof(otMacKeyMaterial));
memcpy(&sNextKey, aNextKey, sizeof(otMacKeyMaterial));
exit:
return;
+1
View File
@@ -96,6 +96,7 @@ dist_openthread_HEADERS = $(openthread_headers)
ot_platform_headers = \
openthread/platform/alarm-micro.h \
openthread/platform/alarm-milli.h \
openthread/platform/crypto.h \
openthread/platform/debug_uart.h \
openthread/platform/diag.h \
openthread/platform/entropy.h \
+1
View File
@@ -99,6 +99,7 @@ source_set("openthread") {
"ping_sender.h",
"platform/alarm-micro.h",
"platform/alarm-milli.h",
"platform/crypto.h",
"platform/debug_uart.h",
"platform/diag.h",
"platform/entropy.h",
+13 -19
View File
@@ -39,6 +39,7 @@
#include <stdint.h>
#include <openthread/error.h>
#include <openthread/platform/crypto.h>
#ifdef __cplusplus
extern "C" {
@@ -78,23 +79,17 @@ typedef struct otCryptoSha256Hash otCryptoSha256Hash;
* This function performs HMAC computation.
*
* @param[in] aKey A pointer to the key.
* @param[in] aKeyLength The key length in bytes.
* @param[in] aBuf A pointer to the input buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
* @param[out] aHash A pointer to a `otCryptoSha256Hash` structure to output the hash value.
*
*/
void otCryptoHmacSha256(const uint8_t * aKey,
uint16_t aKeyLength,
const uint8_t * aBuf,
uint16_t aBufLength,
otCryptoSha256Hash *aHash);
void otCryptoHmacSha256(const otCryptoKey *aKey, const uint8_t *aBuf, uint16_t aBufLength, otCryptoSha256Hash *aHash);
/**
* This method performs AES CCM computation.
*
* @param[in] aKey A pointer to the key.
* @param[in] aKeyLength Length of the key in bytes.
* @param[in] aTagLength Length of tag in bytes.
* @param[in] aNonce A pointer to the nonce.
* @param[in] aNonceLength Length of nonce in bytes.
@@ -110,18 +105,17 @@ void otCryptoHmacSha256(const uint8_t * aKey,
* @param[out] aTag A pointer to the tag.
*
*/
void otCryptoAesCcm(const uint8_t *aKey,
uint16_t aKeyLength,
uint8_t aTagLength,
const void * aNonce,
uint8_t aNonceLength,
const void * aHeader,
uint32_t aHeaderLength,
void * aPlainText,
void * aCipherText,
uint32_t aLength,
bool aEncrypt,
void * aTag);
void otCryptoAesCcm(const otCryptoKey *aKey,
uint8_t aTagLength,
const void * aNonce,
uint8_t aNonceLength,
const void * aHeader,
uint32_t aHeaderLength,
void * aPlainText,
void * aCipherText,
uint32_t aLength,
bool aEncrypt,
void * aTag);
/**
* This method creates ECDSA sign.
+13
View File
@@ -37,6 +37,7 @@
#include <openthread/instance.h>
#include <openthread/ip6.h>
#include <openthread/platform/crypto.h>
#include <openthread/platform/radio.h>
#ifdef __cplusplus
@@ -70,6 +71,12 @@ struct otNetworkKey
*/
typedef struct otNetworkKey otNetworkKey;
/**
* This datatype represents KeyRef to NetworkKey.
*
*/
typedef otCryptoKeyRef otNetworkKeyRef; ///< Reference to Key
#define OT_NETWORK_NAME_MAX_SIZE 16 ///< Maximum size of the Thread Network Name field (bytes)
/**
@@ -127,6 +134,12 @@ struct otPskc
*/
typedef struct otPskc otPskc;
/**
* This datatype represents KeyRef to PSKc.
*
*/
typedef otCryptoKeyRef otPskcRef; ///< Reference to Key
/**
* This structure represent Security Policy.
*
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (159)
#define OPENTHREAD_API_VERSION (160)
/**
* @addtogroup api-instance
+489
View File
@@ -0,0 +1,489 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* @brief
* This file includes the platform abstraction for Crypto operations.
*/
#ifndef OPENTHREAD_PLATFORM_CRYPTO_H_
#define OPENTHREAD_PLATFORM_CRYPTO_H_
#include <stdint.h>
#include <stdlib.h>
#include <openthread/error.h>
#ifdef OT_PLAT_CRYPTO_ATTRIBUTES_TYPE_HEADER
#include OT_PLAT_CRYPTO_ATTRIBUTES_TYPE_HEADER
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup plat-crypto
*
* @brief
* This module includes the platform abstraction for Crypto.
*
* @{
*
*/
/**
* This enumeration defines the key types.
*
*/
typedef enum
{
OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
} otCryptoKeyType;
/**
* This enumeration defines the key algorithms.
*
*/
typedef enum
{
OT_CRYPTO_KEY_ALG_VENDOR, ///< Key Algorithm: Vendor Defined.
OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
} otCryptoKeyAlgorithm;
/**
* This enumeration defines the key usage flags.
*
*/
enum
{
OT_CRYPTO_KEY_USAGE_NONE = 0, ///< Key Usage: Key Usage is empty.
OT_CRYPTO_KEY_USAGE_EXPORT = 1 << 0, ///< Key Usage: Key can be exported.
OT_CRYPTO_KEY_USAGE_ENCRYPT = 1 << 1, ///< Key Usage: Encryption (vendor defined).
OT_CRYPTO_KEY_USAGE_DECRYPT = 1 << 2, ///< Key Usage: AES ECB.
OT_CRYPTO_KEY_USAGE_SIGN_HASH = 1 << 3, ///< Key Usage: HMAC SHA-256.
};
/**
* This enumeration defines the key storage types.
*
*/
typedef enum
{
OT_CRYPTO_KEY_STORAGE_VOLATILE, ///< Key Persistence: Key is volatile.
OT_CRYPTO_KEY_STORAGE_PERSISTENT, ///< Key Persistence: Key is persistent.
} otCryptoKeyStorage;
/**
* This datatype represents the key reference.
*
*/
typedef uint32_t otCryptoKeyRef;
/**
* @struct otCryptoKey
*
* This structure represents the Key Material required for Crypto operations.
*
*/
typedef struct otCryptoKey
{
const uint8_t *mKey; ///< Pointer to the buffer containing key. NULL indicates to use `mKeyRef`.
uint16_t mKeyLength; ///< The key length in bytes (applicable when `mKey` is not NULL).
uint32_t mKeyRef; ///< The PSA key ref (requires `mKey` to be NULL).
} otCryptoKey;
/**
* Initialize the Crypto module.
*
* @retval OT_ERROR_NONE Successfully initialized Crypto module.
* @retval OT_ERROR_FAILED Failed to initialize Crypto module.
*
*/
otError otPlatCryptoInit(void);
/**
* Import a key into PSA ITS.
*
* @param[inout] aKeyRef Pointer to the key ref to be used for crypto operations.
* @param[in] aKeyType Key Type encoding for the key.
* @param[in] aKeyAlgorithm Key algorithm encoding for the key.
* @param[in] aKeyUsage Key Usage encoding for the key (combinations of `OT_CRYPTO_KEY_USAGE_*`).
* @param[in] aKeyPersistence Key Persistence for this key
* @param[in] aKey Actual key to be imported.
* @param[in] aKeyLen Length of the key to be imported.
*
* @retval OT_ERROR_NONE Successfully imported the key.
* @retval OT_ERROR_FAILED Failed to import the key.
* @retval OT_ERROR_INVALID_ARGS @p aKey was set to NULL.
*
* @note If OT_CRYPTO_KEY_STORAGE_PERSISTENT is passed for aKeyPersistence then @p aKeyRef is input and platform
* should use the given aKeyRef and MUST not change it.
*
* If OT_CRYPTO_KEY_STORAGE_VOLATILE is passed for aKeyPersistence then @p aKeyRef is output, the initial
* value does not matter and platform API MUST update it to return the new key ref.
*
* This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
otError otPlatCryptoImportKey(otCryptoKeyRef * aKeyRef,
otCryptoKeyType aKeyType,
otCryptoKeyAlgorithm aKeyAlgorithm,
int aKeyUsage,
otCryptoKeyStorage aKeyPersistence,
const uint8_t * aKey,
size_t aKeyLen);
/**
* Export a key stored in PSA ITS.
*
* @param[in] aKeyRef The key ref to be used for crypto operations.
* @param[out] aBuffer Pointer to the buffer where key needs to be exported.
* @param[in] aBufferLen Length of the buffer passed to store the exported key.
* @param[out] aKeyLen Pointer to return the length of the exported key.
*
* @retval OT_ERROR_NONE Successfully exported @p aKeyRef.
* @retval OT_ERROR_FAILED Failed to export @p aKeyRef.
* @retval OT_ERROR_INVALID_ARGS @p aBuffer was NULL
*
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen);
/**
* Destroy a key stored in PSA ITS.
*
* @param[in] aKeyRef The key ref to be destroyed
*
* @retval OT_ERROR_NONE Successfully destroyed the key.
* @retval OT_ERROR_FAILED Failed to destroy the key.
*
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef);
/**
* Check if the key ref passed has an associated key in PSA ITS.
*
* @param[in] aKeyRef The Key Ref to check.
*
* @retval TRUE There is an associated key with @p aKeyRef.
* @retval FALSE There is no associated key with @p aKeyRef.
*
* @note This API is only used by OT core when `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled.
*
*/
bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef);
/**
* Initialize the HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aContextSize Context size HMAC operation.
*
* @retval OT_ERROR_NONE Successfully initialized HMAC operation.
* @retval OT_ERROR_FAILED Failed to initialize HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_mac_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_md_context_t will be provided.
*
*/
otError otPlatCryptoHmacSha256Init(void *aContext, size_t aContextSize);
/**
* Uninitialize the HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aContextSize Context size HMAC operation.
*
*
* @retval OT_ERROR_NONE Successfully uninitialized HMAC operation.
* @retval OT_ERROR_FAILED Failed to uninitialized HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_mac_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_md_context_t will be provided.
*
*/
otError otPlatCryptoHmacSha256Deinit(void *aContext, size_t aContextSize);
/**
* Start HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aContextSize Context size HMAC operation.
* @param[in] aKey Key material to be used for for HMAC operation.
*
* @retval OT_ERROR_NONE Successfully started HMAC operation.
* @retval OT_ERROR_FAILED Failed to start HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey was NULL
*
* @note In case PSA is supported pointer to psa_mac_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_md_context_t will be provided.
*
*/
otError otPlatCryptoHmacSha256Start(void *aContext, size_t aContextSize, const otCryptoKey *aKey);
/**
* Update the HMAC operation with new input.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aContextSize Context size HMAC operation.
* @param[in] aBuf A pointer to the input buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
*
* @retval OT_ERROR_NONE Successfully updated HMAC with new input operation.
* @retval OT_ERROR_FAILED Failed to update HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL
*
* @note In case PSA is supported pointer to psa_mac_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_md_context_t will be provided.
*
*/
otError otPlatCryptoHmacSha256Update(void *aContext, size_t aContextSize, const void *aBuf, uint16_t aBufLength);
/**
* Complete the HMAC operation.
*
* @param[in] aContext Context for HMAC operation.
* @param[in] aContextSize Context size HMAC operation.
* @param[out] aBuf A pointer to the output buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
*
* @retval OT_ERROR_NONE Successfully completed HMAC operation.
* @retval OT_ERROR_FAILED Failed to complete HMAC operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL
*
* @note In case PSA is supported pointer to psa_mac_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_md_context_t will be provided.
*
*/
otError otPlatCryptoHmacSha256Finish(void *aContext, size_t aContextSize, uint8_t *aBuf, size_t aBufLength);
/**
* Initialise the AES operation.
*
* @param[in] aContext Context for AES operation.
* @param[in] aContextSize Context size AES operation.
*
* @retval OT_ERROR_NONE Successfully Initialised AES operation.
* @retval OT_ERROR_FAILED Failed to Initialise AES operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_key_id will be passed as input.
* In case of mbedTLS, pointer to mbedtls_aes_context_t will be provided.
*
*/
otError otPlatCryptoAesInit(void *aContext, size_t aContextSize);
/**
* Set the key for AES operation.
*
* @param[in] aContext Context for AES operation.
* @param[in] aContextSize Context size AES operation.
* @param[out] aKey Key to use for AES operation.
*
* @retval OT_ERROR_NONE Successfully set the key for AES operation.
* @retval OT_ERROR_FAILED Failed to set the key for AES operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey was NULL
*
* @note In case PSA is supported pointer to psa_key_id will be passed as input.
* In case of mbedTLS, pointer to mbedtls_aes_context_t will be provided.
*
*/
otError otPlatCryptoAesSetKey(void *aContext, size_t aContextSize, const otCryptoKey *aKey);
/**
* Encrypt the given data.
*
* @param[in] aContext Context for AES operation.
* @param[in] aContextSize Context size AES operation.
* @param[in] aInput Pointer to the input buffer.
* @param[in] aOutput Pointer to the output buffer.
*
* @retval OT_ERROR_NONE Successfully encrypted @p aInput.
* @retval OT_ERROR_FAILED Failed to encrypt @p aInput.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aKey or @p aOutput were NULL
*
* @note In case PSA is supported pointer to psa_key_id will be passed as input.
* In case of mbedTLS, pointer to mbedtls_aes_context_t will be provided.
*
*/
otError otPlatCryptoAesEncrypt(void *aContext, size_t aContextSize, const uint8_t *aInput, uint8_t *aOutput);
/**
* Free the AES context.
*
* @param[in] aContext Context for AES operation.
* @param[in] aContextSize Context size AES operation.
*
* @retval OT_ERROR_NONE Successfully freed AES context.
* @retval OT_ERROR_FAILED Failed to free AES context.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_key_id will be passed as input.
* In case of mbedTLS, pointer to mbedtls_aes_context_t will be provided.
*
*/
otError otPlatCryptoAesFree(void *aContext, size_t aContextSize);
/**
* Perform HKDF Expand step.
*
* @param[in] aContext Operation context for HKDF operation.
* @param[in] aContextSize Context size HKDF operation.
* @param[in] aInfo Pointer to the Info sequence.
* @param[in] aInfoLength Length of the Info sequence.
* @param[out] aOutputKey Pointer to the output Key.
* @param[in] aOutputKeyLength Size of the output key buffer.
*
* @retval OT_ERROR_NONE HKDF Expand was successful.
* @retval OT_ERROR_FAILED HKDF Expand failed.
*
*/
otError otPlatCryptoHkdfExpand(void * aContext,
size_t aContextSize,
const uint8_t *aInfo,
uint16_t aInfoLength,
uint8_t * aOutputKey,
uint16_t aOutputKeyLength);
/**
* Perform HKDF Extract step.
*
* @param[in] aContext Operation context for HKDF operation.
* @param[in] aContextSize Context size HKDF operation.
* @param[in] aSalt Pointer to the Salt for HKDF.
* @param[in] aInfoLength length of Salt.
* @param[in] aInputKey Pointer to the input key.
*
* @retval OT_ERROR_NONE HKDF Extract was successful.
* @retval OT_ERROR_FAILED HKDF Extract failed.
*
*/
otError otPlatCryptoHkdfExtract(void * aContext,
size_t aContextSize,
const uint8_t * aSalt,
uint16_t aSaltLength,
const otCryptoKey *aInputKey);
/**
* Initialise the SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aContextSize Context size SHA-256 operation.
*
* @retval OT_ERROR_NONE Successfully initialised SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to initialise SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_hash_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_sha256_context will be provided.
*/
otError otPlatCryptoSha256Init(void *aContext, size_t aContextSize);
/**
* UnInitialise the SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aContextSize Context size SHA-256 operation.
*
* @retval OT_ERROR_NONE Successfully un-initialised SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to un-initialised SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_hash_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_sha256_context will be provided.
*/
otError otPlatCryptoSha256Deinit(void *aContext, size_t aContextSize);
/**
* Start SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aContextSize Context size SHA-256 operation.
*
* @retval OT_ERROR_NONE Successfully started SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to start SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext was NULL
*
* @note In case PSA is supported pointer to psa_hash_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_sha256_context will be provided.
*/
otError otPlatCryptoSha256Start(void *aContext, size_t aContextSize);
/**
* Update SHA-256 operation with new input.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aContextSize Context size SHA-256 operation.
* @param[in] aBuf A pointer to the input buffer.
* @param[in] aBufLength The length of @p aBuf in bytes.
*
* @retval OT_ERROR_NONE Successfully updated SHA-256 with new input operation.
* @retval OT_ERROR_FAILED Failed to update SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aBuf was NULL
*
* @note In case PSA is supported pointer to psa_hash_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_sha256_context will be provided.
*/
otError otPlatCryptoSha256Update(void *aContext, size_t aContextSize, const void *aBuf, uint16_t aBufLength);
/**
* Finish SHA-256 operation.
*
* @param[in] aContext Context for SHA-256 operation.
* @param[in] aContextSize Context size SHA-256 operation.
* @param[in] aHash A pointer to the output buffer, where hash needs to be stored.
* @param[in] aHashSize The length of @p aHash in bytes.
*
* @retval OT_ERROR_NONE Successfully completed the SHA-256 operation.
* @retval OT_ERROR_FAILED Failed to complete SHA-256 operation.
* @retval OT_ERROR_INVALID_ARGS @p aContext or @p aHash was NULL
*
* @note In case PSA is supported pointer to psa_hash_operation_t will be passed as input.
* In case of mbedTLS, pointer to mbedtls_sha256_context will be provided.
*/
otError otPlatCryptoSha256Finish(void *aContext, size_t aContextSize, uint8_t *aHash, uint16_t aHashSize);
/**
* @}
*
*/
#ifdef __cplusplus
} // end of extern "C"
#endif
#endif // OPENTHREAD_PLATFORM_CRYPTO_H_
+53 -12
View File
@@ -40,6 +40,7 @@
#include <openthread/error.h>
#include <openthread/instance.h>
#include <openthread/platform/crypto.h>
#ifdef __cplusplus
extern "C" {
@@ -199,6 +200,44 @@ struct otMacKey
*/
typedef struct otMacKey otMacKey;
/**
* This type represents a MAC Key Ref used by PSA.
*
*/
typedef otCryptoKeyRef otMacKeyRef;
/**
* @struct otMacKeyMaterial
*
* This structure represents a MAC Key.
*
*/
OT_TOOL_PACKED_BEGIN
struct otMacKeyMaterial
{
union
{
otMacKeyRef mKeyRef; ///< Reference to the key stored.
otMacKey mKey; ///< Key stored as literal.
} mKeyMaterial;
} OT_TOOL_PACKED_END;
/**
* This structure represents a MAC Key reference.
*
*/
typedef struct otMacKeyMaterial otMacKeyMaterial;
/**
* This enumeration defines constants about key types.
*
*/
typedef enum
{
OT_KEY_TYPE_LITERAL_KEY = 0, ///< Use Literal Keys.
OT_KEY_TYPE_KEY_REF = 1, ///< Use Reference to Key.
} otRadioKeyType;
/**
* This structure represents the IEEE 802.15.4 Header IE (Information Element) related information of a radio frame.
*/
@@ -231,12 +270,12 @@ typedef struct otRadioFrame
*/
struct
{
const otMacKey *mAesKey; ///< The key used for AES-CCM frame security.
otRadioIeInfo * mIeInfo; ///< The pointer to the Header IE(s) related information.
uint32_t mTxDelay; ///< The delay time for this transmission (based on `mTxDelayBaseTime`).
uint32_t mTxDelayBaseTime; ///< The base time for the transmission delay.
uint8_t mMaxCsmaBackoffs; ///< Maximum number of backoffs attempts before declaring CCA failure.
uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure.
const otMacKeyMaterial *mAesKey; ///< The key material used for AES-CCM frame security.
otRadioIeInfo * mIeInfo; ///< The pointer to the Header IE(s) related information.
uint32_t mTxDelay; ///< The delay time for this transmission (based on `mTxDelayBaseTime`).
uint32_t mTxDelayBaseTime; ///< The base time for the transmission delay.
uint8_t mMaxCsmaBackoffs; ///< Maximum number of backoffs attempts before declaring CCA failure.
uint8_t mMaxFrameRetries; ///< Maximum number of retries allowed after a transmission failure.
/**
* Indicates whether frame counter and CSL IEs are properly updated in the header.
@@ -559,14 +598,16 @@ void otPlatRadioSetPromiscuous(otInstance *aInstance, bool aEnable);
* @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.
* @param[in] aKeyType Key Type used.
*
*/
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKey *aPrevKey,
const otMacKey *aCurrKey,
const otMacKey *aNextKey);
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey,
otRadioKeyType aKeyType);
/**
* This method sets the current MAC frame counter value.
+37 -5
View File
@@ -382,14 +382,27 @@ otError otThreadSetLinkMode(otInstance *aInstance, otLinkModeConfig aConfig);
/**
* Get the Thread Network Key.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to a buffer containing the Thread Network Key.
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[out] aNetworkKey A pointer to an `otNetworkkey` to return the Thread Network Key.
*
* @sa otThreadSetNetworkKey
*
*/
const otNetworkKey *otThreadGetNetworkKey(otInstance *aInstance);
void otThreadGetNetworkKey(otInstance *aInstance, otNetworkKey *aNetworkKey);
/**
* Get the `otNetworkKeyRef` for Thread Network Key.
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns Reference to the Thread Network Key stored in memory.
*
* @sa otThreadSetNetworkKeyRef
*
*/
otNetworkKeyRef otThreadGetNetworkKeyRef(otInstance *aInstance);
/**
* Set the Thread Network Key.
@@ -402,7 +415,6 @@ const otNetworkKey *otThreadGetNetworkKey(otInstance *aInstance);
* @param[in] aKey A pointer to a buffer containing the Thread Network Key.
*
* @retval OT_ERROR_NONE Successfully set the Thread Network Key.
* @retval OT_ERROR_INVALID_ARGS If aKeyLength is larger than 16.
* @retval OT_ERROR_INVALID_STATE Thread protocols are enabled.
*
* @sa otThreadGetNetworkKey
@@ -410,6 +422,26 @@ const otNetworkKey *otThreadGetNetworkKey(otInstance *aInstance);
*/
otError otThreadSetNetworkKey(otInstance *aInstance, const otNetworkKey *aKey);
/**
* Set the Thread Network Key as a `otNetworkKeyRef`.
*
* This function succeeds only when Thread protocols are disabled. A successful
* call to this function invalidates the Active and Pending Operational Datasets in
* non-volatile memory.
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aKeyRef Reference to the Thread Network Key.
*
* @retval OT_ERROR_NONE Successfully set the Thread Network Key.
* @retval OT_ERROR_INVALID_STATE Thread protocols are enabled.
*
* @sa otThreadGetNetworkKeyRef
*
*/
otError otThreadSetNetworkKeyRef(otInstance *aInstance, otNetworkKeyRef aKeyRef);
/**
* This function returns a pointer to the Thread Routing Locator (RLOC) address.
*
+36 -3
View File
@@ -556,13 +556,26 @@ otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntr
* Get the Thread PSKc
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns A pointer to Thread PSKc
* @param[out] aPskc A pointer to an `otPskc` to return the retrieved Thread PSKc.
*
* @sa otThreadSetPskc
*
*/
const otPskc *otThreadGetPskc(otInstance *aInstance);
void otThreadGetPskc(otInstance *aInstance, otPskc *aPskc);
/**
* Get Key Reference to Thread PSKc stored
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` to be enabled.
*
* @param[in] aInstance A pointer to an OpenThread instance.
*
* @returns Key Reference to PSKc
*
* @sa otThreadSetPskcRef
*
*/
otPskcRef otThreadGetPskcRef(otInstance *aInstance);
/**
* Set the Thread PSKc
@@ -582,6 +595,26 @@ const otPskc *otThreadGetPskc(otInstance *aInstance);
*/
otError otThreadSetPskc(otInstance *aInstance, const otPskc *aPskc);
/**
* Set the Thread PSKc
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` to be enabled.
*
* This function will only succeed when Thread protocols are disabled. A successful
* call to this function will also invalidate the Active and Pending Operational Datasets in
* non-volatile memory.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aPskcRef Key Reference to the new Thread PSKc.
*
* @retval OT_ERROR_NONE Successfully set the Thread PSKc.
* @retval OT_ERROR_INVALID_STATE Thread protocols are enabled.
*
* @sa otThreadGetPskcRef
*
*/
otError otThreadSetPskcRef(otInstance *aInstance, otPskcRef aKeyRef);
/**
* Get the assigned parent priority.
*
+59 -3
View File
@@ -2550,9 +2550,10 @@ otError Interpreter::ProcessPskc(Arg aArgs[])
if (aArgs[0].IsEmpty())
{
const otPskc *pskc = otThreadGetPskc(mInstance);
otPskc pskc;
OutputBytes(pskc->m8);
otThreadGetPskc(mInstance, &pskc);
OutputBytes(pskc.m8);
OutputLine("");
}
else
@@ -2581,6 +2582,36 @@ otError Interpreter::ProcessPskc(Arg aArgs[])
exit:
return error;
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError Interpreter::ProcessPskcRef(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgs[0].IsEmpty())
{
OutputLine("0x%04x", otThreadGetPskcRef(mInstance));
}
else
{
otPskcRef pskcRef;
if (aArgs[1].IsEmpty())
{
SuccessOrExit(error = aArgs[0].ParseAsUint32(pskcRef));
}
else
{
ExitNow(error = OT_ERROR_INVALID_ARGS);
}
SuccessOrExit(error = otThreadSetPskcRef(mInstance, pskcRef));
}
exit:
return error;
}
#endif
#endif // OPENTHREAD_FTD
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
@@ -2965,7 +2996,10 @@ otError Interpreter::ProcessNetworkKey(Arg aArgs[])
if (aArgs[0].IsEmpty())
{
OutputBytes(otThreadGetNetworkKey(mInstance)->m8);
otNetworkKey networkKey;
otThreadGetNetworkKey(mInstance, &networkKey);
OutputBytes(networkKey.m8);
OutputLine("");
}
else
@@ -2980,6 +3014,28 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError Interpreter::ProcessNetworkKeyRef(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
if (aArgs[0].IsEmpty())
{
OutputLine("0x%04x", otThreadGetNetworkKeyRef(mInstance));
}
else
{
otNetworkKeyRef keyRef;
SuccessOrExit(error = aArgs[0].ParseAsUint32(keyRef));
SuccessOrExit(error = otThreadSetNetworkKeyRef(mInstance, keyRef));
}
exit:
return error;
}
#endif
otError Interpreter::ProcessNetworkName(Arg aArgs[])
{
otError error = OT_ERROR_NONE;
+12
View File
@@ -594,6 +594,9 @@ private:
otError ProcessNetworkIdTimeout(Arg aArgs[]);
#endif
otError ProcessNetworkKey(Arg aArgs[]);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError ProcessNetworkKeyRef(Arg aArgs[]);
#endif
otError ProcessNetworkName(Arg aArgs[]);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
otError ProcessNetworkTime(Arg aArgs[]);
@@ -617,6 +620,9 @@ private:
#if OPENTHREAD_FTD
otError ProcessPreferRouterId(Arg aArgs[]);
otError ProcessPskc(Arg aArgs[]);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError ProcessPskcRef(Arg aArgs[]);
#endif
#endif
otError ProcessRcp(Arg aArgs[]);
otError ProcessRegion(Arg aArgs[]);
@@ -880,6 +886,9 @@ private:
{"networkidtimeout", &Interpreter::ProcessNetworkIdTimeout},
#endif
{"networkkey", &Interpreter::ProcessNetworkKey},
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
{"networkkeyref", &Interpreter::ProcessNetworkKeyRef},
#endif
{"networkname", &Interpreter::ProcessNetworkName},
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
{"networktime", &Interpreter::ProcessNetworkTime},
@@ -903,6 +912,9 @@ private:
{"promiscuous", &Interpreter::ProcessPromiscuous},
#if OPENTHREAD_FTD
{"pskc", &Interpreter::ProcessPskc},
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
{"pskcref", &Interpreter::ProcessPskcRef},
#endif
#endif
{"rcp", &Interpreter::ProcessRcp},
{"region", &Interpreter::ProcessRegion},
+2
View File
@@ -692,6 +692,8 @@ otError Dataset::ProcessPskc(Arg aArgs[])
if (aArgs[0].IsEmpty())
{
// sDataset holds the key as a literal string, we don't
// need to export it from PSA ITS.
if (sDataset.mComponents.mIsPskcPresent)
{
mInterpreter.OutputBytes(sDataset.mPskc.m8);
+5
View File
@@ -425,6 +425,7 @@ openthread_core_files = [
"crypto/aes_ccm.hpp",
"crypto/aes_ecb.cpp",
"crypto/aes_ecb.hpp",
"crypto/crypto_platform.cpp",
"crypto/ecdsa.cpp",
"crypto/ecdsa.hpp",
"crypto/hkdf_sha256.cpp",
@@ -437,6 +438,8 @@ openthread_core_files = [
"crypto/pbkdf2_cmac.hpp",
"crypto/sha256.cpp",
"crypto/sha256.hpp",
"crypto/storage.cpp",
"crypto/storage.hpp",
"diags/factory_diags.cpp",
"diags/factory_diags.hpp",
"mac/channel_mask.cpp",
@@ -678,6 +681,8 @@ openthread_radio_sources = [
"common/uptime.cpp",
"crypto/aes_ccm.cpp",
"crypto/aes_ecb.cpp",
"crypto/crypto_platform.cpp",
"crypto/storage.cpp",
"diags/factory_diags.cpp",
"mac/link_raw.cpp",
"mac/mac_frame.cpp",
+2
View File
@@ -110,12 +110,14 @@ set(COMMON_SOURCES
common/uptime.cpp
crypto/aes_ccm.cpp
crypto/aes_ecb.cpp
crypto/crypto_platform.cpp
crypto/ecdsa.cpp
crypto/hkdf_sha256.cpp
crypto/hmac_sha256.cpp
crypto/mbedtls.cpp
crypto/pbkdf2_cmac.cpp
crypto/sha256.cpp
crypto/storage.cpp
diags/factory_diags.cpp
mac/channel_mask.cpp
mac/data_poll_handler.cpp
+5
View File
@@ -187,12 +187,14 @@ SOURCES_COMMON = \
common/uptime.cpp \
crypto/aes_ccm.cpp \
crypto/aes_ecb.cpp \
crypto/crypto_platform.cpp \
crypto/ecdsa.cpp \
crypto/hkdf_sha256.cpp \
crypto/hmac_sha256.cpp \
crypto/mbedtls.cpp \
crypto/pbkdf2_cmac.cpp \
crypto/sha256.cpp \
crypto/storage.cpp \
diags/factory_diags.cpp \
mac/channel_mask.cpp \
mac/data_poll_handler.cpp \
@@ -327,6 +329,8 @@ libopenthread_radio_a_SOURCES = \
common/uptime.cpp \
crypto/aes_ccm.cpp \
crypto/aes_ecb.cpp \
crypto/crypto_platform.cpp \
crypto/storage.cpp \
diags/factory_diags.cpp \
mac/link_raw.cpp \
mac/mac_frame.cpp \
@@ -464,6 +468,7 @@ HEADERS_COMMON = \
crypto/mbedtls.hpp \
crypto/pbkdf2_cmac.hpp \
crypto/sha256.hpp \
crypto/storage.hpp \
diags/factory_diags.hpp \
mac/channel_mask.hpp \
mac/data_poll_handler.hpp \
+15 -22
View File
@@ -45,40 +45,33 @@
using namespace ot::Crypto;
void otCryptoHmacSha256(const uint8_t * aKey,
uint16_t aKeyLength,
const uint8_t * aBuf,
uint16_t aBufLength,
otCryptoSha256Hash *aHash)
void otCryptoHmacSha256(const otCryptoKey *aKey, const uint8_t *aBuf, uint16_t aBufLength, otCryptoSha256Hash *aHash)
{
HmacSha256 hmac;
OT_ASSERT((aKey != nullptr) && (aBuf != nullptr) && (aHash != nullptr));
hmac.Start(aKey, aKeyLength);
hmac.Start(*static_cast<const Key *>(aKey));
hmac.Update(aBuf, aBufLength);
hmac.Finish(*static_cast<HmacSha256::Hash *>(aHash));
}
void otCryptoAesCcm(const uint8_t *aKey,
uint16_t aKeyLength,
uint8_t aTagLength,
const void * aNonce,
uint8_t aNonceLength,
const void * aHeader,
uint32_t aHeaderLength,
void * aPlainText,
void * aCipherText,
uint32_t aLength,
bool aEncrypt,
void * aTag)
void otCryptoAesCcm(const otCryptoKey *aKey,
uint8_t aTagLength,
const void * aNonce,
uint8_t aNonceLength,
const void * aHeader,
uint32_t aHeaderLength,
void * aPlainText,
void * aCipherText,
uint32_t aLength,
bool aEncrypt,
void * aTag)
{
AesCcm aesCcm;
OT_ASSERT((aNonce != nullptr) && (aPlainText != nullptr) && (aCipherText != nullptr) && (aTag != nullptr));
OT_ASSERT((aKey != nullptr) && (aNonce != nullptr) && (aPlainText != nullptr) && (aCipherText != nullptr) &&
(aTag != nullptr));
aesCcm.SetKey(aKey, aKeyLength);
aesCcm.SetKey(*static_cast<const Key *>(aKey));
aesCcm.Init(aHeaderLength, aLength, aTagLength, aNonce, aNonceLength);
if (aHeaderLength != 0)
+32 -3
View File
@@ -112,13 +112,22 @@ otError otThreadSetLinkMode(otInstance *aInstance, otLinkModeConfig aConfig)
return instance.Get<Mle::MleRouter>().SetDeviceMode(Mle::DeviceMode(aConfig));
}
const otNetworkKey *otThreadGetNetworkKey(otInstance *aInstance)
void otThreadGetNetworkKey(otInstance *aInstance, otNetworkKey *aNetworkKey)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return &instance.Get<KeyManager>().GetNetworkKey();
instance.Get<KeyManager>().GetNetworkKey(*static_cast<NetworkKey *>(aNetworkKey));
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otNetworkKeyRef otThreadGetNetworkKeyRef(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<KeyManager>().GetNetworkKeyRef();
}
#endif
otError otThreadSetNetworkKey(otInstance *aInstance, const otNetworkKey *aKey)
{
Error error = kErrorNone;
@@ -128,7 +137,8 @@ otError otThreadSetNetworkKey(otInstance *aInstance, const otNetworkKey *aKey)
VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
error = instance.Get<KeyManager>().SetNetworkKey(*static_cast<const NetworkKey *>(aKey));
instance.Get<KeyManager>().SetNetworkKey(*static_cast<const NetworkKey *>(aKey));
instance.Get<MeshCoP::ActiveDataset>().Clear();
instance.Get<MeshCoP::PendingDataset>().Clear();
@@ -136,6 +146,25 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError otThreadSetNetworkKeyRef(otInstance *aInstance, otNetworkKeyRef aKeyRef)
{
Error error = kErrorNone;
Instance &instance = *static_cast<Instance *>(aInstance);
VerifyOrExit(aKeyRef != 0, error = kErrorInvalidArgs);
VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
instance.Get<KeyManager>().SetNetworkKeyRef(static_cast<NetworkKeyRef>(aKeyRef));
instance.Get<MeshCoP::ActiveDataset>().Clear();
instance.Get<MeshCoP::PendingDataset>().Clear();
exit:
return error;
}
#endif
const otIp6Address *otThreadGetRloc(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
+29 -2
View File
@@ -343,13 +343,22 @@ void otThreadSetSteeringData(otInstance *aInstance, const otExtAddress *aExtAddr
}
#endif
const otPskc *otThreadGetPskc(otInstance *aInstance)
void otThreadGetPskc(otInstance *aInstance, otPskc *aPskc)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return &instance.Get<KeyManager>().GetPskc();
instance.Get<KeyManager>().GetPskc(*static_cast<Pskc *>(aPskc));
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otPskcRef otThreadGetPskcRef(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<KeyManager>().GetPskcRef();
}
#endif
otError otThreadSetPskc(otInstance *aInstance, const otPskc *aPskc)
{
Error error = kErrorNone;
@@ -365,6 +374,24 @@ exit:
return error;
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError otThreadSetPskcRef(otInstance *aInstance, otPskcRef aKeyRef)
{
Error error = kErrorNone;
Instance &instance = *static_cast<Instance *>(aInstance);
VerifyOrExit(aKeyRef != 0, error = kErrorInvalidArgs);
VerifyOrExit(instance.Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
instance.Get<KeyManager>().SetPskcRef(aKeyRef);
instance.Get<MeshCoP::ActiveDataset>().Clear();
instance.Get<MeshCoP::PendingDataset>().Clear();
exit:
return error;
}
#endif
int8_t otThreadGetParentPriority(otInstance *aInstance)
{
Instance &instance = *static_cast<Instance *>(aInstance);
+20
View File
@@ -128,6 +128,26 @@
#define OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT 0
#endif
/**
* @def OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET
*
* Default NVM offset while using key refs. Platforms can override this definition based on implementation
*
*/
#ifndef OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET
#define OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET 0x20000
#endif
/**
* @def OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
*
* Define to 1 if you want to enable key ref usage support as defined by platform.
*
*/
#ifndef OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 0
#endif
#if OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_SUPPORT
#if (!defined(OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_PAGE) || \
!defined(OPENTHREAD_CONFIG_PLATFORM_RADIO_PROPRIETARY_CHANNEL_MIN) || \
+9 -3
View File
@@ -44,12 +44,18 @@ namespace Crypto {
void AesCcm::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
{
mEcb.SetKey(aKey, CHAR_BIT * aKeyLength);
Key cryptoKey;
cryptoKey.Set(aKey, aKeyLength);
SetKey(cryptoKey);
}
void AesCcm::SetKey(const Mac::Key &aMacKey)
void AesCcm::SetKey(const Mac::KeyMaterial &aMacKey)
{
SetKey(aMacKey.GetKey(), Mac::Key::kSize);
Key cryptoKey;
aMacKey.ConvertToCryptoKey(cryptoKey);
SetKey(cryptoKey);
}
void AesCcm::Init(uint32_t aHeaderLength,
+12 -2
View File
@@ -38,8 +38,10 @@
#include <stdint.h>
#include <openthread/platform/crypto.h>
#include "common/error.hpp"
#include "crypto/aes_ecb.hpp"
#include "crypto/storage.hpp"
#include "mac/mac_types.hpp"
namespace ot {
@@ -73,6 +75,14 @@ public:
kDecrypt, // Decryption mode.
};
/**
* This method sets the key.
*
* @param[in] aKey Crypto Key used in AES operation
*
*/
void SetKey(const Key &aKey) { mEcb.SetKey(aKey); }
/**
* This method sets the key.
*
@@ -85,10 +95,10 @@ public:
/**
* This method sets the key.
*
* @param[in] aMacKey A MAC key.
* @param[in] aMacKey Key Material for AES operation.
*
*/
void SetKey(const Mac::Key &aMacKey);
void SetKey(const Mac::KeyMaterial &aMacKey);
/**
* This method initializes the AES CCM computation.
+15 -5
View File
@@ -32,28 +32,38 @@
*/
#include "aes_ecb.hpp"
#include "common/debug.hpp"
#include "common/error.hpp"
namespace ot {
namespace Crypto {
AesEcb::AesEcb(void)
{
mbedtls_aes_init(&mContext);
Error err = otPlatCryptoAesInit(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void AesEcb::SetKey(const uint8_t *aKey, uint16_t aKeyLength)
void AesEcb::SetKey(const Key &aKey)
{
mbedtls_aes_setkey_enc(&mContext, aKey, aKeyLength);
Error err = otPlatCryptoAesSetKey(&mContext, sizeof(mContext), &aKey);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void AesEcb::Encrypt(const uint8_t aInput[kBlockSize], uint8_t aOutput[kBlockSize])
{
mbedtls_aes_crypt_ecb(&mContext, MBEDTLS_AES_ENCRYPT, aInput, aOutput);
Error err = otPlatCryptoAesEncrypt(&mContext, sizeof(mContext), aInput, aOutput);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
AesEcb::~AesEcb(void)
{
mbedtls_aes_free(&mContext);
Error err = otPlatCryptoAesFree(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
} // namespace Crypto
+12 -5
View File
@@ -35,8 +35,10 @@
#define AES_ECB_HPP_
#include "openthread-core-config.h"
#include <mbedtls/aes.h>
#include <openthread/platform/crypto.h>
#include "crypto/storage.hpp"
namespace ot {
namespace Crypto {
@@ -72,11 +74,10 @@ public:
/**
* This method sets the key.
*
* @param[in] aKey A pointer to the key.
* @param[in] aKeyLength The key length in bits.
* @param[in] aKey Crypto Key used for ECB operation
*
*/
void SetKey(const uint8_t *aKey, uint16_t aKeyLength);
void SetKey(const Key &aKey);
/**
* This method encrypts data.
@@ -88,7 +89,13 @@ public:
void Encrypt(const uint8_t aInput[kBlockSize], uint8_t aOutput[kBlockSize]);
private:
mbedtls_aes_context mContext;
union AesEcbContext
{
uint32_t mKeyRef;
mbedtls_aes_context mContext;
};
AesEcbContext mContext;
};
/**
+337
View File
@@ -0,0 +1,337 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file implements the Crypto platform callbacks into OpenThread and default/weak Crypto platform APIs.
*/
#include "openthread-core-config.h"
#include <mbedtls/aes.h>
#include <mbedtls/md.h>
#include <openthread/instance.h>
#include <openthread/platform/crypto.h>
#include <openthread/platform/time.h>
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/instance.hpp"
#include "common/message.hpp"
#include "crypto/hmac_sha256.hpp"
#include "crypto/storage.hpp"
using namespace ot;
using namespace Crypto;
//---------------------------------------------------------------------------------------------------------------------
// Default/weak implementation of crypto platform APIs
OT_TOOL_WEAK otError otPlatCryptoInit(void)
{
return kErrorNone;
}
// AES Implementation
OT_TOOL_WEAK otError otPlatCryptoAesInit(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
mbedtls_aes_context *context = static_cast<mbedtls_aes_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
mbedtls_aes_init(context);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoAesSetKey(void *aContext, size_t aContextSize, const otCryptoKey *aKey)
{
Error error = kErrorNone;
mbedtls_aes_context *context = static_cast<mbedtls_aes_context *>(aContext);
const LiteralKey key(*static_cast<const Key *>(aKey));
VerifyOrExit(aContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
VerifyOrExit((mbedtls_aes_setkey_enc(context, key.GetBytes(), (key.GetLength() * CHAR_BIT)) == 0),
error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoAesEncrypt(void * aContext,
size_t aContextSize,
const uint8_t *aInput,
uint8_t * aOutput)
{
Error error = kErrorNone;
mbedtls_aes_context *context = static_cast<mbedtls_aes_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
VerifyOrExit((mbedtls_aes_crypt_ecb(context, MBEDTLS_AES_ENCRYPT, aInput, aOutput) == 0), error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoAesFree(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
mbedtls_aes_context *context = static_cast<mbedtls_aes_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_aes_context), error = kErrorFailed);
mbedtls_aes_free(context);
exit:
return error;
}
#if !OPENTHREAD_RADIO
// HMAC implementations
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Init(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
const mbedtls_md_info_t *mdInfo = nullptr;
mbedtls_md_context_t * context = static_cast<mbedtls_md_context_t *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
mbedtls_md_init(context);
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
VerifyOrExit((mbedtls_md_setup(context, mdInfo, 1) == 0), error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Deinit(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
mbedtls_md_context_t *context = static_cast<mbedtls_md_context_t *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
mbedtls_md_free(context);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Start(void *aContext, size_t aContextSize, const otCryptoKey *aKey)
{
Error error = kErrorNone;
mbedtls_md_context_t *context = static_cast<mbedtls_md_context_t *>(aContext);
const LiteralKey key(*static_cast<const Key *>(aKey));
VerifyOrExit(aContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
VerifyOrExit((mbedtls_md_hmac_starts(context, key.GetBytes(), key.GetLength()) == 0), error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Update(void * aContext,
size_t aContextSize,
const void *aBuf,
uint16_t aBufLength)
{
Error error = kErrorNone;
mbedtls_md_context_t *context = static_cast<mbedtls_md_context_t *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
VerifyOrExit((mbedtls_md_hmac_update(context, reinterpret_cast<const uint8_t *>(aBuf), aBufLength) == 0),
error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Finish(void *aContext, size_t aContextSize, uint8_t *aBuf, size_t aBufLength)
{
OT_UNUSED_VARIABLE(aBufLength);
Error error = kErrorNone;
mbedtls_md_context_t *context = static_cast<mbedtls_md_context_t *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_md_context_t), error = kErrorFailed);
VerifyOrExit((mbedtls_md_hmac_finish(context, aBuf) == 0), error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoHkdfExpand(void * aContext,
size_t aContextSize,
const uint8_t *aInfo,
uint16_t aInfoLength,
uint8_t * aOutputKey,
uint16_t aOutputKeyLength)
{
Error error = kErrorNone;
HmacSha256 hmac;
HmacSha256::Hash hash;
uint8_t iter = 0;
uint16_t copyLength;
HmacSha256::Hash *prk = static_cast<HmacSha256::Hash *>(aContext);
VerifyOrExit(aContextSize >= sizeof(HmacSha256::Hash), error = kErrorFailed);
// The aOutputKey is calculated as follows [RFC5889]:
//
// N = ceil( aOutputKeyLength / HashSize)
// T = T(1) | T(2) | T(3) | ... | T(N)
// aOutputKey is first aOutputKeyLength of T
//
// Where:
// T(0) = empty string (zero length)
// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
// T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
// T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
// ...
while (aOutputKeyLength > 0)
{
Key cryptoKey;
cryptoKey.Set(prk->GetBytes(), sizeof(HmacSha256::Hash));
hmac.Start(cryptoKey);
if (iter != 0)
{
hmac.Update(hash);
}
hmac.Update(aInfo, aInfoLength);
iter++;
hmac.Update(iter);
hmac.Finish(hash);
copyLength = (aOutputKeyLength > sizeof(hash)) ? sizeof(hash) : aOutputKeyLength;
memcpy(aOutputKey, hash.GetBytes(), copyLength);
aOutputKey += copyLength;
aOutputKeyLength -= copyLength;
}
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoHkdfExtract(void * aContext,
size_t aContextSize,
const uint8_t * aSalt,
uint16_t aSaltLength,
const otCryptoKey *aInputKey)
{
Error error = kErrorNone;
HmacSha256 hmac;
Key cryptoKey;
HmacSha256::Hash *prk = static_cast<HmacSha256::Hash *>(aContext);
const LiteralKey inputKey(*static_cast<const Key *>(aInputKey));
VerifyOrExit(aContextSize >= sizeof(HmacSha256::Hash), error = kErrorFailed);
cryptoKey.Set(aSalt, aSaltLength);
// PRK is calculated as HMAC-Hash(aSalt, aInputKey)
hmac.Start(cryptoKey);
hmac.Update(inputKey.GetBytes(), inputKey.GetLength());
hmac.Finish(*prk);
exit:
return error;
}
// SHA256 platform implementations
OT_TOOL_WEAK otError otPlatCryptoSha256Init(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
mbedtls_sha256_context *context = static_cast<mbedtls_sha256_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
mbedtls_sha256_init(context);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoSha256Deinit(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
mbedtls_sha256_context *context = static_cast<mbedtls_sha256_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
mbedtls_sha256_free(context);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoSha256Start(void *aContext, size_t aContextSize)
{
Error error = kErrorNone;
mbedtls_sha256_context *context = static_cast<mbedtls_sha256_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
VerifyOrExit((mbedtls_sha256_starts_ret(context, 0) == 0), error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoSha256Update(void * aContext,
size_t aContextSize,
const void *aBuf,
uint16_t aBufLength)
{
Error error = kErrorNone;
mbedtls_sha256_context *context = static_cast<mbedtls_sha256_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
VerifyOrExit((mbedtls_sha256_update_ret(context, reinterpret_cast<const uint8_t *>(aBuf), aBufLength) == 0),
error = kErrorFailed);
exit:
return error;
}
OT_TOOL_WEAK otError otPlatCryptoSha256Finish(void *aContext, size_t aContextSize, uint8_t *aHash, uint16_t aHashSize)
{
OT_UNUSED_VARIABLE(aHashSize);
Error error = kErrorNone;
mbedtls_sha256_context *context = static_cast<mbedtls_sha256_context *>(aContext);
VerifyOrExit(aContextSize >= sizeof(mbedtls_sha256_context), error = kErrorFailed);
VerifyOrExit((mbedtls_sha256_finish_ret(context, aHash) == 0), error = kErrorFailed);
exit:
return error;
}
#endif // #if !OPENTHREAD_RADIO
+10 -47
View File
@@ -35,61 +35,24 @@
#include <string.h>
#include "common/code_utils.hpp"
#include "common/debug.hpp"
namespace ot {
namespace Crypto {
void HkdfSha256::Extract(const uint8_t *aSalt, uint16_t aSaltLength, const uint8_t *aInputKey, uint16_t aInputKeyLength)
void HkdfSha256::Extract(const uint8_t *aSalt, uint16_t aSaltLength, const Key &aInputKey)
{
HmacSha256 hmac;
// PRK is calculated as HMAC-Hash(aSalt, aInputKey)
hmac.Start(aSalt, aSaltLength);
hmac.Update(aInputKey, aInputKeyLength);
hmac.Finish(mPrk);
Error err = otPlatCryptoHkdfExtract(&mContext, sizeof(mContext), aSalt, aSaltLength, &aInputKey);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void HkdfSha256::Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOutputKey, uint16_t aOutputKeyLength)
{
HmacSha256 hmac;
HmacSha256::Hash hash;
uint8_t iter = 0;
uint16_t copyLength;
// The aOutputKey is calculated as follows [RFC5889]:
//
// N = ceil( aOutputKeyLength / HashSize)
// T = T(1) | T(2) | T(3) | ... | T(N)
// aOutputKey is first aOutputKeyLength of T
//
// Where:
// T(0) = empty string (zero length)
// T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
// T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
// T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
// ...
while (aOutputKeyLength > 0)
{
hmac.Start(mPrk.GetBytes(), sizeof(mPrk));
if (iter != 0)
{
hmac.Update(hash);
}
hmac.Update(aInfo, aInfoLength);
iter++;
hmac.Update(iter);
hmac.Finish(hash);
copyLength = (aOutputKeyLength > sizeof(hash)) ? sizeof(hash) : aOutputKeyLength;
memcpy(aOutputKey, hash.GetBytes(), copyLength);
aOutputKey += copyLength;
aOutputKeyLength -= copyLength;
}
Error err = otPlatCryptoHkdfExpand(&mContext, sizeof(mContext), aInfo, aInfoLength, aOutputKey, aOutputKeyLength);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
} // namespace Crypto
+11 -4
View File
@@ -37,6 +37,8 @@
#include "openthread-core-config.h"
#include <psa/crypto.h>
#include "crypto/hmac_sha256.hpp"
namespace ot {
@@ -63,11 +65,10 @@ public:
*
* @param[in] aSalt A pointer to buffer containing salt.
* @param[in] aSaltLength The salt length (in bytes).
* @param[in] aInputKey A pointer to buffer containing the input key.
* @param[in] aInputKeyLength The input key length (in bytes).
* @param[in] aInputKey The input key.
*
*/
void Extract(const uint8_t *aSalt, uint16_t aSaltLength, const uint8_t *aInputKey, uint16_t aInputKeyLength);
void Extract(const uint8_t *aSalt, uint16_t aSaltLength, const Key &aInputKey);
/**
* This method performs the HKDF Expand step.
@@ -84,7 +85,13 @@ public:
void Expand(const uint8_t *aInfo, uint16_t aInfoLength, uint8_t *aOutputKey, uint16_t aOutputKeyLength);
private:
HmacSha256::Hash mPrk; // Pseudo-Random Key (derived from Extract step).
union HkdfContext
{
HmacSha256::Hash mPrk; // Pseudo-Random Key (derived from Extract step).
psa_key_derivation_operation_t mOperation;
};
HkdfContext mContext;
};
/**
+21 -14
View File
@@ -32,7 +32,7 @@
*/
#include "hmac_sha256.hpp"
#include "common/debug.hpp"
#include "common/message.hpp"
namespace ot {
@@ -40,25 +40,37 @@ namespace Crypto {
HmacSha256::HmacSha256(void)
{
const mbedtls_md_info_t *mdInfo = nullptr;
mbedtls_md_init(&mContext);
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
mbedtls_md_setup(&mContext, mdInfo, 1);
Error err = otPlatCryptoHmacSha256Init(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
HmacSha256::~HmacSha256(void)
{
mbedtls_md_free(&mContext);
Error err = otPlatCryptoHmacSha256Deinit(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void HmacSha256::Start(const uint8_t *aKey, uint16_t aKeyLength)
void HmacSha256::Start(const Key &aKey)
{
mbedtls_md_hmac_starts(&mContext, aKey, aKeyLength);
Error err = otPlatCryptoHmacSha256Start(&mContext, sizeof(mContext), &aKey);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void HmacSha256::Update(const void *aBuf, uint16_t aBufLength)
{
mbedtls_md_hmac_update(&mContext, reinterpret_cast<const uint8_t *>(aBuf), aBufLength);
Error err = otPlatCryptoHmacSha256Update(&mContext, sizeof(mContext), aBuf, aBufLength);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void HmacSha256::Finish(Hash &aHash)
{
Error err = otPlatCryptoHmacSha256Finish(&mContext, sizeof(mContext), aHash.m8, Hash::kSize);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void HmacSha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
@@ -74,10 +86,5 @@ void HmacSha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLen
}
}
void HmacSha256::Finish(Hash &aHash)
{
mbedtls_md_hmac_finish(&mContext, aHash.m8);
}
} // namespace Crypto
} // namespace ot
+13 -4
View File
@@ -39,8 +39,12 @@
#include <stdint.h>
#include <mbedtls/md.h>
#include <psa/crypto.h>
#include <openthread/platform/crypto.h>
#include "crypto/sha256.hpp"
#include "crypto/storage.hpp"
namespace ot {
@@ -83,11 +87,10 @@ public:
/**
* This method sets the key and starts the HMAC computation.
*
* @param[in] aKey A pointer to the key.
* @param[in] aKeyLength The key length in bytes.
* @param[in] aKey The key to use.
*
*/
void Start(const uint8_t *aKey, uint16_t aKeyLength);
void Start(const Key &aKey);
/**
* This method inputs bytes into the HMAC computation.
@@ -131,7 +134,13 @@ public:
void Finish(Hash &aHash);
private:
mbedtls_md_context_t mContext;
union HmacContext
{
psa_mac_operation_t mOperation;
mbedtls_md_context_t mContext;
};
HmacContext mContext;
};
/**
+17 -6
View File
@@ -33,6 +33,8 @@
#include "sha256.hpp"
#include "common/debug.hpp"
#include "common/error.hpp"
#include "common/message.hpp"
namespace ot {
@@ -40,22 +42,30 @@ namespace Crypto {
Sha256::Sha256(void)
{
mbedtls_sha256_init(&mContext);
Error err = otPlatCryptoSha256Init(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
Sha256::~Sha256(void)
{
mbedtls_sha256_free(&mContext);
Error err = otPlatCryptoSha256Deinit(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void Sha256::Start(void)
{
mbedtls_sha256_starts_ret(&mContext, 0);
Error err = otPlatCryptoSha256Start(&mContext, sizeof(mContext));
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void Sha256::Update(const void *aBuf, uint16_t aBufLength)
{
mbedtls_sha256_update_ret(&mContext, reinterpret_cast<const uint8_t *>(aBuf), aBufLength);
Error err = otPlatCryptoSha256Update(&mContext, sizeof(mContext), aBuf, aBufLength);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
void Sha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
@@ -73,8 +83,9 @@ void Sha256::Update(const Message &aMessage, uint16_t aOffset, uint16_t aLength)
void Sha256::Finish(Hash &aHash)
{
mbedtls_sha256_finish_ret(&mContext, aHash.m8);
Error err = otPlatCryptoSha256Finish(&mContext, sizeof(mContext), aHash.m8, Hash::kSize);
OT_ASSERT(err == kErrorNone);
OT_UNUSED_VARIABLE(err);
}
} // namespace Crypto
} // namespace ot
+9 -1
View File
@@ -39,8 +39,10 @@
#include <stdint.h>
#include <mbedtls/sha256.h>
#include <psa/crypto.h>
#include <openthread/crypto.h>
#include <openthread/platform/crypto.h>
#include "common/clearable.hpp"
#include "common/equatable.hpp"
@@ -144,7 +146,13 @@ public:
void Finish(Hash &aHash);
private:
mbedtls_sha256_context mContext;
union Sha256Context
{
psa_hash_operation_t mOperation;
mbedtls_sha256_context mContext;
};
Sha256Context mContext;
};
/**
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes implementation for Crypto Internal Trusted Storage (ITS) APIs.
*/
#include "crypto/storage.hpp"
#include "common/debug.hpp"
namespace ot {
namespace Crypto {
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
Error Key::ExtractKey(uint8_t *aKeyBuffer, uint16_t &aKeyLength) const
{
Error error;
size_t readKeyLength;
OT_ASSERT(IsKeyRef());
error = Crypto::Storage::ExportKey(GetKeyRef(), aKeyBuffer, aKeyLength, readKeyLength);
OT_ASSERT(error == kErrorNone);
VerifyOrExit(readKeyLength <= aKeyLength, error = kErrorNoBufs);
aKeyLength = static_cast<uint16_t>(readKeyLength);
exit:
return error;
}
#endif
LiteralKey::LiteralKey(const Key &aKey)
: mKey(aKey.GetBytes())
, mLength(aKey.GetLength())
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
if (aKey.IsKeyRef())
{
Error error;
mKey = mBuffer;
mLength = sizeof(mBuffer);
error = aKey.ExtractKey(mBuffer, mLength);
OT_ASSERT(error == kErrorNone);
OT_UNUSED_VARIABLE(error);
}
#endif
}
} // namespace Crypto
} // namespace ot
+341
View File
@@ -0,0 +1,341 @@
/*
* Copyright (c) 2021, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for Crypto Internal Trusted Storage (ITS) APIs.
*/
#ifndef STORAGE_HPP_
#define STORAGE_HPP_
#include "openthread-core-config.h"
#include <openthread/platform/crypto.h>
#include "common/clearable.hpp"
#include "common/code_utils.hpp"
#include "common/error.hpp"
#include "common/non_copyable.hpp"
namespace ot {
namespace Crypto {
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
namespace Storage {
/**
* This enumeration defines the key types.
*
*/
enum KeyType : uint8_t
{
kKeyTypeRaw = OT_CRYPTO_KEY_TYPE_RAW, ///< Key Type: Raw Data.
kKeyTypeAes = OT_CRYPTO_KEY_TYPE_AES, ///< Key Type: AES.
kKeyTypeHmac = OT_CRYPTO_KEY_TYPE_HMAC, ///< Key Type: HMAC.
};
/**
* This enumeration defines the key algorithms.
*
*/
enum KeyAlgorithm : uint8_t
{
kKeyAlgorithmVendor = OT_CRYPTO_KEY_ALG_VENDOR, ///< Key Algorithm: Vendor Defined.
kKeyAlgorithmAesEcb = OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
kKeyAlgorithmHmacSha256 = OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
};
constexpr uint8_t kUsageNone = OT_CRYPTO_KEY_USAGE_NONE; ///< Key Usage: Key Usage is empty.
constexpr uint8_t kUsageExport = OT_CRYPTO_KEY_USAGE_EXPORT; ///< Key Usage: Key can be exported.
constexpr uint8_t kUsageEncrypt = OT_CRYPTO_KEY_USAGE_ENCRYPT; ///< Key Usage: Encrypt (vendor defined).
constexpr uint8_t kUsageDecrypt = OT_CRYPTO_KEY_USAGE_DECRYPT; ///< Key Usage: AES ECB.
constexpr uint8_t kUsageSignHash = OT_CRYPTO_KEY_USAGE_SIGN_HASH; ///< Key Usage: HMAC SHA-256.
/**
* This enumeration defines the key storage types.
*
*/
enum StorageType : uint8_t
{
kTypeVolatile = OT_CRYPTO_KEY_STORAGE_VOLATILE, ///< Key is volatile.
kTypePersistent = OT_CRYPTO_KEY_STORAGE_PERSISTENT, ///< Key is persistent.
};
/**
* This datatype represents the key reference.
*
*/
typedef otCryptoKeyRef KeyRef;
constexpr KeyRef kInvalidKeyRef = 0x80000000; ///< Invalid `KeyRef` value (PSA_KEY_ID_VENDOR_MAX + 1).
/**
* This type represents the Key Attributes structure.
*
*/
typedef otCryptoKeyAttributes KeyAttributes;
/**
* Determine if a given `KeyRef` is valid or not.
*
* @param[in] aKeyRef The `KeyRef` to check.
*
* @retval TRUE If @p aKeyRef is valid.
* @retval FALSE If @p aKeyRef is not valid.
*
*/
inline bool IsKeyRefValid(KeyRef aKeyRef)
{
return (aKeyRef < kInvalidKeyRef);
}
/**
* Import a key into PSA ITS.
*
* @param[inout] aKeyRef Reference to the key ref to be used for crypto operations.
* @param[in] aKeyType Key Type encoding for the key.
* @param[in] aKeyAlgorithm Key algorithm encoding for the key.
* @param[in] aKeyUsage Key Usage encoding for the key.
* @param[in] aStorageType Key storage type.
* @param[in] aKey Actual key to be imported.
* @param[in] aKeyLen Length of the key to be imported.
*
* @retval kErrorNone Successfully imported the key.
* @retval kErrorFailed Failed to import the key.
* @retval kErrorInvalidArgs @p aKey was set to nullptr.
*
*/
inline Error ImportKey(KeyRef & aKeyRef,
KeyType aKeyType,
KeyAlgorithm aKeyAlgorithm,
int aKeyUsage,
StorageType aStorageType,
const uint8_t *aKey,
size_t aKeyLen)
{
return otPlatCryptoImportKey(&aKeyRef, static_cast<otCryptoKeyType>(aKeyType),
static_cast<otCryptoKeyAlgorithm>(aKeyAlgorithm), aKeyUsage,
static_cast<otCryptoKeyStorage>(aStorageType), aKey, aKeyLen);
}
/**
* Export a key stored in PSA ITS.
*
* @param[in] aKeyRef The key ref to be used for crypto operations.
* @param[out] aBuffer Pointer to the buffer where key needs to be exported.
* @param[in] aBufferLen Length of the buffer passed to store the exported key.
* @param[out] aKeyLen Reference to variable to return the length of the exported key.
*
* @retval kErrorNone Successfully exported @p aKeyRef.
* @retval kErrorFailed Failed to export @p aKeyRef.
* @retval kErrorInvalidArgs @p aBuffer was nullptr.
*
*/
inline Error ExportKey(KeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t &aKeyLen)
{
return otPlatCryptoExportKey(aKeyRef, aBuffer, aBufferLen, &aKeyLen);
}
/**
* Destroy a key stored in PSA ITS.
*
* @param[in] aKeyRef The key ref to be removed.
*
*/
inline void DestroyKey(KeyRef aKeyRef)
{
if (IsKeyRefValid(aKeyRef))
{
IgnoreError(otPlatCryptoDestroyKey(aKeyRef));
}
}
/**
* Check if the keyRef passed has an associated key in PSA ITS.
*
* @param[in] aKeyRef The Key Ref for to check.
*
* @retval true Key Ref passed has a key associated in PSA.
* @retval false Key Ref passed is invalid and has no key associated in PSA.
*
*/
inline bool HasKey(KeyRef aKeyRef)
{
return otPlatCryptoHasKey(aKeyRef);
}
} // namespace Storage
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* This class represents a crypto key.
*
* The `Key` can represent a literal key (i.e., a pointer to a byte array containing the key along with a key length)
* or a `KeyRef` (if `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled).
*
*/
class Key : public otCryptoKey, public Clearable<Key>
{
public:
/**
* This method sets the `Key` as a literal key from a given byte array and length.
*
* @param[in] aKeyBytes A pointer to buffer containing the key.
* @param[in] aKeyLength The key length (number of bytes in @p akeyBytes).
*
*/
void Set(const uint8_t *aKeyBytes, uint16_t aKeyLength)
{
mKey = aKeyBytes;
mKeyLength = aKeyLength;
}
/**
* This method gets the pointer to the bye array containing the key.
*
* If `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled and `IsKeyRef()` returns `true`, then this
* method returns `nullptr`.
*
* @returns The pointer to the byte array containing the key, or `nullptr` if the `Key` represents a `KeyRef`
*
*/
const uint8_t *GetBytes(void) const { return mKey; }
/**
* This method gets the key length (number of bytes).
*
* If `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` is enabled and `IsKeyRef()` returns `true`, then this
* method returns zero.
*
* @returns The key length (number of bytes in the byte array from `GetBytes()`), or zero if `Key` represents a
* `keyRef`.
*
*/
uint16_t GetLength(void) const { return mKeyLength; }
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* This method indicates whether or not the key is represented as a `KeyRef`.
*
* @retval TRUE The `Key` represents a `KeyRef`
* @retval FALSE The `Key` represents a literal key.
*
*/
bool IsKeyRef(void) const { return (mKey == nullptr); }
/**
* This method gets the `KeyRef`.
*
* This method MUST be used when `IsKeyRef()` returns `true`, otherwise its behavior is undefined.
*
* @returns The `KeyRef` associated with `Key`.
*
*/
Storage::KeyRef GetKeyRef(void) const { return mKeyRef; }
/**
* This method sets the `Key` as a `KeyRef`.
*
* @param[in] aKeyRef The `KeyRef` to set from.
*
*/
void SetAsKeyRef(Storage::KeyRef aKeyRef)
{
mKey = nullptr;
mKeyLength = 0;
mKeyRef = aKeyRef;
}
/**
* This method extracts and return the literal key when the key is represented as a `KeyRef`
*
* This method MUST be used when `IsKeyRef()` returns `true`.
*
* @param[out] aKeyBuffer Pointer to a byte array buffer to place the extracted key.
* @param[inout] aKeyLength On input, the size of @p aKeyBuffer.
* On exit, returns the key length (number of bytes written in @p aKeyBuffer).
*
* @retval kErrorNone Successfully extracted the key, @p aKeyBuffer and @p aKeyLength are updated.
* @retval kErrorNoBufs Key does not fit in @p aKeyBuffer (extracted key length is larger than @p aKeyLength).
*
*/
Error ExtractKey(uint8_t *aKeyBuffer, uint16_t &aKeyLength) const;
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
};
/**
* This class represents a literal key derived from a `Key`.
*
*/
class LiteralKey : public Clearable<LiteralKey>, private NonCopyable
{
public:
static constexpr uint16_t kMaxSize = 32; ///< Maximum size of the key.
/**
* This constructor initializes the `LiteralKey` from a given `Key`.
*
* If the @p aKey is itself represents a literal key the same key buffer pointers are used. If the @p aKey is
* a `KeyRef` then the literal key is extracted. In this case, the extracted key MUST be smaller than `kMaxSize`.
*
* @param[in] aKey The key to convert from.
*
*/
explicit LiteralKey(const Key &aKey);
/*
* This method gets the pointer to the byte array containing the literal key.
*
* @returns The pointer to the byte array containing the literal key.
*
*/
const uint8_t *GetBytes(void) const { return mKey; }
/**
* This method gets the key length.
*
* @returns The key length (number of bytes in the byte array from `GetBytes()`).
*
*/
uint16_t GetLength(void) const { return mLength; }
private:
const uint8_t *mKey;
uint16_t mLength;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
uint8_t mBuffer[kMaxSize];
#endif
};
} // namespace Crypto
} // namespace ot
#endif // STORAGE_HPP_
+10 -2
View File
@@ -225,10 +225,18 @@ Error LinkRaw::SetMacKey(uint8_t aKeyIdMode,
const Key &aCurrKey,
const Key &aNextKey)
{
Error error = kErrorNone;
Error error = kErrorNone;
KeyMaterial prevKey;
KeyMaterial currKey;
KeyMaterial nextKey;
VerifyOrExit(IsEnabled(), error = kErrorInvalidState);
mSubMac.SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey);
prevKey.SetFrom(aPrevKey);
currKey.SetFrom(aCurrKey);
nextKey.SetFrom(aNextKey);
mSubMac.SetMacKey(aKeyIdMode, aKeyId, prevKey, currKey, nextKey);
exit:
return error;
+1
View File
@@ -254,6 +254,7 @@ public:
* @param[in] aNextKey The next MAC key.
*
* @retval kErrorNone If successful.
* @retval kErrorFailed Platform failed to import key.
* @retval kErrorInvalidState If the raw link-layer isn't enabled.
*
*/
+28 -25
View File
@@ -56,9 +56,6 @@
namespace ot {
namespace Mac {
const otMacKey Mac::sMode2Key = {
{0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f, 0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66}};
const otExtAddress Mac::sMode2ExtAddress = {
{0x35, 0x06, 0xfe, 0xb8, 0x23, 0xd4, 0x87, 0x12},
};
@@ -127,6 +124,9 @@ Mac::Mac(Instance &aInstance)
{
ExtAddress randomExtAddress;
static const otMacKey sMode2Key = {
{0x78, 0x58, 0x16, 0x86, 0xfd, 0xb4, 0x58, 0x0f, 0xb0, 0x92, 0x54, 0x6a, 0xec, 0xbd, 0x15, 0x66}};
randomExtAddress.GenerateRandom();
mCcaSuccessRateTracker.Clear();
@@ -145,6 +145,8 @@ Mac::Mac(Instance &aInstance)
SetPanId(mPanId);
SetExtAddress(randomExtAddress);
SetShortAddress(GetShortAddress());
mMode2KeyMaterial.SetFrom(static_cast<const Key &>(sMode2Key));
}
Error Mac::ActiveScan(uint32_t aScanChannels, uint16_t aScanDuration, ActiveScanHandler aHandler, void *aContext)
@@ -999,7 +1001,8 @@ void Mac::ProcessTransmitSecurity(TxFrame &aFrame)
case Frame::kKeyIdMode2:
{
const uint8_t keySource[] = {0xff, 0xff, 0xff, 0xff};
aFrame.SetAesKey(static_cast<const Key &>(sMode2Key));
aFrame.SetAesKey(static_cast<const KeyMaterial &>(mMode2KeyMaterial));
mKeyIdMode2FrameCounter++;
aFrame.SetFrameCounter(mKeyIdMode2FrameCounter);
aFrame.SetKeySource(keySource);
@@ -1613,15 +1616,15 @@ void Mac::HandleTimer(void)
Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neighbor *aNeighbor)
{
KeyManager & keyManager = Get<KeyManager>();
Error error = kErrorSecurity;
uint8_t securityLevel;
uint8_t keyIdMode;
uint32_t frameCounter;
uint8_t keyid;
uint32_t keySequence = 0;
const Key * macKey;
const ExtAddress *extAddress;
KeyManager & keyManager = Get<KeyManager>();
Error error = kErrorSecurity;
uint8_t securityLevel;
uint8_t keyIdMode;
uint32_t frameCounter;
uint8_t keyid;
uint32_t keySequence = 0;
const KeyMaterial *macKey;
const ExtAddress * extAddress;
VerifyOrExit(aFrame.GetSecurityEnabled(), error = kErrorNone);
@@ -1697,7 +1700,7 @@ Error Mac::ProcessReceiveSecurity(RxFrame &aFrame, const Address &aSrcAddr, Neig
break;
case Frame::kKeyIdMode2:
macKey = static_cast<const Key *>(&sMode2Key);
macKey = static_cast<const KeyMaterial *>(&mMode2KeyMaterial);
extAddress = static_cast<const ExtAddress *>(&sMode2ExtAddress);
break;
@@ -1749,17 +1752,17 @@ exit:
#if OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
Error Mac::ProcessEnhAckSecurity(TxFrame &aTxFrame, RxFrame &aAckFrame)
{
Error error = kErrorSecurity;
uint8_t securityLevel;
uint8_t txKeyId;
uint8_t ackKeyId;
uint8_t keyIdMode;
uint32_t frameCounter;
Address srcAddr;
Address dstAddr;
Neighbor * neighbor = nullptr;
KeyManager &keyManager = Get<KeyManager>();
const Key * macKey;
Error error = kErrorSecurity;
uint8_t securityLevel;
uint8_t txKeyId;
uint8_t ackKeyId;
uint8_t keyIdMode;
uint32_t frameCounter;
Address srcAddr;
Address dstAddr;
Neighbor * neighbor = nullptr;
KeyManager & keyManager = Get<KeyManager>();
const KeyMaterial *macKey;
VerifyOrExit(aAckFrame.GetSecurityEnabled(), error = kErrorNone);
VerifyOrExit(aAckFrame.IsVersion2015());
+2 -1
View File
@@ -842,7 +842,6 @@ private:
#endif
static const char *OperationToString(Operation aOperation);
static const otMacKey sMode2Key;
static const otExtAddress sMode2ExtAddress;
static const otExtendedPanId sExtendedPanidInit;
static const char sNetworkNameInit[];
@@ -923,6 +922,8 @@ private:
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
Filter mFilter;
#endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
KeyMaterial mMode2KeyMaterial;
};
/**
+1 -1
View File
@@ -1329,7 +1329,7 @@ exit:
}
#endif // OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2
Error RxFrame::ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const Key &aMacKey)
Error RxFrame::ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey)
{
#if OPENTHREAD_RADIO
OT_UNUSED_VARIABLE(aExtAddress);
+6 -3
View File
@@ -1166,7 +1166,7 @@ public:
* @retval kErrorSecurity Received frame MIC check failed.
*
*/
Error ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const Key &aMacKey);
Error ProcessReceiveAesCcm(const ExtAddress &aExtAddress, const KeyMaterial &aMacKey);
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
/**
@@ -1281,7 +1281,10 @@ public:
* @returns The pointer to the key.
*
*/
const Mac::Key &GetAesKey(void) const { return *static_cast<const Mac::Key *>(mInfo.mTxInfo.mAesKey); }
const Mac::KeyMaterial &GetAesKey(void) const
{
return *static_cast<const Mac::KeyMaterial *>(mInfo.mTxInfo.mAesKey);
}
/**
* This method sets the key used for frame encryption and authentication (AES CCM).
@@ -1289,7 +1292,7 @@ public:
* @param[in] aAesKey The pointer to the key.
*
*/
void SetAesKey(const Mac::Key &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; }
void SetAesKey(const Mac::KeyMaterial &aAesKey) { mInfo.mTxInfo.mAesKey = &aAesKey; }
/**
* This method copies the PSDU and all attributes (except for frame link type) from another frame.
+4 -4
View File
@@ -172,11 +172,11 @@ void Links::Send(TxFrame &aFrame, RadioTypes aRadioTypes)
#endif // #if OPENTHREAD_CONFIG_MULTI_RADIO
const Key *Links::GetCurrentMacKey(const Frame &aFrame) const
const KeyMaterial *Links::GetCurrentMacKey(const Frame &aFrame) const
{
// Gets the security MAC key (for Key Mode 1) based on radio link type of `aFrame`.
const Key *key = nullptr;
const KeyMaterial *key = nullptr;
#if OPENTHREAD_CONFIG_MULTI_RADIO
RadioType radioType = aFrame.GetRadioType();
#endif
@@ -205,12 +205,12 @@ exit:
return key;
}
const Key *Links::GetTemporaryMacKey(const Frame &aFrame, uint32_t aKeySequence) const
const KeyMaterial *Links::GetTemporaryMacKey(const Frame &aFrame, uint32_t aKeySequence) const
{
// Gets the security MAC key (for Key Mode 1) based on radio link
// type of `aFrame` and given Key Sequence.
const Key *key = nullptr;
const KeyMaterial *key = nullptr;
#if OPENTHREAD_CONFIG_MULTI_RADIO
RadioType radioType = aFrame.GetRadioType();
#endif
+2 -2
View File
@@ -633,7 +633,7 @@ public:
* @returns A reference to the current MAC key.
*
*/
const Key *GetCurrentMacKey(const Frame &aFrame) const;
const KeyMaterial *GetCurrentMacKey(const Frame &aFrame) const;
/**
* This method returns a reference to the temporary MAC key (for Key Mode 1) for a given Frame based on a given
@@ -645,7 +645,7 @@ public:
* @returns A reference to the temporary MAC key.
*
*/
const Key *GetTemporaryMacKey(const Frame &aFrame, uint32_t aKeySequence) const;
const KeyMaterial *GetTemporaryMacKey(const Frame &aFrame, uint32_t aKeySequence) const;
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
/**
+93
View File
@@ -334,5 +334,98 @@ void LinkFrameCounters::SetAll(uint32_t aCounter)
#endif
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
KeyMaterial &KeyMaterial::operator=(const KeyMaterial &aOther)
{
VerifyOrExit(GetKeyRef() != aOther.GetKeyRef());
DestroyKey();
SetKeyRef(aOther.GetKeyRef());
exit:
return *this;
}
#endif
void KeyMaterial::Clear(void)
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
DestroyKey();
SetKeyRef(kInvalidKeyRef);
#else
GetKey().Clear();
#endif
}
void KeyMaterial::SetFrom(const Key &aKey, bool aIsExportable)
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
{
Error error;
KeyRef keyRef = 0;
DestroyKey();
error = Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeAes, Crypto::Storage::kKeyAlgorithmAesEcb,
(aIsExportable ? Crypto::Storage::kUsageExport : 0) |
Crypto::Storage::kUsageEncrypt | Crypto::Storage::kUsageDecrypt,
Crypto::Storage::kTypeVolatile, aKey.GetBytes(), Key::kSize);
OT_ASSERT(error == kErrorNone);
OT_UNUSED_VARIABLE(error);
SetKeyRef(keyRef);
}
#else
SetKey(aKey);
OT_UNUSED_VARIABLE(aIsExportable);
#endif
}
void KeyMaterial::ExtractKey(Key &aKey)
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
aKey.Clear();
if (Crypto::Storage::IsKeyRefValid(GetKeyRef()))
{
Error error;
size_t keySize;
error = Crypto::Storage::ExportKey(GetKeyRef(), aKey.m8, Key::kSize, keySize);
OT_ASSERT(error == kErrorNone);
OT_UNUSED_VARIABLE(error);
}
#else
aKey = GetKey();
#endif
}
void KeyMaterial::ConvertToCryptoKey(Crypto::Key &aCryptoKey) const
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
aCryptoKey.SetAsKeyRef(GetKeyRef());
#else
aCryptoKey.Set(GetKey().GetBytes(), Key::kSize);
#endif
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
void KeyMaterial::DestroyKey(void)
{
Crypto::Storage::DestroyKey(GetKeyRef());
SetKeyRef(kInvalidKeyRef);
}
#endif
bool KeyMaterial::operator==(const KeyMaterial &aOther) const
{
return
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
(GetKeyRef() == aOther.GetKeyRef());
#else
(GetKey() == aOther.GetKey());
#endif
}
} // namespace Mac
} // namespace ot
+126 -3
View File
@@ -45,6 +45,7 @@
#include "common/clearable.hpp"
#include "common/equatable.hpp"
#include "common/string.hpp"
#include "crypto/storage.hpp"
namespace ot {
namespace Mac {
@@ -419,15 +420,137 @@ public:
static constexpr uint16_t kSize = OT_MAC_KEY_SIZE; ///< Key size in bytes.
/**
* This method gets a pointer to the buffer containing the key.
* This method gets a pointer to the bytes array containing the key
*
* @returns A pointer to the buffer containing the key.
* @returns A pointer to the byte array containing the key.
*
*/
const uint8_t *GetKey(void) const { return m8; }
const uint8_t *GetBytes(void) const { return m8; }
} OT_TOOL_PACKED_END;
/**
* This type represents a MAC Key Ref used by PSA.
*
*/
typedef otMacKeyRef KeyRef;
/**
* This class represents a MAC Key Material.
*
*/
OT_TOOL_PACKED_BEGIN
class KeyMaterial : public otMacKeyMaterial, public Unequatable<KeyMaterial>
{
public:
/**
* This constructor initializes a `KeyMaterial`.
*
*/
KeyMaterial(void)
{
GetKey().Clear();
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
SetKeyRef(kInvalidKeyRef);
#endif
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* This method overload `=` operator to assign the `KeyMaterial` from another one.
*
* If the `KeyMaterial` currently stores a valid and different `KeyRef`, the assignment of new value will ensure to
* delete the previous one before using the new `KeyRef` from @p aOther.
*
* @param[in] aOther aOther The other `KeyMaterial` instance to assign from.
*
* @returns A reference to the current `KeyMaterial`
*
*/
KeyMaterial &operator=(const KeyMaterial &aOther);
#endif
/**
* This method clears the `KeyMaterial`.
*
* Under `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE`, if the `KeyMaterial` currently stores a valid previous
* `KeyRef`, the `Clear()` call will ensure to delete the previous `KeyRef` and set it to `kInvalidKeyRef`.
*
*/
void Clear(void);
#if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* This method gets the literal `Key`.
*
* @returns The literal `Key`
*
*/
const Key &GetKey(void) const { return static_cast<const Key &>(mKeyMaterial.mKey); }
#else
/**
* This method gets the stored `KeyRef`
*
* @returns The `KeyRef`
*
*/
KeyRef GetKeyRef(void) const { return mKeyMaterial.mKeyRef; }
#endif
/**
* This method sets the `KeyMaterial` from a given Key.
*
* If the `KeyMaterial` currently stores a valid `KeyRef`, the `SetFrom()` call will ensure to delete the previous
* one before creating and using a new `KeyRef` associated with the new `Key`.
*
* @param[in] aKey A reference to the new key.
* @param[in] aIsExportable Boolean indicating if the key is exportable (this is only applicable under
* `OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE` config).
*
*/
void SetFrom(const Key &aKey, bool aIsExportable = false);
/**
* This method extracts the literal key from `KeyMaterial`
*
* @param[out] aKey A reference to the output the key.
*
*/
void ExtractKey(Key &aKey);
/**
* This method converts `KeyMaterial` to a `Crypto::Key`.
*
* @param[out] A reference to a `Crypto::Key` to populate.
*
*/
void ConvertToCryptoKey(Crypto::Key &aCryptoKey) const;
/**
* This method overloads operator `==` to evaluate whether or not two `KeyMaterial` instances are equal.
*
* @param[in] aOther The other `KeyMaterial` instance to compare with.
*
* @retval TRUE If the two `KeyMaterial` instances are equal.
* @retval FALSE If the two `KeyMaterial` instances are not equal.
*
*/
bool operator==(const KeyMaterial &aOther) const;
KeyMaterial(const KeyMaterial &) = delete;
private:
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
static constexpr KeyRef kInvalidKeyRef = Crypto::Storage::kInvalidKeyRef;
void DestroyKey(void);
void SetKeyRef(KeyRef aKeyRef) { mKeyMaterial.mKeyRef = aKeyRef; }
#endif
Key &GetKey(void) { return static_cast<Key &>(mKeyMaterial.mKey); }
void SetKey(const Key &aKey) { mKeyMaterial.mKey = aKey; }
} OT_TOOL_PACKED_END;
/**
* This structure represents an IEEE 802.15.4 Extended PAN Identifier.
*
+5 -8
View File
@@ -78,9 +78,6 @@ SubMac::SubMac(Instance &aInstance)
#endif
{
mExtAddress.Clear();
mPrevKey.Clear();
mCurrKey.Clear();
mNextKey.Clear();
}
otRadioCaps SubMac::GetCaps(void) const
@@ -832,11 +829,11 @@ void SubMac::SetState(State aState)
}
}
void SubMac::SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const Key &aPrevKey,
const Key &aCurrKey,
const Key &aNextKey)
void SubMac::SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const KeyMaterial &aPrevKey,
const KeyMaterial &aCurrKey,
const KeyMaterial &aNextKey)
{
switch (aKeyIdMode)
{
+13 -7
View File
@@ -38,6 +38,8 @@
#include <openthread/link.h>
#include <openthread/platform/crypto.h>
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "common/timer.hpp"
@@ -492,7 +494,11 @@ public:
* @param[in] aNextKey The next MAC key.
*
*/
void SetMacKey(uint8_t aKeyIdMode, uint8_t aKeyId, const Key &aPrevKey, const Key &aCurrKey, const Key &aNextKey);
void SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const KeyMaterial &aPrevKey,
const KeyMaterial &aCurrKey,
const KeyMaterial &aNextKey);
/**
* This method returns a reference to the current MAC key.
@@ -500,7 +506,7 @@ public:
* @returns A reference to the current MAC key.
*
*/
const Key &GetCurrentMacKey(void) const { return mCurrKey; }
const KeyMaterial &GetCurrentMacKey(void) const { return mCurrKey; }
/**
* This method returns a reference to the previous MAC key.
@@ -508,7 +514,7 @@ public:
* @returns A reference to the previous MAC key.
*
*/
const Key &GetPreviousMacKey(void) const { return mPrevKey; }
const KeyMaterial &GetPreviousMacKey(void) const { return mPrevKey; }
/**
* This method returns a reference to the next MAC key.
@@ -516,7 +522,7 @@ public:
* @returns A reference to the next MAC key.
*
*/
const Key &GetNextMacKey(void) const { return mNextKey; }
const KeyMaterial &GetNextMacKey(void) const { return mNextKey; }
/**
* This method returns the current MAC frame counter value.
@@ -642,9 +648,9 @@ private:
Callbacks mCallbacks;
otLinkPcapCallback mPcapCallback;
void * mPcapCallbackContext;
Key mPrevKey;
Key mCurrKey;
Key mNextKey;
KeyMaterial mPrevKey;
KeyMaterial mCurrKey;
KeyMaterial mNextKey;
uint32_t mFrameCounter;
uint8_t mKeyId;
#if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
+5 -1
View File
@@ -583,11 +583,15 @@ void BorderAgent::Start(void)
{
Error error;
Coap::CoapSecure &coaps = Get<Coap::CoapSecure>();
Pskc pskc;
VerifyOrExit(mState == kStateStopped, error = kErrorAlready);
Get<KeyManager>().GetPskc(pskc);
SuccessOrExit(error = coaps.Start(kBorderAgentUdpPort));
SuccessOrExit(error = coaps.SetPsk(Get<KeyManager>().GetPskc().m8, OT_PSKC_MAX_SIZE));
SuccessOrExit(error = coaps.SetPsk(pskc.m8, Pskc::kSize));
pskc.Clear();
coaps.SetConnectedCallback(HandleConnected, this);
coaps.AddResource(mActiveGet);
+4 -1
View File
@@ -1163,9 +1163,12 @@ Error Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo
Coap::Message * message;
uint16_t offset;
Ip6::MessageInfo messageInfo;
Kek kek;
VerifyOrExit((message = NewMeshCoPMessage(Get<Tmf::Agent>())) != nullptr, error = kErrorNoBufs);
Get<KeyManager>().ExtractKek(kek);
message->InitAsNonConfirmablePost();
SuccessOrExit(error = message->AppendUriPathOptions(UriPath::kRelayTx));
SuccessOrExit(error = message->SetPayloadMarker());
@@ -1176,7 +1179,7 @@ Error Commissioner::SendRelayTransmit(Message &aMessage, const Ip6::MessageInfo
if (aMessage.GetSubType() == Message::kSubTypeJoinerFinalizeResponse)
{
SuccessOrExit(error = Tlv::Append<JoinerRouterKekTlv>(*message, Get<KeyManager>().GetKek()));
SuccessOrExit(error = Tlv::Append<JoinerRouterKekTlv>(*message, kek));
}
tlv.SetType(Tlv::kJoinerDtlsEncapsulation);
+5 -2
View File
@@ -564,13 +564,16 @@ Error Dataset::ApplyConfiguration(Instance &aInstance, bool *aIsNetworkKeyUpdate
case Tlv::kNetworkKey:
{
const NetworkKeyTlv *key = static_cast<const NetworkKeyTlv *>(cur);
NetworkKey networkKey;
if (aIsNetworkKeyUpdated && (key->GetNetworkKey() != keyManager.GetNetworkKey()))
keyManager.GetNetworkKey(networkKey);
if (aIsNetworkKeyUpdated && (key->GetNetworkKey() != networkKey))
{
*aIsNetworkKeyUpdated = true;
}
IgnoreError(keyManager.SetNetworkKey(key->GetNetworkKey()));
keyManager.SetNetworkKey(key->GetNetworkKey());
break;
}
+15 -9
View File
@@ -154,9 +154,12 @@ Error DatasetManager::HandleSet(Coap::Message &aMessage, const Ip6::MessageInfo
// check network key
if (Tlv::Find<NetworkKeyTlv>(aMessage, networkKey) == kErrorNone)
{
hasNetworkKey = true;
NetworkKey localNetworkKey;
if (networkKey != Get<KeyManager>().GetNetworkKey())
hasNetworkKey = true;
Get<KeyManager>().GetNetworkKey(localNetworkKey);
if (networkKey != localNetworkKey)
{
doesAffectConnectivity = true;
doesAffectNetworkKey = true;
@@ -164,7 +167,7 @@ Error DatasetManager::HandleSet(Coap::Message &aMessage, const Ip6::MessageInfo
}
// check active timestamp rollback
if (type == Tlv::kPendingTimestamp && (!hasNetworkKey || (networkKey == Get<KeyManager>().GetNetworkKey())))
if (type == Tlv::kPendingTimestamp && (!hasNetworkKey || !doesAffectNetworkKey))
{
// no change to network key, active timestamp must be ahead
const Timestamp *localActiveTimestamp = Get<ActiveDataset>().GetTimestamp();
@@ -353,7 +356,10 @@ Error ActiveDataset::GenerateLocal(void)
if (dataset.GetTlv<NetworkKeyTlv>() == nullptr)
{
IgnoreError(dataset.SetTlv(Tlv::kNetworkKey, Get<KeyManager>().GetNetworkKey()));
NetworkKey networkKey;
Get<KeyManager>().GetNetworkKey(networkKey);
IgnoreError(dataset.SetTlv(Tlv::kNetworkKey, networkKey));
}
if (dataset.GetTlv<NetworkNameTlv>() == nullptr)
@@ -370,18 +376,18 @@ Error ActiveDataset::GenerateLocal(void)
if (dataset.GetTlv<PskcTlv>() == nullptr)
{
Pskc pskc;
if (Get<KeyManager>().IsPskcSet())
{
IgnoreError(dataset.SetTlv(Tlv::kPskc, Get<KeyManager>().GetPskc()));
Get<KeyManager>().GetPskc(pskc);
}
else
{
// PSKc has not yet been configured, generate new PSKc at random
Pskc pskc;
SuccessOrExit(error = pskc.GenerateRandom());
IgnoreError(dataset.SetTlv(Tlv::kPskc, pskc));
}
IgnoreError(dataset.SetTlv(Tlv::kPskc, pskc));
}
if (dataset.GetTlv<SecurityPolicyTlv>() == nullptr)
+3 -2
View File
@@ -314,9 +314,9 @@ Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
Error error;
Coap::Message *message = nullptr;
Dataset dataset;
NetworkNameTlv networkName;
const Tlv * tlv;
NetworkKey networkKey;
VerifyOrExit((message = NewMeshCoPMessage(Get<Tmf::Agent>())) != nullptr, error = kErrorNoBufs);
@@ -325,7 +325,8 @@ Coap::Message *JoinerRouter::PrepareJoinerEntrustMessage(void)
SuccessOrExit(error = message->SetPayloadMarker());
message->SetSubType(Message::kSubTypeJoinerEntrust);
SuccessOrExit(error = Tlv::Append<NetworkKeyTlv>(*message, Get<KeyManager>().GetNetworkKey()));
Get<KeyManager>().GetNetworkKey(networkKey);
SuccessOrExit(error = Tlv::Append<NetworkKeyTlv>(*message, networkKey));
SuccessOrExit(error = Tlv::Append<MeshLocalPrefixTlv>(*message, Get<Mle::MleRouter>().GetMeshLocalPrefix()));
SuccessOrExit(error = Tlv::Append<ExtendedPanIdTlv>(*message, Get<Mac::Mac>().GetExtendedPanId()));
+3
View File
@@ -56,6 +56,9 @@ target_sources(openthread-radio PRIVATE
common/uptime.cpp
crypto/aes_ccm.cpp
crypto/aes_ecb.cpp
crypto/crypto_platform.cpp
crypto/hmac_sha256.cpp
crypto/storage.cpp
diags/factory_diags.cpp
mac/link_raw.cpp
mac/mac_frame.cpp
+25 -12
View File
@@ -38,6 +38,7 @@
#include <openthread/platform/radio.h>
#include <openthread/platform/crypto.h>
#include "common/locator.hpp"
#include "common/non_copyable.hpp"
#include "mac/mac_frame.hpp"
@@ -277,11 +278,11 @@ public:
* @param[in] aNextKey The next MAC key.
*
*/
void SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const Mac::Key &aPrevKey,
const Mac::Key &aCurrKey,
const Mac::Key &aNextKey);
void SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const Mac::KeyMaterial &aPrevKey,
const Mac::KeyMaterial &aCurrKey,
const Mac::KeyMaterial &aNextKey);
/**
* This method sets the current MAC Frame Counter value.
@@ -704,13 +705,21 @@ inline void Radio::SetPanId(Mac::PanId aPanId)
otPlatRadioSetPanId(GetInstancePtr(), aPanId);
}
inline void Radio::SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const Mac::Key &aPrevKey,
const Mac::Key &aCurrKey,
const Mac::Key &aNextKey)
inline void Radio::SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const Mac::KeyMaterial &aPrevKey,
const Mac::KeyMaterial &aCurrKey,
const Mac::KeyMaterial &aNextKey)
{
otPlatRadioSetMacKey(GetInstancePtr(), aKeyIdMode, aKeyId, &aPrevKey, &aCurrKey, &aNextKey);
otRadioKeyType aKeyType;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
aKeyType = OT_KEY_TYPE_KEY_REF;
#else
aKeyType = OT_KEY_TYPE_LITERAL_KEY;
#endif
otPlatRadioSetMacKey(GetInstancePtr(), aKeyIdMode, aKeyId, &aPrevKey, &aCurrKey, &aNextKey, aKeyType);
}
inline Error Radio::GetTransmitPower(int8_t &aPower)
@@ -876,7 +885,11 @@ inline void Radio::SetShortAddress(Mac::ShortAddress)
{
}
inline void Radio::SetMacKey(uint8_t, uint8_t, const Mac::Key &, const Mac::Key &, const Mac::Key &)
inline void Radio::SetMacKey(uint8_t,
uint8_t,
const Mac::KeyMaterial &,
const Mac::KeyMaterial &,
const Mac::KeyMaterial &)
{
}
+8 -6
View File
@@ -202,12 +202,13 @@ 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,
const otMacKey *aPrevKey,
const otMacKey *aCurrKey,
const otMacKey *aNextKey)
OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey,
otRadioKeyType aKeyType)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aKeyIdMode);
@@ -215,6 +216,7 @@ OT_TOOL_WEAK void otPlatRadioSetMacKey(otInstance * aInstance,
OT_UNUSED_VARIABLE(aPrevKey);
OT_UNUSED_VARIABLE(aCurrKey);
OT_UNUSED_VARIABLE(aNextKey);
OT_UNUSED_VARIABLE(aKeyType);
}
OT_TOOL_WEAK void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+241 -42
View File
@@ -39,6 +39,7 @@
#include "common/locator_getters.hpp"
#include "common/timer.hpp"
#include "crypto/hkdf_sha256.hpp"
#include "crypto/storage.hpp"
#include "thread/mle_router.hpp"
#include "thread/thread_netif.hpp"
@@ -179,13 +180,24 @@ KeyManager::KeyManager(Instance &aInstance)
, mKekFrameCounter(0)
, mIsPskcSet(false)
{
Error error = mNetworkKey.GenerateRandom();
IgnoreError(otPlatCryptoInit());
OT_ASSERT(error == kErrorNone);
OT_UNUSED_VARIABLE(error);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
{
NetworkKey networkKey;
mNetworkKeyRef = Crypto::Storage::kInvalidKeyRef;
mPskcRef = Crypto::Storage::kInvalidKeyRef;
IgnoreError(networkKey.GenerateRandom());
StoreNetworkKey(networkKey, /* aOverWriteExisting */ false);
}
#else
IgnoreError(mNetworkKey.GenerateRandom());
mPskc.Clear();
#endif
mMacFrameCounters.Reset();
mPskc.Clear();
}
void KeyManager::Start(void)
@@ -199,24 +211,31 @@ void KeyManager::Stop(void)
mKeyRotationTimer.Stop();
}
#if OPENTHREAD_MTD || OPENTHREAD_FTD
void KeyManager::SetPskc(const Pskc &aPskc)
{
IgnoreError(Get<Notifier>().Update(mPskc, aPskc, kEventPskcChanged));
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
if (Crypto::Storage::IsKeyRefValid(mPskcRef))
{
Pskc pskc;
GetPskc(pskc);
VerifyOrExit(aPskc != pskc, Get<Notifier>().SignalIfFirst(kEventPskcChanged));
}
StorePskc(aPskc);
Get<Notifier>().Signal(kEventPskcChanged);
#else
SuccessOrExit(Get<Notifier>().Update(mPskc, aPskc, kEventPskcChanged));
#endif
exit:
mIsPskcSet = true;
}
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
Error KeyManager::SetNetworkKey(const NetworkKey &aKey)
void KeyManager::ResetFrameCounters(void)
{
Error error = kErrorNone;
Router *parent;
SuccessOrExit(Get<Notifier>().Update(mNetworkKey, aKey, kEventNetworkKeyChanged));
Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
mKeySequence = 0;
UpdateKeyMaterial();
// reset parent frame counters
parent = &Get<Mle::MleRouter>().GetParent();
parent->SetKeySequence(0);
@@ -243,17 +262,48 @@ Error KeyManager::SetNetworkKey(const NetworkKey &aKey)
child.SetMleFrameCounter(0);
}
#endif
}
void KeyManager::SetNetworkKey(const NetworkKey &aNetworkKey)
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
if (Crypto::Storage::IsKeyRefValid(mNetworkKeyRef))
{
NetworkKey networkKey;
GetNetworkKey(networkKey);
VerifyOrExit(networkKey != aNetworkKey, Get<Notifier>().SignalIfFirst(kEventNetworkKeyChanged));
}
StoreNetworkKey(aNetworkKey, /* aOverWriteExisting */ true);
Get<Notifier>().Signal(kEventNetworkKeyChanged);
#else
SuccessOrExit(Get<Notifier>().Update(mNetworkKey, aNetworkKey, kEventNetworkKeyChanged));
#endif
Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
mKeySequence = 0;
UpdateKeyMaterial();
ResetFrameCounters();
exit:
return error;
return;
}
void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
{
Crypto::HmacSha256 hmac;
uint8_t keySequenceBytes[sizeof(uint32_t)];
Crypto::Key cryptoKey;
hmac.Start(mNetworkKey.m8, sizeof(mNetworkKey.m8));
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
cryptoKey.SetAsKeyRef(mNetworkKeyRef);
#else
cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
#endif
hmac.Start(cryptoKey);
Encoding::BigEndian::WriteUint32(aKeySequence, keySequenceBytes);
hmac.Update(keySequenceBytes);
@@ -263,40 +313,59 @@ void KeyManager::ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys)
}
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aTrelKey)
void KeyManager::ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey)
{
Crypto::HkdfSha256 hkdf;
uint8_t salt[sizeof(uint32_t) + sizeof(kHkdfExtractSaltString)];
Crypto::Key cryptoKey;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
cryptoKey.SetAsKeyRef(mNetworkKeyRef);
#else
cryptoKey.Set(mNetworkKey.m8, NetworkKey::kSize);
#endif
Encoding::BigEndian::WriteUint32(aKeySequence, salt);
memcpy(salt + sizeof(uint32_t), kHkdfExtractSaltString, sizeof(kHkdfExtractSaltString));
hkdf.Extract(salt, sizeof(salt), mNetworkKey.m8, sizeof(NetworkKey));
hkdf.Expand(kTrelInfoString, sizeof(kTrelInfoString), aTrelKey.m8, sizeof(Mac::Key));
hkdf.Extract(salt, sizeof(salt), cryptoKey);
hkdf.Expand(kTrelInfoString, sizeof(kTrelInfoString), aKey.m8, Mac::Key::kSize);
}
#endif
void KeyManager::UpdateKeyMaterial(void)
{
HashKeys cur;
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
HashKeys prev;
HashKeys next;
#endif
HashKeys hashKeys;
ComputeKeys(mKeySequence, cur);
mMleKey = cur.mKeys.mMleKey;
ComputeKeys(mKeySequence, hashKeys);
mMleKey.SetFrom(hashKeys.GetMleKey());
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
ComputeKeys(mKeySequence - 1, prev);
ComputeKeys(mKeySequence + 1, next);
{
Mac::KeyMaterial curKey;
Mac::KeyMaterial prevKey;
Mac::KeyMaterial nextKey;
Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prev.mKeys.mMacKey,
cur.mKeys.mMacKey, next.mKeys.mMacKey);
curKey.SetFrom(hashKeys.GetMacKey());
ComputeKeys(mKeySequence - 1, hashKeys);
prevKey.SetFrom(hashKeys.GetMacKey());
ComputeKeys(mKeySequence + 1, hashKeys);
nextKey.SetFrom(hashKeys.GetMacKey());
Get<Mac::SubMac>().SetMacKey(Mac::Frame::kKeyIdMode1, (mKeySequence & 0x7f) + 1, prevKey, curKey, nextKey);
}
#endif
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
ComputeTrelKey(mKeySequence, mTrelKey);
{
Mac::Key key;
ComputeTrelKey(mKeySequence, key);
mTrelKey.SetFrom(key);
}
#endif
}
@@ -328,20 +397,23 @@ exit:
return;
}
const Mle::Key &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
const Mle::KeyMaterial &KeyManager::GetTemporaryMleKey(uint32_t aKeySequence)
{
HashKeys hashKeys;
ComputeKeys(aKeySequence, hashKeys);
mTemporaryMleKey = hashKeys.mKeys.mMleKey;
mTemporaryMleKey.SetFrom(hashKeys.GetMleKey());
return mTemporaryMleKey;
}
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
const Mac::Key &KeyManager::GetTemporaryTrelMacKey(uint32_t aKeySequence)
const Mac::KeyMaterial &KeyManager::GetTemporaryTrelMacKey(uint32_t aKeySequence)
{
ComputeTrelKey(aKeySequence, mTemporaryTrelKey);
Mac::Key key;
ComputeTrelKey(aKeySequence, key);
mTemporaryTrelKey.SetFrom(key);
return mTemporaryTrelKey;
}
@@ -396,13 +468,7 @@ void KeyManager::IncrementMleFrameCounter(void)
void KeyManager::SetKek(const Kek &aKek)
{
mKek = aKek;
mKekFrameCounter = 0;
}
void KeyManager::SetKek(const uint8_t *aKek)
{
memcpy(mKek.m8, aKek, sizeof(mKek));
mKek.SetFrom(aKek, /* aIsExportable */ true);
mKekFrameCounter = 0;
}
@@ -443,4 +509,137 @@ void KeyManager::HandleKeyRotationTimer(void)
}
}
void KeyManager::GetNetworkKey(NetworkKey &aNetworkKey) const
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
if (Crypto::Storage::IsKeyRefValid(mNetworkKeyRef))
{
Error error = kErrorNone;
size_t keyLen;
error = Crypto::Storage::ExportKey(mNetworkKeyRef, aNetworkKey.m8, NetworkKey::kSize, keyLen);
OT_ASSERT(error == kErrorNone);
OT_ASSERT(keyLen == NetworkKey::kSize);
OT_UNUSED_VARIABLE(error);
}
else
{
aNetworkKey.Clear();
}
#else
aNetworkKey = mNetworkKey;
#endif
}
void KeyManager::GetPskc(Pskc &aPskc) const
{
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
if (Crypto::Storage::IsKeyRefValid(mPskcRef))
{
Error error = kErrorNone;
size_t keyLen;
error = Crypto::Storage::ExportKey(mPskcRef, aPskc.m8, Pskc::kSize, keyLen);
OT_ASSERT(error == kErrorNone);
OT_ASSERT(keyLen == Pskc::kSize);
OT_UNUSED_VARIABLE(error);
}
else
{
aPskc.Clear();
}
#else
aPskc = mPskc;
#endif
}
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
void KeyManager::StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting)
{
Error error;
NetworkKeyRef keyRef;
keyRef = kNetworkKeyPsaItsOffset;
if (!aOverWriteExisting)
{
// Check if there is already a network key stored in ITS. If
// stored, and we are not overwriting the existing key,
// return without doing anything.
if (Crypto::Storage::HasKey(keyRef))
{
ExitNow();
}
}
Crypto::Storage::DestroyKey(keyRef);
error = Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeHmac, Crypto::Storage::kKeyAlgorithmHmacSha256,
Crypto::Storage::kUsageSignHash | Crypto::Storage::kUsageExport,
Crypto::Storage::kTypePersistent, aNetworkKey.m8, NetworkKey::kSize);
OT_ASSERT(error == kErrorNone);
exit:
if (mNetworkKeyRef != keyRef)
{
Crypto::Storage::DestroyKey(mNetworkKeyRef);
}
mNetworkKeyRef = keyRef;
}
void KeyManager::StorePskc(const Pskc &aPskc)
{
PskcRef keyRef = kPskcPsaItsOffset;
Error error = kErrorNone;
Crypto::Storage::DestroyKey(keyRef);
error = Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeRaw, Crypto::Storage::kKeyAlgorithmVendor,
Crypto::Storage::kUsageExport, Crypto::Storage::kTypePersistent, aPskc.m8,
Pskc::kSize);
OT_ASSERT(error == kErrorNone);
OT_UNUSED_VARIABLE(error);
if (mPskcRef != keyRef)
{
Crypto::Storage::DestroyKey(mPskcRef);
}
mPskcRef = keyRef;
}
void KeyManager::SetPskcRef(PskcRef aKeyRef)
{
VerifyOrExit(mPskcRef != aKeyRef, Get<Notifier>().SignalIfFirst(kEventPskcChanged));
Crypto::Storage::DestroyKey(mPskcRef);
mPskcRef = aKeyRef;
Get<Notifier>().Signal(kEventPskcChanged);
exit:
mIsPskcSet = true;
}
void KeyManager::SetNetworkKeyRef(otNetworkKeyRef aKeyRef)
{
VerifyOrExit(mNetworkKeyRef != aKeyRef, Get<Notifier>().SignalIfFirst(kEventNetworkKeyChanged));
Crypto::Storage::DestroyKey(mNetworkKeyRef);
mNetworkKeyRef = aKeyRef;
Get<Notifier>().Signal(kEventNetworkKeyChanged);
Get<Notifier>().Signal(kEventThreadKeySeqCounterChanged);
mKeySequence = 0;
UpdateKeyMaterial();
ResetFrameCounters();
exit:
return;
}
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
} // namespace ot
+123 -36
View File
@@ -40,6 +40,7 @@
#include <openthread/dataset.h>
#include <openthread/platform/crypto.h>
#include "common/clearable.hpp"
#include "common/encoding.hpp"
#include "common/equatable.hpp"
@@ -133,9 +134,11 @@ private:
*
*/
OT_TOOL_PACKED_BEGIN
class NetworkKey : public otNetworkKey, public Equatable<NetworkKey>
class NetworkKey : public otNetworkKey, public Equatable<NetworkKey>, public Clearable<NetworkKey>
{
public:
static constexpr uint8_t kSize = OT_NETWORK_KEY_SIZE; ///< Size of the Thread Network Key (in bytes).
#if !OPENTHREAD_RADIO
/**
* This method generates a cryptographically secure random sequence to populate the Thread Network Key.
@@ -146,8 +149,17 @@ public:
*/
Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); }
#endif
} OT_TOOL_PACKED_END;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* Provides a representation for Network Key reference.
*
*/
typedef otNetworkKeyRef NetworkKeyRef;
#endif
/**
* This class represents a Thread Pre-Shared Key for the Commissioner (PSKc).
*
@@ -156,6 +168,8 @@ OT_TOOL_PACKED_BEGIN
class Pskc : public otPskc, public Equatable<Pskc>, public Clearable<Pskc>
{
public:
static constexpr uint8_t kSize = OT_PSKC_MAX_SIZE; ///< Size (number of bytes) of the PSKc.
#if !OPENTHREAD_RADIO
/**
* This method generates a cryptographically secure random sequence to populate the Thread PSKc.
@@ -163,11 +177,18 @@ public:
* @retval kErrorNone Successfully generated a random Thread PSKc.
*
*/
Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(Pskc)); }
Error GenerateRandom(void) { return Random::Crypto::FillBuffer(m8, sizeof(m8)); }
#endif
} OT_TOOL_PACKED_END;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* Provides a representation for Network Key reference.
*
*/
typedef otPskcRef PskcRef;
#endif
/**
*
* This class represents a Key Encryption Key (KEK).
@@ -175,6 +196,13 @@ public:
*/
typedef Mac::Key Kek;
/**
*
* This class represents a Key Material for Key Encryption Key (KEK).
*
*/
typedef Mac::KeyMaterial KekKeyMaterial;
/**
* This class defines Thread Key Manager.
*
@@ -182,6 +210,9 @@ typedef Mac::Key Kek;
class KeyManager : public InstanceLocator, private NonCopyable
{
public:
static constexpr uint32_t kNetworkKeyPsaItsOffset = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 1;
static constexpr uint32_t kPskcPsaItsOffset = OPENTHREAD_CONFIG_PSA_ITS_NVM_OFFSET + 2;
/**
* This constructor initializes the object.
*
@@ -203,25 +234,39 @@ public:
void Stop(void);
/**
* This method returns the Thread Network Key.
* This method gets the Thread Network Key.
*
* @returns The Thread Network Key.
* @param[out] aNetworkKey A reference to a `NetworkKey` to output the Thread Network Key.
*
*/
const NetworkKey &GetNetworkKey(void) const { return mNetworkKey; }
void GetNetworkKey(NetworkKey &aNetworkKey) const;
/**
* This method sets the Thread Network Key.
*
* @param[in] aKey A Thread Network Key.
*
* @retval kErrorNone Successfully set the Thread Network Key.
* @retval kErrorInvalidArgs The @p aKeyLength value was invalid.
* @param[in] aNetworkKey A Thread Network Key.
*
*/
Error SetNetworkKey(const NetworkKey &aKey);
void SetNetworkKey(const NetworkKey &aNetworkKey);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* This method returns a Key Ref to Thread Network Key.
*
* @returns A key reference to the Thread Network Key.
*
*/
NetworkKeyRef GetNetworkKeyRef(void) { return mNetworkKeyRef; }
/**
* This method sets the Thread Network Key using Key Reference.
*
* @param[in] aKeyRef Reference to Thread Network Key.
*
*/
void SetNetworkKeyRef(NetworkKeyRef aKeyRef);
#endif
#if OPENTHREAD_FTD || OPENTHREAD_MTD
/**
* This method indicates whether the PSKc is configured.
*
@@ -234,12 +279,12 @@ public:
bool IsPskcSet(void) const { return mIsPskcSet; }
/**
* This method returns a pointer to the PSKc.
* This method gets the PKSc.
*
* @returns A reference to the PSKc.
* @param[out] aPskc A reference to a `Pskc` to return the PSKc.
*
*/
const Pskc &GetPskc(void) const { return mPskc; }
void GetPskc(Pskc &aPskc) const;
/**
* This method sets the PSKc.
@@ -248,6 +293,23 @@ public:
*
*/
void SetPskc(const Pskc &aPskc);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
/**
* This method returns a Key Ref to PSKc.
*
* @returns A key reference to the PSKc.
*
*/
const PskcRef &GetPskcRef(void) { return mPskcRef; }
/**
* This method sets the PSKc as a Key reference.
*
* @param[in] aPskc A reference to the PSKc.
*
*/
void SetPskcRef(PskcRef aKeyRef);
#endif
/**
@@ -273,7 +335,7 @@ public:
* @returns The current TREL MAC key.
*
*/
const Mac::Key &GetCurrentTrelMacKey(void) const { return mTrelKey; }
const Mac::KeyMaterial &GetCurrentTrelMacKey(void) const { return mTrelKey; }
/**
* This method returns a temporary MAC key for TREL radio link computed from the given key sequence.
@@ -283,26 +345,26 @@ public:
* @returns The temporary TREL MAC key.
*
*/
const Mac::Key &GetTemporaryTrelMacKey(uint32_t aKeySequence);
const Mac::KeyMaterial &GetTemporaryTrelMacKey(uint32_t aKeySequence);
#endif
/**
* This method returns the current MLE key.
* This method returns the current MLE key Material.
*
* @returns The current MLE key.
*
*/
const Mle::Key &GetCurrentMleKey(void) const { return mMleKey; }
const Mle::KeyMaterial &GetCurrentMleKey(void) const { return mMleKey; }
/**
* This method returns a temporary MLE key computed from the given key sequence.
* This method returns a temporary MLE key Material computed from the given key sequence.
*
* @param[in] aKeySequence The key sequence value.
*
* @returns The temporary MLE key.
*
*/
const Mle::Key &GetTemporaryMleKey(uint32_t aKeySequence);
const Mle::KeyMaterial &GetTemporaryMleKey(uint32_t aKeySequence);
#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
/**
@@ -385,12 +447,20 @@ public:
void IncrementMleFrameCounter(void);
/**
* This method returns the KEK.
* This method returns the KEK as `KekKeyMaterail`
*
* @returns A pointer to the KEK.
* @returns The KEK as `KekKeyMaterial`.
*
*/
const Kek &GetKek(void) const { return mKek; }
const KekKeyMaterial &GetKek(void) const { return mKek; }
/**
* This method retrieves the KEK as literal `Kek` key.
*
* @param[out] aKek A reference to a `Kek` to output the retrieved KEK.
*
*/
void ExtractKek(Kek &aKek) { mKek.ExtractKey(aKek); }
/**
* This method sets the KEK.
@@ -403,10 +473,10 @@ public:
/**
* This method sets the KEK.
*
* @param[in] aKek A pointer to the KEK.
* @param[in] aKekBytes A pointer to the KEK bytes.
*
*/
void SetKek(const uint8_t *aKek);
void SetKek(const uint8_t *aKekBytes) { SetKek(*reinterpret_cast<const Kek *>(aKekBytes)); }
/**
* This method returns the current KEK Frame Counter value.
@@ -493,18 +563,28 @@ private:
{
Crypto::HmacSha256::Hash mHash;
Keys mKeys;
const Mle::Key &GetMleKey(void) const { return mKeys.mMleKey; }
const Mac::Key &GetMacKey(void) const { return mKeys.mMacKey; }
};
void ComputeKeys(uint32_t aKeySequence, HashKeys &aHashKeys);
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aTrelKey);
void ComputeTrelKey(uint32_t aKeySequence, Mac::Key &aKey);
#endif
void StartKeyRotationTimer(void);
static void HandleKeyRotationTimer(Timer &aTimer);
void HandleKeyRotationTimer(void);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
void StoreNetworkKey(const NetworkKey &aNetworkKey, bool aOverWriteExisting);
void StorePskc(const Pskc &aPskc);
#endif
void ResetFrameCounters(void);
static const uint8_t kThreadString[];
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
@@ -512,15 +592,19 @@ private:
static const uint8_t kTrelInfoString[];
#endif
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
NetworkKeyRef mNetworkKeyRef;
#else
NetworkKey mNetworkKey;
#endif
uint32_t mKeySequence;
Mle::Key mMleKey;
Mle::Key mTemporaryMleKey;
uint32_t mKeySequence;
Mle::KeyMaterial mMleKey;
Mle::KeyMaterial mTemporaryMleKey;
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
Mac::Key mTrelKey;
Mac::Key mTemporaryTrelKey;
Mac::KeyMaterial mTrelKey;
Mac::KeyMaterial mTemporaryTrelKey;
#endif
Mac::LinkFrameCounters mMacFrameCounters;
@@ -533,11 +617,14 @@ private:
bool mKeySwitchGuardEnabled;
TimerMilli mKeyRotationTimer;
#if OPENTHREAD_MTD || OPENTHREAD_FTD
Pskc mPskc;
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
PskcRef mPskcRef;
#else
Pskc mPskc;
#endif
Kek mKek;
uint32_t mKekFrameCounter;
KekKeyMaterial mKek;
uint32_t mKekFrameCounter;
SecurityPolicy mSecurityPolicy;
bool mIsPskcSet : 1;
+15 -15
View File
@@ -2675,21 +2675,21 @@ void Mle::HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageI
void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
Error error = kErrorNone;
Header header;
uint32_t keySequence;
const Key * mleKey;
uint32_t frameCounter;
uint8_t messageTag[kMleSecurityTagSize];
uint8_t nonce[Crypto::AesCcm::kNonceSize];
Mac::ExtAddress extAddr;
Crypto::AesCcm aesCcm;
uint16_t mleOffset;
uint8_t buf[64];
uint16_t length;
uint8_t tag[kMleSecurityTagSize];
uint8_t command;
Neighbor * neighbor;
Error error = kErrorNone;
Header header;
uint32_t keySequence;
const KeyMaterial *mleKey;
uint32_t frameCounter;
uint8_t messageTag[kMleSecurityTagSize];
uint8_t nonce[Crypto::AesCcm::kNonceSize];
Mac::ExtAddress extAddr;
Crypto::AesCcm aesCcm;
uint16_t mleOffset;
uint8_t buf[64];
uint16_t length;
uint8_t tag[kMleSecurityTagSize];
uint8_t command;
Neighbor * neighbor;
otLogDebgMle("Receive UDP message");
+7 -1
View File
@@ -571,7 +571,13 @@ private:
} OT_TOOL_PACKED_END;
/**
* This class represents a MLE key.
* This class represents a MLE Key Material
*
*/
typedef Mac::KeyMaterial KeyMaterial;
/**
* This class represents a MLE Key.
*
*/
typedef Mac::Key Key;
+9 -8
View File
@@ -628,20 +628,21 @@ public:
*
* @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.
* @param[in] aPrevKey Pointer to previous MAC key.
* @param[in] aCurrKey Pointer to current MAC key.
* @param[in] aNextKey Pointer to next MAC key.
*
* @retval OT_ERROR_NONE Succeeded.
* @retval OT_ERROR_INVALID_ARGS One of the keys passed is invalid..
* @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,
const otMacKey &aPrevKey,
const otMacKey &aCurrKey,
const otMacKey &aNextKey);
otError SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey);
/**
* This method sets the current MAC Frame Counter value.
+25 -10
View File
@@ -1134,26 +1134,41 @@ exit:
}
template <typename InterfaceType, typename ProcessContextType>
otError RadioSpinel<InterfaceType, ProcessContextType>::SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKey &aPrevKey,
const otMacKey &aCurrKey,
const otMacKey &aNextKey)
otError RadioSpinel<InterfaceType, ProcessContextType>::SetMacKey(uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey)
{
otError error;
size_t aKeySize;
VerifyOrExit((aPrevKey != nullptr) && (aCurrKey != nullptr) && (aNextKey != nullptr), error = kErrorInvalidArgs);
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
SuccessOrExit(error = otPlatCryptoExportKey(aPrevKey->mKeyMaterial.mKeyRef, aPrevKey->mKeyMaterial.mKey.m8,
sizeof(aPrevKey->mKeyMaterial.mKey.m8), &aKeySize));
SuccessOrExit(error = otPlatCryptoExportKey(aCurrKey->mKeyMaterial.mKeyRef, aCurrKey->mKeyMaterial.mKey.m8,
sizeof(aCurrKey->mKeyMaterial.mKey.m8), &aKeySize));
SuccessOrExit(error = otPlatCryptoExportKey(aNextKey->mKeyMaterial.mKeyRef, aNextKey->mKeyMaterial.mKey.m8,
sizeof(aNextKey->mKeyMaterial.mKey.m8), &aKeySize));
#else
OT_UNUSED_VARIABLE(aKeySize);
#endif
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.m8, sizeof(otMacKey), aCurrKey.m8, sizeof(otMacKey),
aNextKey.m8, sizeof(otMacKey)));
aKeyIdMode, aKeyId, aPrevKey->mKeyMaterial.mKey.m8, sizeof(otMacKey),
aCurrKey->mKeyMaterial.mKey.m8, sizeof(otMacKey), aNextKey->mKeyMaterial.mKey.m8,
sizeof(otMacKey)));
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
mKeyIdMode = aKeyIdMode;
mKeyId = aKeyId;
memcpy(mPrevKey.m8, aPrevKey.m8, OT_MAC_KEY_SIZE);
memcpy(mCurrKey.m8, aCurrKey.m8, OT_MAC_KEY_SIZE);
memcpy(mNextKey.m8, aNextKey.m8, OT_MAC_KEY_SIZE);
memcpy(mPrevKey.m8, aPrevKey->mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE);
memcpy(mCurrKey.m8, aCurrKey->mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE);
memcpy(mNextKey.m8, aNextKey->mKeyMaterial.mKey.m8, OT_MAC_KEY_SIZE);
mMacKeySet = true;
#endif
+5 -1
View File
@@ -502,7 +502,11 @@ exit:
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_PSKC>(void)
{
return mEncoder.WriteData(otThreadGetPskc(mInstance)->m8, sizeof(spinel_net_pskc_t));
Pskc pskc;
otThreadGetPskc(mInstance, &pskc);
return mEncoder.WriteData(pskc.m8, sizeof(spinel_net_pskc_t));
}
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_PSKC>(void)
+5 -1
View File
@@ -662,7 +662,11 @@ exit:
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_NET_NETWORK_KEY>(void)
{
return mEncoder.WriteData(otThreadGetNetworkKey(mInstance)->m8, OT_NETWORK_KEY_SIZE);
otNetworkKey networkKey;
otThreadGetNetworkKey(mInstance, &networkKey);
return mEncoder.WriteData(networkKey.m8, OT_NETWORK_KEY_SIZE);
}
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_NET_NETWORK_KEY>(void)
+9 -7
View File
@@ -563,15 +563,17 @@ otRadioState otPlatRadioGetState(otInstance *aInstance)
return sRadioSpinel.GetState();
}
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKey *aPrevKey,
const otMacKey *aCurrKey,
const otMacKey *aNextKey)
void otPlatRadioSetMacKey(otInstance * aInstance,
uint8_t aKeyIdMode,
uint8_t aKeyId,
const otMacKeyMaterial *aPrevKey,
const otMacKeyMaterial *aCurrKey,
const otMacKeyMaterial *aNextKey,
otRadioKeyType aKeyType)
{
SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, *aPrevKey, *aCurrKey, *aNextKey));
SuccessOrDie(sRadioSpinel.SetMacKey(aKeyIdMode, aKeyId, aPrevKey, aCurrKey, aNextKey));
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aKeyType);
}
void otPlatRadioSetMacFrameCounter(otInstance *aInstance, uint32_t aMacFrameCounter)
+5 -1
View File
@@ -129,6 +129,7 @@ void TestHkdfSha256(void)
{
ot::Crypto::HkdfSha256 hkdf;
uint8_t outKey[kMaxOuttKey];
ot::Crypto::Key testInputKey;
printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
DumpBuffer("\nInput Key", test->mInKey, test->mInKeyLength);
@@ -137,8 +138,11 @@ void TestHkdfSha256(void)
DumpBuffer("\nExpected Output Key", test->mOutKey, test->mOutKeyLength);
memset(outKey, kFillByte, sizeof(outKey));
memset(&testInputKey, 0x00, sizeof(testInputKey));
testInputKey.mKey = test->mInKey;
testInputKey.mKeyLength = test->mInKeyLength;
hkdf.Extract(test->mSalt, test->mSaltLength, test->mInKey, test->mInKeyLength);
hkdf.Extract(test->mSalt, test->mSaltLength, testInputKey);
hkdf.Expand(test->mInfo, test->mInfoLength, outKey, test->mOutKeyLength);
DumpBuffer("\nCalculated Output Key", outKey, test->mOutKeyLength);
+8 -9
View File
@@ -140,8 +140,7 @@ void TestHmacSha256(void)
{
struct TestCase
{
const void * mKey;
uint16_t mKeyLength;
otCryptoKey mKey;
const void * mData;
uint16_t mDataLength;
otCryptoSha256Hash mHash;
@@ -219,11 +218,11 @@ void TestHmacSha256(void)
}};
static const TestCase kTestCases[] = {
{kKey1, sizeof(kKey1), kData1, sizeof(kData1) - 1, kHash1},
{kKey2, sizeof(kKey2) - 1, kData2, sizeof(kData2) - 1, kHash2},
{kKey3, sizeof(kKey3), kData3, sizeof(kData3), kHash3},
{kKey4, sizeof(kKey4), kData4, sizeof(kData4), kHash4},
{kKey5, sizeof(kKey5), kData5, sizeof(kData5) - 1, kHash5},
{{&kKey1[0], sizeof(kKey1), 0}, kData1, sizeof(kData1) - 1, kHash1},
{{reinterpret_cast<const uint8_t *>(&kKey2[0]), sizeof(kKey2) - 1, 0}, kData2, sizeof(kData2) - 1, kHash2},
{{&kKey3[0], sizeof(kKey3), 0}, kData3, sizeof(kData3), kHash3},
{{&kKey4[0], sizeof(kKey4), 0}, kData4, sizeof(kData4), kHash4},
{{&kKey5[0], sizeof(kKey5), 0}, kData5, sizeof(kData5) - 1, kHash5},
};
Instance * instance = testInitInstance();
@@ -244,7 +243,7 @@ void TestHmacSha256(void)
Crypto::HmacSha256 hmac;
Crypto::HmacSha256::Hash hash;
hmac.Start(reinterpret_cast<const uint8_t *>(testCase.mKey), testCase.mKeyLength);
hmac.Start(static_cast<const Crypto::Key &>(testCase.mKey));
hmac.Update(testCase.mData, testCase.mDataLength);
hmac.Finish(hash);
@@ -270,7 +269,7 @@ void TestHmacSha256(void)
Crypto::HmacSha256 hmac;
Crypto::HmacSha256::Hash hash;
hmac.Start(reinterpret_cast<const uint8_t *>(testCase.mKey), testCase.mKeyLength);
hmac.Start(static_cast<const Crypto::Key &>(testCase.mKey));
hmac.Update(*message, offsets[index++], testCase.mDataLength);
hmac.Finish(hash);
+48
View File
@@ -502,4 +502,52 @@ OT_TOOL_WEAK otError otPlatInfraIfSendIcmp6Nd(uint32_t, const otIp6Address *, co
}
#endif
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
otError otPlatCryptoImportKey(otCryptoKeyRef * aKeyRef,
otCryptoKeyType aKeyType,
otCryptoKeyAlgorithm aKeyAlgorithm,
int aKeyUsage,
otCryptoKeyStorage aKeyPersistence,
const uint8_t * aKey,
size_t aKeyLen)
{
OT_UNUSED_VARIABLE(aKeyRef);
OT_UNUSED_VARIABLE(aKeyType);
OT_UNUSED_VARIABLE(aKeyAlgorithm);
OT_UNUSED_VARIABLE(aKeyUsage);
OT_UNUSED_VARIABLE(aKeyPersistence);
OT_UNUSED_VARIABLE(aKey);
OT_UNUSED_VARIABLE(aKeyLen);
return OT_ERROR_NONE;
}
otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen)
{
OT_UNUSED_VARIABLE(aKeyRef);
OT_UNUSED_VARIABLE(aBuffer);
OT_UNUSED_VARIABLE(aBufferLen);
*aKeyLen = 0;
return OT_ERROR_NONE;
}
otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef)
{
OT_UNUSED_VARIABLE(aKeyRef);
return OT_ERROR_NONE;
}
bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
{
OT_UNUSED_VARIABLE(aKeyRef);
return false;
}
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
} // extern "C"
+3 -3
View File
@@ -46,7 +46,7 @@ void TestMinimumPassphrase(void)
otInstance * instance = testInitInstance();
SuccessOrQuit(ot::MeshCoP::GeneratePskc(passphrase, *reinterpret_cast<const ot::Mac::NetworkName *>("OpenThread"),
static_cast<const ot::Mac::ExtendedPanId &>(xpanid), pskc));
VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc)) == 0);
VerifyOrQuit(memcmp(pskc.m8, expectedPskc, OT_PSKC_MAX_SIZE) == 0);
testFreeInstance(instance);
}
@@ -76,7 +76,7 @@ void TestMaximumPassphrase(void)
otInstance *instance = testInitInstance();
SuccessOrQuit(ot::MeshCoP::GeneratePskc(passphrase, *reinterpret_cast<const ot::Mac::NetworkName *>("OpenThread"),
static_cast<const ot::Mac::ExtendedPanId &>(xpanid), pskc));
VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc)) == 0);
VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc.m8)) == 0);
testFreeInstance(instance);
}
@@ -91,7 +91,7 @@ void TestExampleInSpec(void)
otInstance *instance = testInitInstance();
SuccessOrQuit(ot::MeshCoP::GeneratePskc(passphrase, *reinterpret_cast<const ot::Mac::NetworkName *>("Test Network"),
static_cast<const ot::Mac::ExtendedPanId &>(xpanid), pskc));
VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc)) == 0);
VerifyOrQuit(memcmp(pskc.m8, expectedPskc, sizeof(pskc.m8)) == 0);
testFreeInstance(instance);
}
+4 -1
View File
@@ -72,7 +72,10 @@ else()
configure_file(mbedtls-config.h openthread-mbedtls-config.h COPYONLY)
endif()
target_include_directories(ot-config INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(ot-config
INTERFACE
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/repo/include)
target_compile_definitions(mbedtls
PUBLIC