mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d4fa4223f | |||
| 291b7036b8 | |||
| 2c0c3e84a3 | |||
| b614af3a91 | |||
| 6b167f1cd3 | |||
| 3ed9fa8525 | |||
| aa3c2464d8 | |||
| bd36cf1ac5 | |||
| 31cf8eac65 | |||
| 24e0504b7d | |||
| cec709fcca | |||
| a71682d765 | |||
| 6f666901e3 | |||
| 2972fe884f | |||
| baed8372c3 | |||
| 3a6573fee8 |
@@ -419,6 +419,102 @@ jobs:
|
||||
path: tmp/coverage.info
|
||||
retention-days: 1
|
||||
|
||||
cli-psa:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
COVERAGE: 1
|
||||
THREAD_VERSION: 1.4
|
||||
VIRTUAL_TIME: 1
|
||||
INTER_OP_BBR: 1
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
- name: Bootstrap
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get --no-install-recommends install -y g++-multilib lcov ninja-build
|
||||
python3 -m pip install -r tests/scripts/thread-cert/requirements.txt
|
||||
- name: Build
|
||||
run: |
|
||||
OT_OPTIONS="-DOT_PLATFORM_KEY_REF=ON -DOT_CRYPTO_LIB=PSA" OT_NODE_TYPE=cli ./script/test build
|
||||
- name: Run
|
||||
run: |
|
||||
./script/test unit
|
||||
OT_NODE_TYPE=cli ./script/test cert_suite ./tests/scripts/thread-cert/Cert_*.py ./tests/scripts/thread-cert/test_*.py
|
||||
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
name: cli-psa
|
||||
path: ot_testing
|
||||
- name: Generate Coverage
|
||||
run: |
|
||||
./script/test generate_coverage gcc
|
||||
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
with:
|
||||
name: cov-cli-psa
|
||||
path: tmp/coverage.info
|
||||
retention-days: 1
|
||||
|
||||
cli-psa-expects:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
COVERAGE: 1
|
||||
THREAD_VERSION: 1.4
|
||||
VIRTUAL_TIME: 0
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
|
||||
with:
|
||||
egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
|
||||
with:
|
||||
python-version: '3.12'
|
||||
cache: pip
|
||||
- name: Bootstrap
|
||||
run: |
|
||||
sudo apt-get --no-install-recommends install -y expect ninja-build lcov
|
||||
sudo bash script/install_socat
|
||||
pip install bleak 'cryptography==43.0.0'
|
||||
- name: Run CLI Mode
|
||||
run: |
|
||||
ulimit -c unlimited
|
||||
./script/test prepare_coredump_upload
|
||||
OT_OPTIONS="-DOT_PLATFORM_KEY_REF=ON -DOT_CRYPTO_LIB=PSA -DOT_TIME_SYNC=ON -DOT_BLE_TCAT=ON" OT_NODE_TYPE=cli ./script/test build expect
|
||||
- name: Check Crash
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
CRASHED=$(./script/test check_crash | tail -1)
|
||||
[[ $CRASHED -eq "1" ]] && echo "Crashed!" || echo "Not crashed."
|
||||
echo "CRASHED=$CRASHED" >> $GITHUB_ENV
|
||||
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
if: ${{ failure() && env.CRASHED == '1' }}
|
||||
with:
|
||||
name: core-cli-psa-expects-1-4
|
||||
path: |
|
||||
./ot-core-dump/*
|
||||
- name: Generate Coverage
|
||||
run: |
|
||||
./script/test generate_coverage gcc
|
||||
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
|
||||
with:
|
||||
name: cov-cli-psa-expects
|
||||
path: tmp/coverage.info
|
||||
retention-days: 1
|
||||
|
||||
upload-coverage:
|
||||
needs:
|
||||
- thread-1-4
|
||||
@@ -426,6 +522,8 @@ jobs:
|
||||
- packet-verification-1-1-on-1-4
|
||||
- expects
|
||||
- thread-1-4-posix
|
||||
- cli-psa
|
||||
- cli-psa-expects
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
|
||||
@@ -180,9 +180,6 @@ jobs:
|
||||
./tests/toranj/build.sh --log-level CRIT all
|
||||
git clean -dfx
|
||||
./tests/toranj/build.sh --log-level NONE all
|
||||
#- - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
git clean -dfx
|
||||
./tests/toranj/build.sh --enable-plat-key-ref all
|
||||
|
||||
toranj-macos:
|
||||
name: toranj-macos
|
||||
|
||||
@@ -300,6 +300,10 @@ if(ot_index EQUAL -1)
|
||||
message(FATAL_ERROR "Invalid value for OT_PLATFORM - valid values are:" "${OT_PLATFORM_VALUES}")
|
||||
endif()
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
set(OT_CRYPTO_LIB_VALUES "MBEDTLS" "PSA" "PLATFORM")
|
||||
ot_multi_option(OT_CRYPTO_LIB OT_CRYPTO_LIB_VALUES OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_ "set Crypto backend library")
|
||||
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
set(OT_THREAD_VERSION_VALUES "1.1" "1.2" "1.3" "1.3.1" "1.4")
|
||||
set(OT_THREAD_VERSION "1.4" CACHE STRING "set Thread version")
|
||||
@@ -357,7 +361,7 @@ ot_int_option(OT_RCP_TX_WAIT_TIME_SECS OPENTHREAD_SPINEL_CONFIG_RCP_TX_WAIT_TIME
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
if(NOT OT_EXTERNAL_MBEDTLS)
|
||||
set(OT_MBEDTLS mbedtls)
|
||||
set(OT_MBEDTLS mbedtls mbedcrypto)
|
||||
target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS=1")
|
||||
else()
|
||||
set(OT_MBEDTLS ${OT_EXTERNAL_MBEDTLS})
|
||||
|
||||
@@ -48,9 +48,9 @@ target_link_libraries(ot-cli-ftd PRIVATE
|
||||
openthread-cli-ftd
|
||||
${OT_PLATFORM_LIB_FTD}
|
||||
openthread-ftd
|
||||
${OT_PLATFORM_LIB_FTD}
|
||||
openthread-cli-ftd
|
||||
${OT_MBEDTLS}
|
||||
${OT_PLATFORM_LIB_FTD}
|
||||
ot-config-ftd
|
||||
ot-config
|
||||
)
|
||||
|
||||
@@ -56,8 +56,7 @@ extern void otAppCliInit(otInstance *aInstance);
|
||||
|
||||
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
OT_TOOL_WEAK void *otPlatCAlloc(size_t aNum, size_t aSize) { return calloc(aNum, aSize); }
|
||||
|
||||
OT_TOOL_WEAK void otPlatFree(void *aPtr) { free(aPtr); }
|
||||
OT_TOOL_WEAK void otPlatFree(void *aPtr) { free(aPtr); }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_POSIX && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
|
||||
|
||||
@@ -48,9 +48,9 @@ target_link_libraries(ot-cli-mtd PRIVATE
|
||||
openthread-cli-mtd
|
||||
${OT_PLATFORM_LIB_MTD}
|
||||
openthread-mtd
|
||||
${OT_PLATFORM_LIB_MTD}
|
||||
openthread-cli-mtd
|
||||
${OT_MBEDTLS}
|
||||
${OT_PLATFORM_LIB_MTD}
|
||||
ot-config-mtd
|
||||
ot-config
|
||||
)
|
||||
|
||||
@@ -41,9 +41,9 @@ target_link_libraries(ot-ncp-ftd PRIVATE
|
||||
openthread-ncp-ftd
|
||||
${OT_PLATFORM_LIB_FTD}
|
||||
openthread-ftd
|
||||
${OT_PLATFORM_LIB_FTD}
|
||||
openthread-ncp-ftd
|
||||
${OT_MBEDTLS}
|
||||
${OT_PLATFORM_LIB_FTD}
|
||||
ot-config-ftd
|
||||
ot-config
|
||||
)
|
||||
|
||||
@@ -62,8 +62,7 @@ extern void otAppNcpInitMulti(otInstance **aInstances, uint8_t count);
|
||||
|
||||
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
OT_TOOL_WEAK void *otPlatCAlloc(size_t aNum, size_t aSize) { return calloc(aNum, aSize); }
|
||||
|
||||
OT_TOOL_WEAK void otPlatFree(void *aPtr) { free(aPtr); }
|
||||
OT_TOOL_WEAK void otPlatFree(void *aPtr) { free(aPtr); }
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
@@ -41,9 +41,9 @@ target_link_libraries(ot-ncp-mtd PRIVATE
|
||||
openthread-ncp-mtd
|
||||
${OT_PLATFORM_LIB_MTD}
|
||||
openthread-mtd
|
||||
${OT_PLATFORM_LIB_MTD}
|
||||
openthread-ncp-mtd
|
||||
${OT_MBEDTLS}
|
||||
${OT_PLATFORM_LIB_MTD}
|
||||
ot-config-mtd
|
||||
ot-config
|
||||
)
|
||||
|
||||
@@ -74,7 +74,6 @@ set(OT_PLATFORM_DEFINES ${OT_PLATFORM_DEFINES} PARENT_SCOPE)
|
||||
add_library(openthread-simulation
|
||||
alarm.c
|
||||
ble.c
|
||||
crypto.c
|
||||
diag.c
|
||||
dns.c
|
||||
dnssd.c
|
||||
@@ -104,6 +103,8 @@ endif()
|
||||
|
||||
target_link_libraries(openthread-simulation PRIVATE
|
||||
openthread-platform
|
||||
mbedtls
|
||||
openthread-native-its-file
|
||||
ot-simulation-config
|
||||
ot-config
|
||||
)
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
#include <openthread/platform/entropy.h>
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
#include <psa/crypto.h>
|
||||
#endif
|
||||
|
||||
#include "utils/code_utils.h"
|
||||
|
||||
#ifndef __SANITIZE_ADDRESS__
|
||||
@@ -133,3 +137,33 @@ exit:
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
/**
|
||||
* When OpenThread is compiled with the PSA Crypto backend using Mbed TLS 3.x, there is no
|
||||
* API to configure a dedicated non-default entropy source. It is documented that a future version of
|
||||
* Mbed TLS (likely 4.x) will include a PSA interface for configuring entropy sources.
|
||||
*
|
||||
* For now, we need to define the external RNG. Since the implementation of `otPlatEntropyGet` already
|
||||
* uses CSPRNG, we will call it here as well.
|
||||
*/
|
||||
psa_status_t mbedtls_psa_external_get_random(mbedtls_psa_external_random_context_t *context,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(context);
|
||||
|
||||
otError error;
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
|
||||
error = otPlatEntropyGet(output, (uint16_t)output_size);
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
*output_length = output_size;
|
||||
status = PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -52,6 +52,10 @@
|
||||
#include <openthread/platform/alarm-milli.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
#include <psa/crypto.h>
|
||||
#endif
|
||||
|
||||
#include "simul_utils.h"
|
||||
|
||||
uint32_t gNodeId = 1;
|
||||
@@ -61,6 +65,11 @@ extern otRadioCaps gRadioCaps;
|
||||
|
||||
static volatile bool gTerminate = false;
|
||||
|
||||
#if OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_FILE && (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
static char sNativeItsFileNamePrefix[256];
|
||||
extern const char *gItsFileNamePrefix;
|
||||
#endif
|
||||
|
||||
static void handleSignal(int aSignal)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aSignal);
|
||||
@@ -193,6 +202,15 @@ void otSysInit(int aArgCount, char *aArgVector[])
|
||||
signal(SIGTERM, &handleSignal);
|
||||
signal(SIGHUP, &handleSignal);
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
psa_crypto_init();
|
||||
#if OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_FILE
|
||||
snprintf(sNativeItsFileNamePrefix, sizeof(sNativeItsFileNamePrefix), "%s/%s_%d_",
|
||||
OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH, getenv("PORT_OFFSET") ? getenv("PORT_OFFSET") : "0", gNodeId);
|
||||
gItsFileNamePrefix = sNativeItsFileNamePrefix;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
platformLoggingInit(basename(aArgVector[0]));
|
||||
platformAlarmInit(speedUpFactor);
|
||||
platformRadioInit();
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
#include <openthread/tasklet.h>
|
||||
#include <openthread/platform/alarm-milli.h>
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
#include <psa/crypto.h>
|
||||
#endif
|
||||
|
||||
#include "lib/platform/exit_code.h"
|
||||
#include "utils/uart.h"
|
||||
|
||||
@@ -63,6 +67,11 @@ static bool sUseUnixSocket = false;
|
||||
int gArgumentsCount = 0;
|
||||
char **gArguments = NULL;
|
||||
|
||||
#if OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_FILE && (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
static char sNativeItsFileNamePrefix[256];
|
||||
extern const char *gItsFileNamePrefix;
|
||||
#endif
|
||||
|
||||
uint64_t sNow = 0; // microseconds
|
||||
int sSockFd;
|
||||
uint16_t sPortBase = 9000;
|
||||
@@ -273,6 +282,15 @@ void otSysInit(int argc, char *argv[])
|
||||
DieNow(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
psa_crypto_init();
|
||||
#if OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_FILE
|
||||
snprintf(sNativeItsFileNamePrefix, sizeof(sNativeItsFileNamePrefix), "%s/%s_%d_",
|
||||
OPENTHREAD_CONFIG_POSIX_SETTINGS_PATH, getenv("PORT_OFFSET") ? getenv("PORT_OFFSET") : "0", gNodeId);
|
||||
gItsFileNamePrefix = sNativeItsFileNamePrefix;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
socket_init();
|
||||
|
||||
platformAlarmInit(1);
|
||||
|
||||
@@ -52,7 +52,7 @@ extern "C" {
|
||||
*
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (548)
|
||||
#define OPENTHREAD_API_VERSION (551)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -60,10 +60,11 @@ extern "C" {
|
||||
*/
|
||||
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.
|
||||
OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
|
||||
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.
|
||||
OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
|
||||
OT_CRYPTO_KEY_TYPE_DERIVE, ///< Key Type: Derive.
|
||||
} otCryptoKeyType;
|
||||
|
||||
/**
|
||||
@@ -75,6 +76,7 @@ typedef enum
|
||||
OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
|
||||
OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
|
||||
OT_CRYPTO_KEY_ALG_ECDSA, ///< Key Algorithm: ECDSA.
|
||||
OT_CRYPTO_KEY_ALG_HKDF_SHA256, ///< Key Algorithm: HKDF SHA-256.
|
||||
} otCryptoKeyAlgorithm;
|
||||
|
||||
/**
|
||||
@@ -88,6 +90,7 @@ enum
|
||||
OT_CRYPTO_KEY_USAGE_DECRYPT = 1 << 2, ///< Key Usage: AES ECB.
|
||||
OT_CRYPTO_KEY_USAGE_SIGN_HASH = 1 << 3, ///< Key Usage: Sign Hash.
|
||||
OT_CRYPTO_KEY_USAGE_VERIFY_HASH = 1 << 4, ///< Key Usage: Verify Hash.
|
||||
OT_CRYPTO_KEY_USAGE_DERIVE = 1 << 5, ///< Key Usage: Derive.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -212,11 +215,6 @@ typedef struct otPlatCryptoEcdsaSignature otPlatCryptoEcdsaSignature;
|
||||
*/
|
||||
#define OT_CRYPTO_PBDKF2_MAX_SALT_SIZE 30
|
||||
|
||||
/**
|
||||
* Initialize the Crypto module.
|
||||
*/
|
||||
void otPlatCryptoInit(void);
|
||||
|
||||
/**
|
||||
* Import a key into PSA ITS.
|
||||
*
|
||||
@@ -288,6 +286,33 @@ otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef);
|
||||
*/
|
||||
bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef);
|
||||
|
||||
/**
|
||||
* Dynamically allocates new memory for Crypto subsystem. On platforms that support it, should just redirect to calloc.
|
||||
* For those that don't support calloc, should support the same functionality:
|
||||
*
|
||||
* "The calloc() function contiguously allocates enough space for count objects that are size bytes of
|
||||
* memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes
|
||||
* of value zero."
|
||||
*
|
||||
* Is required for OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE.
|
||||
*
|
||||
* @param[in] aNum The number of blocks to allocate
|
||||
* @param[in] aSize The size of each block to allocate
|
||||
*
|
||||
* @retval void* The pointer to the front of the memory allocated
|
||||
* @retval NULL Failed to allocate the memory requested.
|
||||
*/
|
||||
void *otPlatCryptoCAlloc(size_t aNum, size_t aSize);
|
||||
|
||||
/**
|
||||
* Frees memory that was dynamically allocated by otPlatCryptoCAlloc.
|
||||
*
|
||||
* Is required for OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE.
|
||||
*
|
||||
* @param[in] aPtr A pointer the memory blocks to free. The pointer may be NULL.
|
||||
*/
|
||||
void otPlatCryptoFree(void *aPtr);
|
||||
|
||||
/**
|
||||
* Initialize the HMAC operation.
|
||||
*
|
||||
|
||||
+4
-2
@@ -481,7 +481,8 @@ openthread_core_files = [
|
||||
"crypto/aes_ecb.cpp",
|
||||
"crypto/aes_ecb.hpp",
|
||||
"crypto/context_size.hpp",
|
||||
"crypto/crypto_platform.cpp",
|
||||
"crypto/crypto_platform_mbedtls.cpp",
|
||||
"crypto/crypto_platform_psa.cpp",
|
||||
"crypto/ecdsa.hpp",
|
||||
"crypto/hkdf_sha256.cpp",
|
||||
"crypto/hkdf_sha256.hpp",
|
||||
@@ -803,7 +804,8 @@ openthread_radio_sources = [
|
||||
"common/uptime.cpp",
|
||||
"crypto/aes_ccm.cpp",
|
||||
"crypto/aes_ecb.cpp",
|
||||
"crypto/crypto_platform.cpp",
|
||||
"crypto/crypto_platform_mbedtls.cpp",
|
||||
"crypto/crypto_platform_psa.cpp",
|
||||
"crypto/storage.cpp",
|
||||
"diags/factory_diags.cpp",
|
||||
"instance/instance.cpp",
|
||||
|
||||
@@ -135,7 +135,8 @@ set(COMMON_SOURCES
|
||||
common/uptime.cpp
|
||||
crypto/aes_ccm.cpp
|
||||
crypto/aes_ecb.cpp
|
||||
crypto/crypto_platform.cpp
|
||||
crypto/crypto_platform_mbedtls.cpp
|
||||
crypto/crypto_platform_psa.cpp
|
||||
crypto/hkdf_sha256.cpp
|
||||
crypto/hmac_sha256.cpp
|
||||
crypto/mbedtls.cpp
|
||||
@@ -307,7 +308,8 @@ set(RADIO_COMMON_SOURCES
|
||||
common/uptime.cpp
|
||||
crypto/aes_ccm.cpp
|
||||
crypto/aes_ecb.cpp
|
||||
crypto/crypto_platform.cpp
|
||||
crypto/crypto_platform_mbedtls.cpp
|
||||
crypto/crypto_platform_psa.cpp
|
||||
crypto/storage.cpp
|
||||
diags/factory_diags.cpp
|
||||
instance/instance.cpp
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
* - @sa OPENTHREAD_CONFIG_CRYPTO_LIB_PLATFORM
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_CRYPTO_LIB
|
||||
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
|
||||
#define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
#endif
|
||||
|
||||
/** Use mbedtls as crypto library */
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#ifndef CONFIG_PLATFORM_H_
|
||||
#define CONFIG_PLATFORM_H_
|
||||
|
||||
#include "config/srp_server.h"
|
||||
#include "config/crypto.h"
|
||||
|
||||
/**
|
||||
* @addtogroup config-platform
|
||||
@@ -154,9 +154,13 @@
|
||||
* @def OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
*
|
||||
* Define to 1 if you want to enable key ref usage support as defined by platform.
|
||||
*
|
||||
* This config is enabled by default for PSA Crypto backend.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 0
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE \
|
||||
(OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/platform/crypto.h>
|
||||
#include <openthread/platform/entropy.h>
|
||||
#include <openthread/platform/memory.h>
|
||||
#include <openthread/platform/time.h>
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
@@ -78,10 +79,10 @@ static constexpr uint16_t kEntropyMinThreshold = 16;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
OT_TOOL_WEAK void otPlatCryptoInit(void)
|
||||
{
|
||||
// Intentionally empty.
|
||||
}
|
||||
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
OT_TOOL_WEAK void *otPlatCryptoCAlloc(size_t aNum, size_t aSize) { return otPlatCAlloc(aNum, aSize); }
|
||||
OT_TOOL_WEAK void otPlatCryptoFree(void *aPtr) { otPlatFree(aPtr); }
|
||||
#endif
|
||||
|
||||
// AES Implementation
|
||||
OT_TOOL_WEAK otError otPlatCryptoAesInit(otCryptoContext *aContext)
|
||||
@@ -749,74 +750,4 @@ exit:
|
||||
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
|
||||
#elif OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
#if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyPair);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair,
|
||||
otPlatCryptoEcdsaPublicKey *aPublicKey)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyPair);
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyPair);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
#endif // #if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
|
||||
#endif // #if OPENTHREAD_FTD || OPENTHREAD_MTD
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
|
||||
uint16_t aPasswordLen,
|
||||
const uint8_t *aSalt,
|
||||
uint16_t aSaltLen,
|
||||
uint32_t aIterationCounter,
|
||||
uint16_t aKeyLen,
|
||||
uint8_t *aKey)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aPassword);
|
||||
OT_UNUSED_VARIABLE(aPasswordLen);
|
||||
OT_UNUSED_VARIABLE(aSalt);
|
||||
OT_UNUSED_VARIABLE(aSaltLen);
|
||||
OT_UNUSED_VARIABLE(aIterationCounter);
|
||||
OT_UNUSED_VARIABLE(aKeyLen);
|
||||
OT_UNUSED_VARIABLE(aKey);
|
||||
|
||||
return OT_ERROR_NOT_CAPABLE;
|
||||
}
|
||||
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
|
||||
@@ -0,0 +1,797 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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 default/weak Crypto platform APIs using ARM PSA API.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <mbedtls/asn1.h>
|
||||
#include <psa/crypto.h>
|
||||
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/platform/crypto.h>
|
||||
#include <openthread/platform/entropy.h>
|
||||
#include <openthread/platform/memory.h>
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/debug.hpp"
|
||||
#include "common/new.hpp"
|
||||
#include "config/crypto.h"
|
||||
#include "crypto/ecdsa.hpp"
|
||||
#include "crypto/hmac_sha256.hpp"
|
||||
#include "crypto/storage.hpp"
|
||||
#include "instance/instance.hpp"
|
||||
|
||||
using namespace ot;
|
||||
using namespace Crypto;
|
||||
|
||||
#if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Default/weak implementation of crypto platform APIs
|
||||
|
||||
static otError psaToOtError(psa_status_t aStatus)
|
||||
{
|
||||
switch (aStatus)
|
||||
{
|
||||
case PSA_SUCCESS:
|
||||
return kErrorNone;
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
return kErrorInvalidArgs;
|
||||
case PSA_ERROR_BUFFER_TOO_SMALL:
|
||||
return kErrorNoBufs;
|
||||
default:
|
||||
return kErrorFailed;
|
||||
}
|
||||
}
|
||||
|
||||
static psa_key_type_t toPsaKeyType(otCryptoKeyType aType)
|
||||
{
|
||||
switch (aType)
|
||||
{
|
||||
case OT_CRYPTO_KEY_TYPE_RAW:
|
||||
return PSA_KEY_TYPE_RAW_DATA;
|
||||
case OT_CRYPTO_KEY_TYPE_AES:
|
||||
return PSA_KEY_TYPE_AES;
|
||||
case OT_CRYPTO_KEY_TYPE_HMAC:
|
||||
return PSA_KEY_TYPE_HMAC;
|
||||
case OT_CRYPTO_KEY_TYPE_ECDSA:
|
||||
return PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
|
||||
case OT_CRYPTO_KEY_TYPE_DERIVE:
|
||||
return PSA_KEY_TYPE_DERIVE;
|
||||
default:
|
||||
return PSA_KEY_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static psa_algorithm_t toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm)
|
||||
{
|
||||
switch (aAlgorithm)
|
||||
{
|
||||
case OT_CRYPTO_KEY_ALG_AES_ECB:
|
||||
return PSA_ALG_ECB_NO_PADDING;
|
||||
case OT_CRYPTO_KEY_ALG_HMAC_SHA_256:
|
||||
return PSA_ALG_HMAC(PSA_ALG_SHA_256);
|
||||
case OT_CRYPTO_KEY_ALG_ECDSA:
|
||||
return PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256);
|
||||
case OT_CRYPTO_KEY_ALG_HKDF_SHA256:
|
||||
return PSA_ALG_HKDF(PSA_ALG_SHA_256);
|
||||
default:
|
||||
return PSA_ALG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static psa_key_usage_t toPsaKeyUsage(int aUsage)
|
||||
{
|
||||
psa_key_usage_t usage = 0;
|
||||
|
||||
if (aUsage & OT_CRYPTO_KEY_USAGE_EXPORT)
|
||||
{
|
||||
usage |= PSA_KEY_USAGE_EXPORT;
|
||||
}
|
||||
|
||||
if (aUsage & OT_CRYPTO_KEY_USAGE_ENCRYPT)
|
||||
{
|
||||
usage |= PSA_KEY_USAGE_ENCRYPT;
|
||||
}
|
||||
|
||||
if (aUsage & OT_CRYPTO_KEY_USAGE_DECRYPT)
|
||||
{
|
||||
usage |= PSA_KEY_USAGE_DECRYPT;
|
||||
}
|
||||
|
||||
if (aUsage & OT_CRYPTO_KEY_USAGE_SIGN_HASH)
|
||||
{
|
||||
usage |= PSA_KEY_USAGE_SIGN_HASH;
|
||||
}
|
||||
|
||||
if (aUsage & OT_CRYPTO_KEY_USAGE_VERIFY_HASH)
|
||||
{
|
||||
usage |= PSA_KEY_USAGE_VERIFY_HASH;
|
||||
}
|
||||
|
||||
if (aUsage & OT_CRYPTO_KEY_USAGE_DERIVE)
|
||||
{
|
||||
usage |= PSA_KEY_USAGE_DERIVE;
|
||||
}
|
||||
|
||||
return usage;
|
||||
}
|
||||
|
||||
static bool checkKeyUsage(int aUsage)
|
||||
{
|
||||
/* Check if only supported flags have been passed */
|
||||
int supportedFlags = OT_CRYPTO_KEY_USAGE_EXPORT | OT_CRYPTO_KEY_USAGE_ENCRYPT | OT_CRYPTO_KEY_USAGE_DECRYPT |
|
||||
OT_CRYPTO_KEY_USAGE_SIGN_HASH | OT_CRYPTO_KEY_USAGE_VERIFY_HASH | OT_CRYPTO_KEY_USAGE_DERIVE;
|
||||
|
||||
return (aUsage & ~supportedFlags) == 0;
|
||||
}
|
||||
|
||||
static bool checkContext(otCryptoContext *aContext, size_t aMinSize)
|
||||
{
|
||||
/* Verify that the passed context is initialized and points to a big enough buffer */
|
||||
return aContext != nullptr && aContext->mContext != nullptr && aContext->mContextSize >= aMinSize;
|
||||
}
|
||||
|
||||
static otError extractPrivateKeyInfo(const uint8_t *aAsn1KeyPair,
|
||||
size_t aAsn1KeyPairLen,
|
||||
size_t *aKeyOffset,
|
||||
size_t *aKeyLen)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
unsigned char *p = const_cast<unsigned char *>(aAsn1KeyPair);
|
||||
const unsigned char *end = p + aAsn1KeyPairLen;
|
||||
size_t len;
|
||||
|
||||
// Parse the ASN.1 SEQUENCE headers
|
||||
int ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
VerifyOrExit(ret == 0, error = kErrorInvalidArgs);
|
||||
|
||||
// Parse the version (INTEGER)
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
|
||||
VerifyOrExit(ret == 0, error = kErrorInvalidArgs);
|
||||
|
||||
// Skip the version.
|
||||
p += len;
|
||||
|
||||
// Parse the private key (OCTET STRING)
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
VerifyOrExit(ret == 0, error = kErrorInvalidArgs);
|
||||
|
||||
// Check if the private key includes a padding byte (0x00)
|
||||
if (*p == 0x00)
|
||||
{
|
||||
p++;
|
||||
len--; // Skip the padding byte and reduce length by 1
|
||||
}
|
||||
|
||||
*aKeyOffset = (p - aAsn1KeyPair);
|
||||
*aKeyLen = len;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
OT_TOOL_WEAK void *otPlatCryptoCAlloc(size_t aNum, size_t aSize) { return otPlatCAlloc(aNum, aSize); }
|
||||
OT_TOOL_WEAK void otPlatCryptoFree(void *aPtr) { otPlatFree(aPtr); }
|
||||
#endif
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef,
|
||||
otCryptoKeyType aKeyType,
|
||||
otCryptoKeyAlgorithm aKeyAlgorithm,
|
||||
int aKeyUsage,
|
||||
otCryptoKeyStorage aKeyPersistence,
|
||||
const uint8_t *aKey,
|
||||
size_t aKeyLen)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
|
||||
VerifyOrExit(checkKeyUsage(aKeyUsage), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aKeyRef != nullptr && aKey != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
// PSA Crypto API expects the private key to be provided, not the full ASN1 buffer.
|
||||
if (aKeyType == OT_CRYPTO_KEY_TYPE_ECDSA)
|
||||
{
|
||||
size_t pkOffset;
|
||||
size_t pkLength;
|
||||
|
||||
SuccessOrExit(error = extractPrivateKeyInfo(aKey, aKeyLen, &pkOffset, &pkLength));
|
||||
|
||||
// Overwrite the content of the key.
|
||||
aKey += pkOffset;
|
||||
aKeyLen = pkLength;
|
||||
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
}
|
||||
|
||||
psa_set_key_type(&attributes, toPsaKeyType(aKeyType));
|
||||
psa_set_key_algorithm(&attributes, toPsaAlgorithm(aKeyAlgorithm));
|
||||
psa_set_key_usage_flags(&attributes, toPsaKeyUsage(aKeyUsage));
|
||||
|
||||
switch (aKeyPersistence)
|
||||
{
|
||||
case OT_CRYPTO_KEY_STORAGE_PERSISTENT:
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
|
||||
psa_set_key_id(&attributes, *aKeyRef);
|
||||
break;
|
||||
case OT_CRYPTO_KEY_STORAGE_VOLATILE:
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
|
||||
break;
|
||||
default:
|
||||
OT_ASSERT(false);
|
||||
}
|
||||
|
||||
status = psa_import_key(&attributes, aKey, aKeyLen, aKeyRef);
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
if (error != kErrorNone)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(aBuffer != nullptr && aKeyLen != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
error = psaToOtError(psa_export_key(aKeyRef, aBuffer, aBufferLen, aKeyLen));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef) { return psaToOtError(psa_destroy_key(aKeyRef)); }
|
||||
|
||||
OT_TOOL_WEAK bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef)
|
||||
{
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_get_key_attributes(aKeyRef, &attributes);
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
return status == PSA_SUCCESS;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoAesInit(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_key_id_t *keyRef;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_id_t)), error = kErrorInvalidArgs);
|
||||
|
||||
keyRef = static_cast<psa_key_id_t *>(aContext->mContext);
|
||||
*keyRef = PSA_KEY_ID_NULL;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoAesSetKey(otCryptoContext *aContext, const otCryptoKey *aKey)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_key_id_t *keyRef;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_id_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aKey != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
keyRef = static_cast<psa_key_id_t *>(aContext->mContext);
|
||||
*keyRef = aKey->mKeyRef;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, uint8_t *aOutput)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
const size_t blockSize = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES);
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_id_t *keyRef;
|
||||
size_t cipherLen;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_id_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aInput != nullptr && aOutput != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
keyRef = static_cast<psa_key_id_t *>(aContext->mContext);
|
||||
status = psa_cipher_encrypt(*keyRef, PSA_ALG_ECB_NO_PADDING, aInput, blockSize, aOutput, blockSize, &cipherLen);
|
||||
|
||||
error = psaToOtError(status);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoAesFree(otCryptoContext *aContext)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aContext);
|
||||
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
#if !OPENTHREAD_RADIO
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Init(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_mac_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_mac_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_mac_operation_t *>(aContext->mContext);
|
||||
|
||||
// Initialize the structure using memset as documented alternative for psa_mac_operation_init().
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Deinit(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_mac_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_mac_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_mac_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_mac_abort(operation));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey *aKey)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_mac_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_mac_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aKey != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_mac_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_mac_sign_setup(operation, aKey->mKeyRef, PSA_ALG_HMAC(PSA_ALG_SHA_256)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_mac_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_mac_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aBuf != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_mac_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_mac_update(operation, static_cast<const uint8_t *>(aBuf), aBufLength));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_mac_operation_t *operation;
|
||||
size_t macLength;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_mac_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aBuf != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_mac_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_mac_sign_finish(operation, aBuf, aBufLength, &macLength));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHkdfInit(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_key_derivation_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_derivation_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_key_derivation_operation_t *>(aContext->mContext);
|
||||
|
||||
*operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
|
||||
error = psaToOtError(psa_key_derivation_setup(operation, PSA_ALG_HKDF(PSA_ALG_SHA_256)));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHkdfExtract(otCryptoContext *aContext,
|
||||
const uint8_t *aSalt,
|
||||
uint16_t aSaltLength,
|
||||
const otCryptoKey *aInputKey)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_derivation_operation_t *operation = nullptr;
|
||||
otCryptoKeyRef keyRef = PSA_KEY_ID_NULL;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t keyAlg = PSA_ALG_NONE;
|
||||
size_t keyLength = 0;
|
||||
constexpr size_t kBufferSize = 128;
|
||||
uint8_t keyBuffer[kBufferSize];
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_derivation_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aInputKey != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_key_derivation_operation_t *>(aContext->mContext);
|
||||
|
||||
status = psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_SALT, aSalt, aSaltLength);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
|
||||
status = psa_get_key_attributes(aInputKey->mKeyRef, &attributes);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
|
||||
keyAlg = psa_get_key_algorithm(&attributes);
|
||||
|
||||
// The PSA API enforces a policy that restricts each key to a single algorithm.
|
||||
// If the key is already HKDF-SHA256, we can use it directly.
|
||||
// Otherwise, export and re-import it as a volatile HKDF key.
|
||||
if (keyAlg != toPsaAlgorithm(OT_CRYPTO_KEY_ALG_HKDF_SHA256))
|
||||
{
|
||||
SuccessOrExit(error = otPlatCryptoExportKey(aInputKey->mKeyRef, keyBuffer, sizeof(keyBuffer), &keyLength));
|
||||
SuccessOrExit(error = otPlatCryptoImportKey(&keyRef, OT_CRYPTO_KEY_TYPE_DERIVE, OT_CRYPTO_KEY_ALG_HKDF_SHA256,
|
||||
OT_CRYPTO_KEY_USAGE_DERIVE, OT_CRYPTO_KEY_STORAGE_VOLATILE,
|
||||
keyBuffer, keyLength));
|
||||
|
||||
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET, keyRef);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
}
|
||||
else
|
||||
{
|
||||
status = psa_key_derivation_input_key(operation, PSA_KEY_DERIVATION_INPUT_SECRET, aInputKey->mKeyRef);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
}
|
||||
|
||||
exit:
|
||||
if (keyRef != PSA_KEY_ID_NULL)
|
||||
{
|
||||
otPlatCryptoDestroyKey(keyRef);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHkdfExpand(otCryptoContext *aContext,
|
||||
const uint8_t *aInfo,
|
||||
uint16_t aInfoLength,
|
||||
uint8_t *aOutputKey,
|
||||
uint16_t aOutputKeyLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_derivation_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_derivation_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aOutputKey != nullptr, error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aOutputKeyLength != 0, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_key_derivation_operation_t *>(aContext->mContext);
|
||||
|
||||
status = psa_key_derivation_input_bytes(operation, PSA_KEY_DERIVATION_INPUT_INFO, aInfo, aInfoLength);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
|
||||
status = psa_key_derivation_output_bytes(operation, aOutputKey, aOutputKeyLength);
|
||||
SuccessOrExit(error = psaToOtError(status));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoHkdfDeinit(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_key_derivation_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_key_derivation_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_key_derivation_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_key_derivation_abort(operation));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoSha256Init(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_hash_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_hash_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_hash_operation_t *>(aContext->mContext);
|
||||
|
||||
// Initialize the structure using memset as documented alternative for psa_hash_operation_init().
|
||||
memset(operation, 0, sizeof(*operation));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoSha256Deinit(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_hash_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_hash_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_hash_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_hash_abort(operation));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoSha256Start(otCryptoContext *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_hash_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_hash_operation_t)), error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_hash_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_hash_setup(operation, PSA_ALG_SHA_256));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_hash_operation_t *operation;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_hash_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aBuf != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_hash_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_hash_update(operation, static_cast<const uint8_t *>(aBuf), aBufLength));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
psa_hash_operation_t *operation;
|
||||
size_t hashSize;
|
||||
|
||||
VerifyOrExit(checkContext(aContext, sizeof(psa_hash_operation_t)), error = kErrorInvalidArgs);
|
||||
VerifyOrExit(aHash != nullptr, error = kErrorInvalidArgs);
|
||||
|
||||
operation = static_cast<psa_hash_operation_t *>(aContext->mContext);
|
||||
|
||||
error = psaToOtError(psa_hash_finish(operation, aHash, aHashSize, &hashSize));
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK void otPlatCryptoRandomInit(void) { psa_crypto_init(); }
|
||||
|
||||
OT_TOOL_WEAK void otPlatCryptoRandomDeinit(void)
|
||||
{
|
||||
// Intentionally empty
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoRandomGet(uint8_t *aBuffer, uint16_t aSize)
|
||||
{
|
||||
return psaToOtError(psa_generate_random(aBuffer, aSize));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
|
||||
{
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_status_t status;
|
||||
psa_key_id_t keyId = static_cast<psa_key_id_t>(aKeyRef);
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);
|
||||
psa_set_key_id(&attributes, keyId);
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
|
||||
status = psa_generate_key(&attributes, &keyId);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&attributes);
|
||||
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t exportedLen;
|
||||
uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE];
|
||||
|
||||
status = psa_export_public_key(aKeyRef, buffer, sizeof(buffer), &exportedLen);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
OT_ASSERT(exportedLen == sizeof(buffer));
|
||||
memcpy(aPublicKey->m8, buffer + 1, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE);
|
||||
|
||||
exit:
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
psa_status_t status;
|
||||
size_t signatureLen;
|
||||
|
||||
status = psa_sign_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8, OT_CRYPTO_SHA256_HASH_SIZE,
|
||||
aSignature->m8, OT_CRYPTO_ECDSA_SIGNATURE_SIZE, &signatureLen);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
OT_ASSERT(signatureLen == OT_CRYPTO_ECDSA_SIGNATURE_SIZE);
|
||||
|
||||
exit:
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t keyId = PSA_KEY_ID_NULL;
|
||||
psa_status_t status;
|
||||
uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE];
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_bits(&attributes, 256);
|
||||
|
||||
/*
|
||||
* `psa_import_key` expects a key format as specified by SEC1 §2.3.3 for the
|
||||
* uncompressed representation of the ECPoint.
|
||||
*/
|
||||
buffer[0] = 0x04;
|
||||
memcpy(buffer + 1, aPublicKey->m8, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE);
|
||||
|
||||
status = psa_import_key(&attributes, buffer, sizeof(buffer), &keyId);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
status = psa_verify_hash(keyId, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8, OT_CRYPTO_SHA256_HASH_SIZE,
|
||||
aSignature->m8, OT_CRYPTO_ECDSA_SIGNATURE_SIZE);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&attributes);
|
||||
psa_destroy_key(keyId);
|
||||
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
status = psa_verify_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8,
|
||||
OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8, OT_CRYPTO_ECDSA_SIGNATURE_SIZE);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
exit:
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
|
||||
#endif // #if !OPENTHREAD_RADIO
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
|
||||
OT_TOOL_WEAK otError otPlatCryptoPbkdf2GenerateKey(const uint8_t *aPassword,
|
||||
uint16_t aPasswordLen,
|
||||
const uint8_t *aSalt,
|
||||
uint16_t aSaltLen,
|
||||
uint32_t aIterationCounter,
|
||||
uint16_t aKeyLen,
|
||||
uint8_t *aKey)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
psa_key_id_t key_id = PSA_KEY_ID_NULL;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t algorithm = PSA_ALG_PBKDF2_AES_CMAC_PRF_128;
|
||||
psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
|
||||
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
|
||||
psa_set_key_algorithm(&attributes, algorithm);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_PASSWORD);
|
||||
psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(aPasswordLen));
|
||||
|
||||
status = psa_import_key(&attributes, aPassword, aPasswordLen, &key_id);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
status = psa_key_derivation_setup(&operation, algorithm);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
status = psa_key_derivation_input_integer(&operation, PSA_KEY_DERIVATION_INPUT_COST, aIterationCounter);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT, aSalt, aSaltLen);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
status = psa_key_derivation_input_key(&operation, PSA_KEY_DERIVATION_INPUT_PASSWORD, key_id);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
status = psa_key_derivation_output_bytes(&operation, aKey, aKeyLen);
|
||||
VerifyOrExit(status == PSA_SUCCESS);
|
||||
|
||||
exit:
|
||||
psa_reset_key_attributes(&attributes);
|
||||
psa_key_derivation_abort(&operation);
|
||||
psa_destroy_key(key_id);
|
||||
|
||||
return psaToOtError(status);
|
||||
}
|
||||
|
||||
#endif // #if OPENTHREAD_FTD
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
+22
-22
@@ -33,9 +33,9 @@
|
||||
|
||||
#include "mbedtls.hpp"
|
||||
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
// #include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/debug.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
// #include <mbedtls/entropy.h>
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/threading.h>
|
||||
|
||||
@@ -57,9 +57,9 @@ MbedTls::MbedTls(void)
|
||||
// mbedTLS's debug level is almost the same as OpenThread's
|
||||
mbedtls_debug_set_threshold(OPENTHREAD_CONFIG_LOG_LEVEL);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT
|
||||
#if OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT && !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
mbedtls_platform_set_calloc_free(Heap::CAlloc, Heap::Free);
|
||||
#endif // OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT
|
||||
#endif // OPENTHREAD_CONFIG_ENABLE_BUILTIN_MBEDTLS_MANAGEMENT && !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
}
|
||||
|
||||
Error MbedTls::MapError(int aMbedTlsError)
|
||||
@@ -69,8 +69,8 @@ Error MbedTls::MapError(int aMbedTlsError)
|
||||
switch (aMbedTlsError)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
|
||||
// case MBEDTLS_ERR_ECP_BAD_INPUT_DATA:
|
||||
// case MBEDTLS_ERR_MPI_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_MPI_INVALID_CHARACTER:
|
||||
#endif
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
@@ -84,7 +84,7 @@ Error MbedTls::MapError(int aMbedTlsError)
|
||||
case MBEDTLS_ERR_PK_INVALID_PUBKEY:
|
||||
case MBEDTLS_ERR_PK_INVALID_ALG:
|
||||
case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
|
||||
case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
|
||||
// case MBEDTLS_ERR_PK_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_X509_SIG_MISMATCH:
|
||||
case MBEDTLS_ERR_X509_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_X509_FILE_IO_ERROR:
|
||||
@@ -102,42 +102,42 @@ Error MbedTls::MapError(int aMbedTlsError)
|
||||
case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_SSL_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
|
||||
case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
|
||||
// case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
|
||||
// case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
|
||||
error = kErrorInvalidArgs;
|
||||
break;
|
||||
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_MPI_ALLOC_FAILED:
|
||||
// case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
|
||||
// case MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL:
|
||||
// case MBEDTLS_ERR_MPI_ALLOC_FAILED:
|
||||
#endif
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_PEM_ALLOC_FAILED:
|
||||
// case MBEDTLS_ERR_PEM_ALLOC_FAILED:
|
||||
case MBEDTLS_ERR_PK_ALLOC_FAILED:
|
||||
case MBEDTLS_ERR_X509_BUFFER_TOO_SMALL:
|
||||
case MBEDTLS_ERR_X509_ALLOC_FAILED:
|
||||
// case MBEDTLS_ERR_X509_ALLOC_FAILED:
|
||||
#endif
|
||||
case MBEDTLS_ERR_SSL_ALLOC_FAILED:
|
||||
// case MBEDTLS_ERR_SSL_ALLOC_FAILED:
|
||||
case MBEDTLS_ERR_SSL_WANT_WRITE:
|
||||
case MBEDTLS_ERR_ENTROPY_MAX_SOURCES:
|
||||
// case MBEDTLS_ERR_ENTROPY_MAX_SOURCES:
|
||||
error = kErrorNoBufs;
|
||||
break;
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE:
|
||||
case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
|
||||
// case MBEDTLS_ERR_PK_SIG_LEN_MISMATCH:
|
||||
case MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE:
|
||||
case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED:
|
||||
#endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
|
||||
case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
|
||||
case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
|
||||
case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
|
||||
// case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
|
||||
// case MBEDTLS_ERR_ENTROPY_SOURCE_FAILED:
|
||||
// case MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED:
|
||||
// case MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE:
|
||||
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
|
||||
case MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED:
|
||||
#endif
|
||||
case MBEDTLS_ERR_THREADING_BAD_INPUT_DATA:
|
||||
// case MBEDTLS_ERR_THREADING_BAD_INPUT_DATA:
|
||||
case MBEDTLS_ERR_THREADING_MUTEX_ERROR:
|
||||
error = kErrorSecurity;
|
||||
break;
|
||||
|
||||
@@ -57,10 +57,11 @@ namespace Storage {
|
||||
*/
|
||||
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.
|
||||
kKeyTypeEcdsa = OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
|
||||
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.
|
||||
kKeyTypeEcdsa = OT_CRYPTO_KEY_TYPE_ECDSA, ///< Key Type: ECDSA.
|
||||
kKeyTypeDerive = OT_CRYPTO_KEY_TYPE_DERIVE, ///< Key Type: Derive.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -72,6 +73,7 @@ enum KeyAlgorithm : uint8_t
|
||||
kKeyAlgorithmAesEcb = OT_CRYPTO_KEY_ALG_AES_ECB, ///< Key Algorithm: AES ECB.
|
||||
kKeyAlgorithmHmacSha256 = OT_CRYPTO_KEY_ALG_HMAC_SHA_256, ///< Key Algorithm: HMAC SHA-256.
|
||||
kKeyAlgorithmEcdsa = OT_CRYPTO_KEY_ALG_ECDSA, ///< Key Algorithm: ECDSA.
|
||||
kKeyAlgorithmHkdfSha256 = OT_CRYPTO_KEY_ALG_HKDF_SHA256, ///< Key Algorithm: HKDF SHA-256.
|
||||
};
|
||||
|
||||
constexpr uint8_t kUsageNone = OT_CRYPTO_KEY_USAGE_NONE; ///< Key Usage: Key Usage is empty.
|
||||
@@ -80,6 +82,7 @@ constexpr uint8_t kUsageEncrypt = OT_CRYPTO_KEY_USAGE_ENCRYPT; ///< Key U
|
||||
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: Sign Hash.
|
||||
constexpr uint8_t kUsageVerifyHash = OT_CRYPTO_KEY_USAGE_VERIFY_HASH; ///< Key Usage: Verify Hash.
|
||||
constexpr uint8_t kUsageDerive = OT_CRYPTO_KEY_USAGE_DERIVE; ///< Key Usage: Derive.
|
||||
|
||||
/**
|
||||
* Defines the key storage types.
|
||||
|
||||
@@ -303,6 +303,7 @@ Instance::Instance(void)
|
||||
, mIsInitialized(false)
|
||||
, mId(Random::NonCrypto::GetUint32())
|
||||
{
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
#if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
|
||||
mCryptoStorageKeyRefManager.SetKeyRefExtraOffset(Crypto::Storage::KeyRefManager::kKeyRefExtraOffset * GetIdx(this));
|
||||
@@ -311,6 +312,7 @@ Instance::Instance(void)
|
||||
"The `KeyRef` values will be shared across different `Instance` objects"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_MTD || OPENTHREAD_FTD) && !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
|
||||
@@ -199,7 +199,7 @@ Error SecureSession::Setup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
mbedtls_ssl_conf_rng(&mConf, Crypto::MbedTls::CryptoSecurePrng, nullptr);
|
||||
// mbedtls_ssl_conf_rng(&mConf, Crypto::MbedTls::CryptoSecurePrng, nullptr);
|
||||
#if (MBEDTLS_VERSION_NUMBER >= 0x03020000)
|
||||
mbedtls_ssl_conf_min_tls_version(&mConf, MBEDTLS_SSL_VERSION_TLS1_2);
|
||||
mbedtls_ssl_conf_max_tls_version(&mConf, MBEDTLS_SSL_VERSION_TLS1_2);
|
||||
@@ -278,7 +278,8 @@ Error SecureSession::Setup(void)
|
||||
|
||||
if (mIsServer)
|
||||
{
|
||||
rval = mbedtls_ssl_cookie_setup(&mCookieCtx, Crypto::MbedTls::CryptoSecurePrng, nullptr);
|
||||
// rval = mbedtls_ssl_cookie_setup(&mCookieCtx, Crypto::MbedTls::CryptoSecurePrng, nullptr);
|
||||
rval = mbedtls_ssl_cookie_setup(&mCookieCtx);
|
||||
VerifyOrExit(rval == 0);
|
||||
|
||||
mbedtls_ssl_conf_dtls_cookies(&mConf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &mCookieCtx);
|
||||
|
||||
@@ -176,8 +176,6 @@ KeyManager::KeyManager(Instance &aInstance)
|
||||
, mKekFrameCounter(0)
|
||||
, mIsPskcSet(false)
|
||||
{
|
||||
otPlatCryptoInit();
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
{
|
||||
NetworkKey networkKey;
|
||||
|
||||
@@ -42,6 +42,8 @@ add_library(ot-fake-platform
|
||||
)
|
||||
target_link_libraries(ot-fake-platform
|
||||
ot-config
|
||||
${OT_MBEDTLS}
|
||||
openthread-native-its-ram
|
||||
)
|
||||
|
||||
add_library(ot-fake-ftd INTERFACE)
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
#include <openthread/platform/trel.h>
|
||||
#include <openthread/platform/udp.h>
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
#include <psa/crypto.h>
|
||||
#endif
|
||||
|
||||
using namespace ot;
|
||||
|
||||
bool operator<(const otExtAddress &aLeft, const otExtAddress &aRight)
|
||||
@@ -482,6 +486,36 @@ otError otPlatEntropyGet(uint8_t *aOutput, uint16_t aOutputLength)
|
||||
return error;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
/**
|
||||
* When OpenThread is compiled with the PSA Crypto backend using Mbed TLS 3.x, there is no
|
||||
* API to configure a dedicated non-default entropy source. It is documented that a future version of
|
||||
* Mbed TLS (likely 4.x) will include a PSA interface for configuring entropy sources.
|
||||
*
|
||||
* For now, we need to define the external RNG. Since the implementation of `otPlatEntropyGet` already
|
||||
* uses CSPRNG, we will call it here as well.
|
||||
*/
|
||||
extern "C" psa_status_t mbedtls_psa_external_get_random(mbedtls_psa_external_random_context_t *context,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(context);
|
||||
|
||||
otError error;
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
|
||||
error = otPlatEntropyGet(output, (uint16_t)output_size);
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
*output_length = output_size;
|
||||
status = PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
void otPlatDiagSetOutputCallback(otInstance *, otPlatDiagOutputCallback, void *) {}
|
||||
|
||||
void otPlatDiagModeSet(bool) {}
|
||||
|
||||
@@ -101,6 +101,7 @@ endif()
|
||||
target_link_libraries(ot-test-platform-ftd
|
||||
PRIVATE
|
||||
ot-config
|
||||
mbedtls
|
||||
${OT_MBEDTLS}
|
||||
)
|
||||
|
||||
@@ -116,10 +117,11 @@ set(COMMON_LIBS
|
||||
ot-test-platform-ftd
|
||||
openthread-ftd
|
||||
ot-test-platform-ftd
|
||||
${OT_MBEDTLS}
|
||||
ot-config
|
||||
openthread-ftd
|
||||
openthread-url
|
||||
${OT_MBEDTLS}
|
||||
openthread-native-its-ram
|
||||
)
|
||||
|
||||
set(COMMON_LIBS_RCP
|
||||
|
||||
+67
-9
@@ -41,7 +41,7 @@ namespace ot {
|
||||
*/
|
||||
void TestMacBeaconFrame(void)
|
||||
{
|
||||
uint8_t key[] = {
|
||||
uint8_t rawKey[] = {
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
};
|
||||
|
||||
@@ -57,19 +57,34 @@ void TestMacBeaconFrame(void)
|
||||
0xAC, 0x02, 0x05, 0x00, 0x00, 0x00, 0x55, 0xCF, 0x00, 0x00, 0x51, 0x52,
|
||||
0x53, 0x54, 0x22, 0x3B, 0xC1, 0xEC, 0x84, 0x1A, 0xB5, 0x53};
|
||||
|
||||
uint8_t nonce[] = {
|
||||
0xAC, 0xDE, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x02,
|
||||
};
|
||||
|
||||
otInstance *instance = testInitInstance();
|
||||
Crypto::AesCcm aesCcm;
|
||||
uint32_t headerLength = sizeof(test) - 8;
|
||||
uint32_t payloadLength = 0;
|
||||
uint8_t tagLength = 8;
|
||||
|
||||
uint8_t nonce[] = {
|
||||
0xAC, 0xDE, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x02,
|
||||
};
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Key key;
|
||||
Crypto::Storage::KeyRef keyRef;
|
||||
#endif
|
||||
|
||||
VerifyOrQuit(instance != nullptr);
|
||||
|
||||
aesCcm.SetKey(key, sizeof(key));
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeAes, Crypto::Storage::kKeyAlgorithmAesEcb,
|
||||
Crypto::Storage::kUsageEncrypt, Crypto::Storage::kTypeVolatile, rawKey,
|
||||
sizeof(rawKey)));
|
||||
|
||||
key.SetAsKeyRef(keyRef);
|
||||
aesCcm.SetKey(key);
|
||||
#else
|
||||
aesCcm.SetKey(rawKey, sizeof(rawKey));
|
||||
#endif
|
||||
|
||||
aesCcm.Init(headerLength, payloadLength, tagLength, nonce, sizeof(nonce));
|
||||
aesCcm.Header(test, headerLength);
|
||||
VerifyOrQuit(aesCcm.GetTagLength() == tagLength);
|
||||
@@ -84,6 +99,10 @@ void TestMacBeaconFrame(void)
|
||||
|
||||
VerifyOrQuit(memcmp(test, decrypted, sizeof(decrypted)) == 0);
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
#endif
|
||||
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
@@ -92,7 +111,7 @@ void TestMacBeaconFrame(void)
|
||||
*/
|
||||
void TestMacCommandFrame(void)
|
||||
{
|
||||
uint8_t key[] = {
|
||||
uint8_t rawKey[] = {
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
};
|
||||
|
||||
@@ -128,9 +147,24 @@ void TestMacCommandFrame(void)
|
||||
Message *message;
|
||||
Crypto::AesCcm aesCcm;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Key key;
|
||||
Crypto::Storage::KeyRef keyRef;
|
||||
#endif
|
||||
|
||||
VerifyOrQuit(instance != nullptr);
|
||||
|
||||
aesCcm.SetKey(key, sizeof(key));
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeAes, Crypto::Storage::kKeyAlgorithmAesEcb,
|
||||
Crypto::Storage::kUsageEncrypt, Crypto::Storage::kTypeVolatile, rawKey,
|
||||
sizeof(rawKey)));
|
||||
|
||||
key.SetAsKeyRef(keyRef);
|
||||
aesCcm.SetKey(key);
|
||||
#else
|
||||
aesCcm.SetKey(rawKey, sizeof(rawKey));
|
||||
#endif
|
||||
|
||||
aesCcm.Init(kHeaderLength, kPayloadLength, kTagLength, nonce, sizeof(nonce));
|
||||
aesCcm.Header(test, kHeaderLength);
|
||||
aesCcm.Payload(test + kHeaderLength, test + kHeaderLength, kPayloadLength, Crypto::AesCcm::kEncrypt);
|
||||
@@ -171,6 +205,11 @@ void TestMacCommandFrame(void)
|
||||
VerifyOrQuit(message->Compare(0, decrypted));
|
||||
|
||||
message->Free();
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
#endif
|
||||
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
@@ -182,7 +221,7 @@ void TestInPlaceAesCcmProcessing(void)
|
||||
static constexpr uint16_t kTagLength = 4;
|
||||
static constexpr uint32_t kHeaderLength = 19;
|
||||
|
||||
static const uint8_t kKey[] = {
|
||||
static const uint8_t kRawKey[] = {
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
};
|
||||
|
||||
@@ -200,12 +239,26 @@ void TestInPlaceAesCcmProcessing(void)
|
||||
Message *message;
|
||||
Message *messageClone;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Key key;
|
||||
Crypto::Storage::KeyRef keyRef;
|
||||
#endif
|
||||
|
||||
VerifyOrQuit(instance != nullptr);
|
||||
|
||||
message = instance->Get<MessagePool>().Allocate(Message::kTypeIp6);
|
||||
VerifyOrQuit(message != nullptr);
|
||||
|
||||
aesCcm.SetKey(kKey, sizeof(kKey));
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeAes, Crypto::Storage::kKeyAlgorithmAesEcb,
|
||||
Crypto::Storage::kUsageEncrypt, Crypto::Storage::kTypeVolatile, kRawKey,
|
||||
sizeof(kRawKey)));
|
||||
|
||||
key.SetAsKeyRef(keyRef);
|
||||
aesCcm.SetKey(key);
|
||||
#else
|
||||
aesCcm.SetKey(kRawKey, sizeof(kRawKey));
|
||||
#endif
|
||||
|
||||
for (uint16_t msgLength : kMessageLengths)
|
||||
{
|
||||
@@ -251,6 +304,11 @@ void TestInPlaceAesCcmProcessing(void)
|
||||
}
|
||||
|
||||
message->Free();
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
#endif
|
||||
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,6 +135,9 @@ void otPlatFree(void *aPtr)
|
||||
|
||||
free(aPtr);
|
||||
}
|
||||
|
||||
void *otPlatCryptoCAlloc(size_t aNum, size_t aSize) { return calloc(aNum, aSize); }
|
||||
void otPlatCryptoFree(void *aPtr) { free(aPtr); }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
|
||||
|
||||
@@ -77,7 +77,13 @@ void TestEcdsaVector(void)
|
||||
|
||||
Instance *instance = testInitInstance();
|
||||
|
||||
Ecdsa::P256::KeyPair keyPair;
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Ecdsa::P256::KeyPairAsRef keyPair;
|
||||
Crypto::Storage::KeyRef keyRef;
|
||||
#else
|
||||
Ecdsa::P256::KeyPair keyPair;
|
||||
#endif
|
||||
|
||||
Ecdsa::P256::PublicKey publicKey;
|
||||
Ecdsa::P256::Signature signature;
|
||||
Sha256 sha256;
|
||||
@@ -89,10 +95,18 @@ void TestEcdsaVector(void)
|
||||
printf("Test ECDA with test vector from RFC 6979 (A.2.5)\n");
|
||||
|
||||
printf("\nLoading key-pair ----------------------------------------------------------\n");
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(keyRef, Storage::kKeyTypeEcdsa, Storage::kKeyAlgorithmEcdsa,
|
||||
(Storage::kUsageSignHash | Storage::kUsageVerifyHash),
|
||||
Storage::kTypeVolatile, kKeyPairInfo, sizeof(kKeyPairInfo)));
|
||||
keyPair.SetKeyRef(keyRef);
|
||||
#else
|
||||
memcpy(keyPair.GetDerBytes(), kKeyPairInfo, sizeof(kKeyPairInfo));
|
||||
keyPair.SetDerLength(sizeof(kKeyPairInfo));
|
||||
|
||||
DumpBuffer("KeyPair", keyPair.GetDerBytes(), keyPair.GetDerLength());
|
||||
#endif
|
||||
|
||||
SuccessOrQuit(keyPair.GetPublicKey(publicKey));
|
||||
DumpBuffer("PublicKey", publicKey.GetBytes(), Ecdsa::P256::PublicKey::kSize);
|
||||
@@ -109,6 +123,7 @@ void TestEcdsaVector(void)
|
||||
DumpBuffer("Hash", hash.GetBytes(), sizeof(hash));
|
||||
|
||||
printf("\nSign the message ----------------------------------------------------------\n");
|
||||
|
||||
SuccessOrQuit(keyPair.Sign(hash, signature));
|
||||
DumpBuffer("Signature", signature.GetBytes(), sizeof(signature));
|
||||
|
||||
@@ -135,7 +150,13 @@ void TestEcdsaKeyGenerationSignAndVerify(void)
|
||||
|
||||
const char kMessage[] = "You are not a drop in the ocean. You are the entire ocean in a drop.";
|
||||
|
||||
Ecdsa::P256::KeyPair keyPair;
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::KeyRef keyRef = 0x1234;
|
||||
Ecdsa::P256::KeyPairAsRef keyPair(keyRef);
|
||||
#else
|
||||
Ecdsa::P256::KeyPair keyPair;
|
||||
#endif
|
||||
|
||||
Ecdsa::P256::PublicKey publicKey;
|
||||
Ecdsa::P256::Signature signature;
|
||||
Sha256 sha256;
|
||||
@@ -149,7 +170,9 @@ void TestEcdsaKeyGenerationSignAndVerify(void)
|
||||
printf("\nGenerating key-pair -------------------------------------------------------\n");
|
||||
SuccessOrQuit(keyPair.Generate());
|
||||
|
||||
#if !OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
DumpBuffer("KeyPair", keyPair.GetDerBytes(), keyPair.GetDerLength());
|
||||
#endif
|
||||
|
||||
SuccessOrQuit(keyPair.GetPublicKey(publicKey));
|
||||
DumpBuffer("PublicKey", publicKey.GetBytes(), Ecdsa::P256::PublicKey::kSize);
|
||||
@@ -175,6 +198,10 @@ void TestEcdsaKeyGenerationSignAndVerify(void)
|
||||
VerifyOrQuit(publicKey.Verify(hash, signature) != kErrorNone, "PublicKey::Verify() passed for invalid signature");
|
||||
printf("\nSignature verification correctly failed with incorrect hash/signature.\n\n");
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
#endif
|
||||
|
||||
testFreeInstance(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,11 @@ struct TestVector
|
||||
uint16_t mOutKeyLength;
|
||||
};
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
void TestHkdfSha256(Crypto::Storage::KeyAlgorithm aAlgorithm)
|
||||
#else
|
||||
void TestHkdfSha256(void)
|
||||
#endif
|
||||
{
|
||||
enum
|
||||
{
|
||||
@@ -134,6 +138,10 @@ void TestHkdfSha256(void)
|
||||
uint8_t outKey[kMaxOuttKey];
|
||||
Crypto::Key testInputKey;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::KeyRef keyRef;
|
||||
#endif
|
||||
|
||||
printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||
DumpBuffer("\nInput Key", test->mInKey, test->mInKeyLength);
|
||||
DumpBuffer("\nSalt", test->mSalt, test->mSaltLength);
|
||||
@@ -141,9 +149,30 @@ 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;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
if (aAlgorithm == Crypto::Storage::kKeyAlgorithmHkdfSha256)
|
||||
{
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(
|
||||
keyRef, Crypto::Storage::kKeyTypeDerive, Crypto::Storage::kKeyAlgorithmHkdfSha256,
|
||||
Crypto::Storage::kUsageDerive, Crypto::Storage::kTypeVolatile, test->mInKey, test->mInKeyLength));
|
||||
}
|
||||
else if (aAlgorithm == Crypto::Storage::kKeyAlgorithmHmacSha256)
|
||||
{
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(keyRef, Crypto::Storage::kKeyTypeHmac,
|
||||
Crypto::Storage::kKeyAlgorithmHmacSha256,
|
||||
Crypto::Storage::kUsageSignHash | Crypto::Storage::kUsageExport,
|
||||
Crypto::Storage::kTypeVolatile, test->mInKey, test->mInKeyLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyOrQuit(false);
|
||||
}
|
||||
|
||||
testInputKey.SetAsKeyRef(keyRef);
|
||||
#else
|
||||
testInputKey.Set(test->mInKey, test->mInKeyLength);
|
||||
#endif
|
||||
|
||||
hkdf.Extract(test->mSalt, test->mSaltLength, testInputKey);
|
||||
hkdf.Expand(test->mInfo, test->mInfoLength, outKey, test->mOutKeyLength);
|
||||
@@ -156,6 +185,10 @@ void TestHkdfSha256(void)
|
||||
{
|
||||
VerifyOrQuit(outKey[i] == kFillByte, "HKDF-SHA-256 wrote beyond output key length");
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(keyRef);
|
||||
#endif
|
||||
}
|
||||
|
||||
testFreeInstance(instance);
|
||||
@@ -165,7 +198,13 @@ void TestHkdfSha256(void)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
ot::TestHkdfSha256(ot::Crypto::Storage::kKeyAlgorithmHkdfSha256);
|
||||
ot::TestHkdfSha256(ot::Crypto::Storage::kKeyAlgorithmHmacSha256);
|
||||
#else
|
||||
ot::TestHkdfSha256();
|
||||
#endif
|
||||
|
||||
printf("All tests passed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -141,10 +141,15 @@ void TestHmacSha256(void)
|
||||
{
|
||||
struct TestCase
|
||||
{
|
||||
otCryptoKey mKey;
|
||||
const uint8_t *mKey;
|
||||
uint16_t mKeyLength;
|
||||
const void *mData;
|
||||
uint16_t mDataLength;
|
||||
otCryptoSha256Hash mHash;
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::KeyRef mKeyRef;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Test-cases from RFC 4231.
|
||||
@@ -218,12 +223,12 @@ void TestHmacSha256(void)
|
||||
0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93, 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2,
|
||||
}};
|
||||
|
||||
static const TestCase kTestCases[] = {
|
||||
{{&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},
|
||||
static TestCase kTestCases[] = {
|
||||
{kKey1, sizeof(kKey1), kData1, sizeof(kData1) - 1, kHash1},
|
||||
{reinterpret_cast<const uint8_t *>(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},
|
||||
};
|
||||
|
||||
Instance *instance = testInitInstance();
|
||||
@@ -239,12 +244,23 @@ void TestHmacSha256(void)
|
||||
messagePool = &instance->Get<MessagePool>();
|
||||
VerifyOrQuit((message = messagePool->Allocate(Message::kTypeIp6)) != nullptr);
|
||||
|
||||
for (const TestCase &testCase : kTestCases)
|
||||
for (TestCase &testCase : kTestCases)
|
||||
{
|
||||
Crypto::HmacSha256 hmac;
|
||||
Crypto::HmacSha256::Hash hash;
|
||||
Crypto::Key key;
|
||||
|
||||
hmac.Start(static_cast<const Crypto::Key &>(testCase.mKey));
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
SuccessOrQuit(Crypto::Storage::ImportKey(
|
||||
testCase.mKeyRef, Crypto::Storage::kKeyTypeHmac, Crypto::Storage::kKeyAlgorithmHmacSha256,
|
||||
Crypto::Storage::kUsageSignHash, Crypto::Storage::kTypeVolatile, testCase.mKey, testCase.mKeyLength));
|
||||
|
||||
key.SetAsKeyRef(testCase.mKeyRef);
|
||||
#else
|
||||
key.Set(testCase.mKey, testCase.mKeyLength);
|
||||
#endif
|
||||
|
||||
hmac.Start(key);
|
||||
hmac.Update(testCase.mData, testCase.mDataLength);
|
||||
hmac.Finish(hash);
|
||||
|
||||
@@ -255,7 +271,7 @@ void TestHmacSha256(void)
|
||||
|
||||
index = 0;
|
||||
|
||||
for (const TestCase &testCase : kTestCases)
|
||||
for (TestCase &testCase : kTestCases)
|
||||
{
|
||||
SuccessOrQuit(message->Append("Hello"));
|
||||
offsets[index++] = message->GetLength();
|
||||
@@ -269,12 +285,23 @@ void TestHmacSha256(void)
|
||||
{
|
||||
Crypto::HmacSha256 hmac;
|
||||
Crypto::HmacSha256::Hash hash;
|
||||
Crypto::Key key;
|
||||
|
||||
hmac.Start(static_cast<const Crypto::Key &>(testCase.mKey));
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
key.SetAsKeyRef(testCase.mKeyRef);
|
||||
#else
|
||||
key.Set(testCase.mKey, testCase.mKeyLength);
|
||||
#endif
|
||||
|
||||
hmac.Start(key);
|
||||
hmac.Update(*message, offsets[index++], testCase.mDataLength);
|
||||
hmac.Finish(hash);
|
||||
|
||||
VerifyOrQuit(hash == static_cast<const Crypto::HmacSha256::Hash &>(testCase.mHash));
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
Crypto::Storage::DestroyKey(testCase.mKeyRef);
|
||||
#endif
|
||||
}
|
||||
|
||||
message->Free();
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include <openthread/platform/ble.h>
|
||||
#endif
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA)
|
||||
#include <psa/crypto.h>
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
FLASH_SWAP_SIZE = 2048,
|
||||
@@ -226,6 +230,36 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if (OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA) && defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
|
||||
/**
|
||||
* When OpenThread is compiled with the PSA Crypto backend using Mbed TLS 3.x, there is no
|
||||
* API to configure a dedicated non-default entropy source. It is documented that a future version of
|
||||
* Mbed TLS (likely 4.x) will include a PSA interface for configuring entropy sources.
|
||||
*
|
||||
* For now, we need to define the external RNG. Since the implementation of `otPlatEntropyGet` already
|
||||
* uses CSPRNG, we will call it here as well.
|
||||
*/
|
||||
extern "C" psa_status_t mbedtls_psa_external_get_random(mbedtls_psa_external_random_context_t *context,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(context);
|
||||
|
||||
otError error;
|
||||
psa_status_t status = PSA_ERROR_GENERIC_ERROR;
|
||||
|
||||
error = otPlatEntropyGet(output, (uint16_t)output_size);
|
||||
if (error == OT_ERROR_NONE)
|
||||
{
|
||||
*output_length = output_size;
|
||||
status = PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void DiagOutput(const char *aFormat, ...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -512,91 +546,6 @@ OT_TOOL_WEAK void otPlatInfraIfDhcp6PdClientSend(otInstance *aInstance,
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE && OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_CLIENT_ENABLE
|
||||
#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, otPlatCryptoEcdsaPublicKey *aPublicKey)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aPublicKey);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef,
|
||||
const otPlatCryptoSha256Hash *aHash,
|
||||
const otPlatCryptoEcdsaSignature *aSignature)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aKeyRef);
|
||||
OT_UNUSED_VARIABLE(aHash);
|
||||
OT_UNUSED_VARIABLE(aSignature);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
|
||||
|
||||
otError otPlatRadioSetCcaEnergyDetectThreshold(otInstance *aInstance, int8_t aThreshold)
|
||||
{
|
||||
OT_UNUSED_VARIABLE(aInstance);
|
||||
|
||||
@@ -131,6 +131,9 @@ void otPlatFree(void *aPtr)
|
||||
|
||||
free(aPtr);
|
||||
}
|
||||
|
||||
void *otPlatCryptoCAlloc(size_t aNum, size_t aSize) { return calloc(aNum, aSize); }
|
||||
void otPlatCryptoFree(void *aPtr) { free(aPtr); }
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED
|
||||
|
||||
Vendored
+1
@@ -28,6 +28,7 @@
|
||||
|
||||
if(NOT OT_EXTERNAL_MBEDTLS)
|
||||
add_subdirectory(mbedtls)
|
||||
add_subdirectory(mbedtls/native_its)
|
||||
endif()
|
||||
|
||||
add_subdirectory(tcplp)
|
||||
|
||||
Vendored
+28
-6
@@ -27,8 +27,10 @@
|
||||
#
|
||||
|
||||
set(OT_MBEDTLS_DEFAULT_CONFIG_FILE \"openthread-mbedtls-config.h\")
|
||||
set(OT_PSA_CRYPTO_DEFAULT_CONFIG_FILE \"openthread-psa-crypto-config.h\")
|
||||
|
||||
set(OT_MBEDTLS_CONFIG_FILE "" CACHE STRING "The mbedTLS config file")
|
||||
set(OT_PSA_CRYPTO_CONFIG_FILE "" CACHE STRING "The PSA Crypto config file")
|
||||
|
||||
set(ENABLE_TESTING OFF CACHE BOOL "Disable mbedtls test" FORCE)
|
||||
set(ENABLE_PROGRAMS OFF CACHE BOOL "Disable mbetls program" FORCE)
|
||||
@@ -42,6 +44,8 @@ if(UNIFDEF_EXE)
|
||||
endif()
|
||||
find_program(SED_EXE sed)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-but-set-variable")
|
||||
|
||||
string(REPLACE "-Wconversion" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
string(REPLACE "-Wconversion" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
@@ -63,15 +67,29 @@ if(UNIFDEFALL_EXE AND SED_EXE AND UNIFDEF_VERSION VERSION_GREATER_EQUAL 2.10)
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
|
||||
add_custom_target(openthread-mbedtls-config
|
||||
DEPENDS openthread-mbedtls-config.h)
|
||||
add_custom_command(OUTPUT openthread-psa-crypto-config.h
|
||||
COMMAND ${UNIFDEFALL_EXE}
|
||||
"'-D$<JOIN:$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>,';'-D>'"
|
||||
"-I$<JOIN:$<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>,;-I>"
|
||||
"-I$<JOIN:${OT_PUBLIC_INCLUDES},;-I>"
|
||||
"-I${CMAKE_CURRENT_SOURCE_DIR}/repo/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/psa-crypto-config.h" |
|
||||
${SED_EXE} '/openthread-core-config\.h/d' >
|
||||
openthread-psa-crypto-config.h
|
||||
MAIN_DEPENDENCY psa-crypto-config.h
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
|
||||
add_dependencies(ot-config openthread-mbedtls-config)
|
||||
add_dependencies(mbedtls openthread-mbedtls-config)
|
||||
add_dependencies(mbedx509 openthread-mbedtls-config)
|
||||
add_dependencies(mbedcrypto openthread-mbedtls-config)
|
||||
add_custom_target(openthread-mbedtls-config
|
||||
DEPENDS openthread-mbedtls-config.h openthread-psa-crypto-config.h)
|
||||
|
||||
add_dependencies(ot-config openthread-mbedtls-config openthread-psa-crypto-config)
|
||||
add_dependencies(mbedtls openthread-mbedtls-config openthread-psa-crypto-config)
|
||||
add_dependencies(mbedx509 openthread-mbedtls-config openthread-psa-crypto-config)
|
||||
add_dependencies(mbedcrypto openthread-mbedtls-config openthread-psa-crypto-config)
|
||||
else()
|
||||
configure_file(mbedtls-config.h openthread-mbedtls-config.h COPYONLY)
|
||||
configure_file(psa-crypto-config.h openthread-psa-crypto-config.h COPYONLY)
|
||||
endif()
|
||||
|
||||
target_include_directories(ot-config SYSTEM
|
||||
@@ -82,6 +100,7 @@ target_include_directories(ot-config SYSTEM
|
||||
target_compile_definitions(mbedtls
|
||||
PUBLIC
|
||||
"MBEDTLS_CONFIG_FILE=$<IF:$<BOOL:${OT_MBEDTLS_CONFIG_FILE}>,${OT_MBEDTLS_CONFIG_FILE},${OT_MBEDTLS_DEFAULT_CONFIG_FILE}>"
|
||||
"MBEDTLS_PSA_CRYPTO_CONFIG_FILE=$<IF:$<BOOL:${OT_PSA_CRYPTO_CONFIG_FILE}>,${OT_PSA_CRYPTO_CONFIG_FILE},${OT_PSA_CRYPTO_DEFAULT_CONFIG_FILE}>"
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
@@ -96,6 +115,7 @@ target_include_directories(mbedtls
|
||||
target_compile_definitions(mbedx509
|
||||
PUBLIC
|
||||
"MBEDTLS_CONFIG_FILE=$<IF:$<BOOL:${OT_MBEDTLS_CONFIG_FILE}>,${OT_MBEDTLS_CONFIG_FILE},${OT_MBEDTLS_DEFAULT_CONFIG_FILE}>"
|
||||
"MBEDTLS_PSA_CRYPTO_CONFIG_FILE=$<IF:$<BOOL:${OT_PSA_CRYPTO_CONFIG_FILE}>,${OT_PSA_CRYPTO_CONFIG_FILE},${OT_PSA_CRYPTO_DEFAULT_CONFIG_FILE}>"
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
@@ -110,6 +130,7 @@ target_include_directories(mbedx509
|
||||
target_compile_definitions(mbedcrypto
|
||||
PUBLIC
|
||||
"MBEDTLS_CONFIG_FILE=$<IF:$<BOOL:${OT_MBEDTLS_CONFIG_FILE}>,${OT_MBEDTLS_CONFIG_FILE},${OT_MBEDTLS_DEFAULT_CONFIG_FILE}>"
|
||||
"MBEDTLS_PSA_CRYPTO_CONFIG_FILE=$<IF:$<BOOL:${OT_PSA_CRYPTO_CONFIG_FILE}>,${OT_PSA_CRYPTO_CONFIG_FILE},${OT_PSA_CRYPTO_DEFAULT_CONFIG_FILE}>"
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
@@ -119,4 +140,5 @@ target_include_directories(mbedcrypto
|
||||
PRIVATE
|
||||
${OT_PUBLIC_INCLUDES}
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
native_its/include
|
||||
)
|
||||
|
||||
Vendored
+104
-49
@@ -40,7 +40,11 @@
|
||||
#include <openthread/platform/logging.h>
|
||||
#include <openthread/platform/memory.h>
|
||||
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
|
||||
// ==============================================================================
|
||||
// mbedTLS legacy/PSA configuration
|
||||
// ==============================================================================
|
||||
|
||||
#if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_MBEDTLS
|
||||
|
||||
#define MBEDTLS_AES_C
|
||||
#if (MBEDTLS_VERSION_NUMBER >= 0x03050000)
|
||||
@@ -66,19 +70,46 @@
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
#define MBEDTLS_HAVE_ASM
|
||||
#define MBEDTLS_HMAC_DRBG_C
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
|
||||
#define MBEDTLS_MD_C
|
||||
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
#define MBEDTLS_PLATFORM_MEMORY
|
||||
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
#define MBEDTLS_SHA224_C
|
||||
#define MBEDTLS_SHA256_C
|
||||
#define MBEDTLS_SHA256_SMALLER
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE || OPENTHREAD_CONFIG_TLS_ENABLE
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||
#define MBEDTLS_GCM_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE
|
||||
#define MBEDTLS_ECDSA_DETERMINISTIC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
#define MBEDTLS_USE_PSA_CRYPTO
|
||||
|
||||
#define MBEDTLS_PSA_CRYPTO_C
|
||||
#define MBEDTLS_PSA_CRYPTO_CLIENT
|
||||
#define MBEDTLS_PSA_CRYPTO_STORAGE_C
|
||||
#define MBEDTLS_PSA_CRYPTO_CONFIG
|
||||
#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
|
||||
|
||||
#endif
|
||||
|
||||
// ==============================================================================
|
||||
// SSL configuration
|
||||
// ==============================================================================
|
||||
|
||||
#define MBEDTLS_SSL_CLI_C
|
||||
#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
|
||||
#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
|
||||
@@ -93,6 +124,12 @@
|
||||
#define MBEDTLS_SSL_SRV_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||
#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
|
||||
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
|
||||
#endif
|
||||
@@ -101,45 +138,6 @@
|
||||
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||
#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
|
||||
#define MBEDTLS_GCM_C
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_X509_USE_C
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_ECDH_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
#if OPENTHREAD_CONFIG_DETERMINISTIC_ECDSA_ENABLE
|
||||
#define MBEDTLS_ECDSA_DETERMINISTIC
|
||||
#endif
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_PK_WRITE_C
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */
|
||||
#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */
|
||||
#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */
|
||||
#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */
|
||||
#define MBEDTLS_ENTROPY_MAX_SOURCES 1 /**< Maximum number of sources supported */
|
||||
|
||||
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC otPlatCAlloc /**< Default allocator to use, can be undefined */
|
||||
#define MBEDTLS_PLATFORM_STD_FREE otPlatFree /**< Default free to use, can be undefined */
|
||||
#else
|
||||
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
|
||||
#define MBEDTLS_SSL_MAX_CONTENT_LEN 2000 /**< Maxium fragment length in bytes */
|
||||
#elif OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
|
||||
@@ -152,6 +150,63 @@
|
||||
#define MBEDTLS_SSL_OUT_CONTENT_LEN MBEDTLS_SSL_MAX_CONTENT_LEN
|
||||
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
|
||||
|
||||
// ==============================================================================
|
||||
// x509 & PK configuration
|
||||
// ==============================================================================
|
||||
|
||||
#define MBEDTLS_OID_C
|
||||
#define MBEDTLS_PK_C
|
||||
#define MBEDTLS_PK_PARSE_C
|
||||
|
||||
#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE || OPENTHREAD_CONFIG_TLS_ENABLE
|
||||
#define MBEDTLS_BASE64_C
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_X509_USE_C
|
||||
#define MBEDTLS_X509_CRT_PARSE_C
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_ECDSA_ENABLE
|
||||
#define MBEDTLS_PEM_PARSE_C
|
||||
#define MBEDTLS_PK_WRITE_C
|
||||
#endif
|
||||
|
||||
// ==============================================================================
|
||||
// MPI configuration
|
||||
// ==============================================================================
|
||||
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */
|
||||
#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */
|
||||
|
||||
// ==============================================================================
|
||||
// ECP configuration
|
||||
// ==============================================================================
|
||||
|
||||
#if (MBEDTLS_VERSION_NUMBER < 0x03000000)
|
||||
#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */
|
||||
#endif
|
||||
#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */
|
||||
|
||||
// ==============================================================================
|
||||
// Platform configuration
|
||||
// ==============================================================================
|
||||
|
||||
#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf
|
||||
|
||||
#if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
|
||||
#define MBEDTLS_PLATFORM_STD_CALLOC otPlatCryptoCAlloc /**< Default allocator to use, can be undefined */
|
||||
#define MBEDTLS_PLATFORM_STD_FREE otPlatCryptoFree /**< Default free to use, can be undefined */
|
||||
#else
|
||||
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
|
||||
#endif
|
||||
|
||||
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
#define MBEDTLS_PLATFORM_C
|
||||
#define MBEDTLS_PLATFORM_MEMORY
|
||||
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
|
||||
#define MBEDTLS_ENTROPY_MAX_SOURCES 1
|
||||
|
||||
// Spans multiple lines to avoid being processed by unifdef
|
||||
#if defined(\
|
||||
MBEDTLS_USER_CONFIG_FILE)
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
# Copyright (c) 2025, 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.
|
||||
#
|
||||
|
||||
|
||||
config("openthread-native-its-config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("openthread-native-its-file") {
|
||||
sources = [
|
||||
"src/file/its_file.c"
|
||||
]
|
||||
|
||||
configs += [
|
||||
":openthread-native-its-config",
|
||||
]
|
||||
|
||||
defines = [ "OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_FILE=1" ]
|
||||
}
|
||||
|
||||
static_library("openthread-native-its-ram") {
|
||||
sources = [
|
||||
"src/ram/its_ram.c"
|
||||
]
|
||||
|
||||
configs += [
|
||||
":openthread-native-its-config",
|
||||
]
|
||||
|
||||
defines = [ "OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_RAM=1" ]
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#
|
||||
# Copyright (c) 2025, 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.
|
||||
#
|
||||
|
||||
add_library(openthread-native-its-file STATIC)
|
||||
target_sources(openthread-native-its-file PRIVATE
|
||||
src/file/its_file.c
|
||||
)
|
||||
target_include_directories(openthread-native-its-file PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
${OT_PUBLIC_INCLUDES}
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_compile_definitions(openthread-native-its-file
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
|
||||
PUBLIC
|
||||
OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_FILE=1
|
||||
)
|
||||
|
||||
add_library(openthread-native-its-ram STATIC)
|
||||
target_sources(openthread-native-its-ram PRIVATE
|
||||
src/ram/its_ram.c
|
||||
)
|
||||
target_include_directories(openthread-native-its-ram PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
${OT_PUBLIC_INCLUDES}
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_compile_definitions(openthread-native-its-ram
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:ot-config,INTERFACE_COMPILE_DEFINITIONS>
|
||||
PUBLIC
|
||||
OPENTHREAD_PSA_CRYPTO_NATIVE_ITS_RAM=1
|
||||
)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
#ifndef PSA_ERROR_H__
|
||||
#define PSA_ERROR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int32_t psa_status_t;
|
||||
|
||||
#define PSA_SUCCESS ((psa_status_t)0)
|
||||
#define PSA_ERROR_GENERIC_ERROR ((psa_status_t)-132)
|
||||
#define PSA_ERROR_NOT_PERMITTED ((psa_status_t)-133)
|
||||
#define PSA_ERROR_NOT_SUPPORTED ((psa_status_t)-134)
|
||||
#define PSA_ERROR_INVALID_ARGUMENT ((psa_status_t)-135)
|
||||
#define PSA_ERROR_ALREADY_EXISTS ((psa_status_t)-139)
|
||||
#define PSA_ERROR_DOES_NOT_EXIST ((psa_status_t)-140)
|
||||
#define PSA_ERROR_INSUFFICIENT_STORAGE ((psa_status_t)-142)
|
||||
#define PSA_ERROR_STORAGE_FAILURE ((psa_status_t)-146)
|
||||
#define PSA_ERROR_INVALID_SIGNATURE ((psa_status_t)-149)
|
||||
#define PSA_ERROR_DATA_CORRUPT ((psa_status_t)-152)
|
||||
|
||||
#endif /* PSA_ERROR_H__ */
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
#ifndef PSA_INTERNAL_TRUSTED_STORAGE_H__
|
||||
#define PSA_INTERNAL_TRUSTED_STORAGE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/error.h"
|
||||
|
||||
/** \brief Flags used when creating a data entry
|
||||
*/
|
||||
typedef uint32_t psa_storage_create_flags_t;
|
||||
|
||||
/** \brief A type for UIDs used for identifying data
|
||||
*/
|
||||
typedef uint64_t psa_storage_uid_t;
|
||||
|
||||
#define PSA_STORAGE_FLAG_NONE 0 /**< No flags to pass */
|
||||
#define PSA_STORAGE_FLAG_WRITE_ONCE (1 << 0) /**< The data associated with the uid will not be able to be modified or deleted. Intended to be used to set bits in `psa_storage_create_flags_t`*/
|
||||
|
||||
/**
|
||||
* \brief A container for metadata associated with a specific uid
|
||||
*/
|
||||
struct psa_storage_info_t {
|
||||
uint32_t size; /**< The size of the data associated with a uid **/
|
||||
psa_storage_create_flags_t flags; /**< The flags set when the uid was created **/
|
||||
};
|
||||
|
||||
/** Flag indicating that \ref psa_storage_create and \ref psa_storage_set_extended are supported */
|
||||
#define PSA_STORAGE_SUPPORT_SET_EXTENDED (1 << 0)
|
||||
|
||||
#define PSA_ITS_API_VERSION_MAJOR 1 /**< The major version number of the PSA ITS API. It will be incremented on significant updates that may include breaking changes */
|
||||
#define PSA_ITS_API_VERSION_MINOR 1 /**< The minor version number of the PSA ITS API. It will be incremented in small updates that are unlikely to include breaking changes */
|
||||
|
||||
/**
|
||||
* \brief Create a new or modify an existing uid/value pair
|
||||
*
|
||||
* \param[in] aUid The identifier for the data
|
||||
* \param[in] aDataLength The size in bytes of the data in `p_data`
|
||||
* \param[in] aData A buffer containing the data
|
||||
* \param[in] aCreateFlags The flags that the data will be stored with
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided `uid` value was already created with PSA_STORAGE_FLAG_WRITE_ONCE
|
||||
* \retval #PSA_ERROR_NOT_SUPPORTED The operation failed because one or more of the flags provided in `create_flags` is not supported or is not valid
|
||||
* \retval #PSA_ERROR_INSUFFICIENT_STORAGE The operation failed because there was insufficient space on the storage medium
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`)
|
||||
* is invalid, for example is `NULL` or references memory the caller cannot access
|
||||
*/
|
||||
psa_status_t psa_its_set(psa_storage_uid_t aUid,
|
||||
uint32_t aDataLength,
|
||||
const void *aData,
|
||||
psa_storage_create_flags_t aCreateFlags);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the value associated with a provided uid
|
||||
*
|
||||
* \param[in] aUid The uid value
|
||||
* \param[in] aDataOffset The starting offset of the data requested
|
||||
* \param[in] aDataLength The amount of data requested (and the minimum allocated size of the `p_data` buffer)
|
||||
* \param[out] aData The buffer where the data will be placed upon successful completion
|
||||
* \param[out] aDataLengthOut The amount of data returned in the p_data buffer
|
||||
*
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided `uid` value was not found in the storage
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_data`, `p_data_length`)
|
||||
* is invalid. For example is `NULL` or references memory the caller cannot access.
|
||||
* In addition, this can also happen if an invalid offset was provided.
|
||||
*/
|
||||
psa_status_t psa_its_get(psa_storage_uid_t aUid,
|
||||
uint32_t aDataOffset,
|
||||
uint32_t aDataLength,
|
||||
void *aData,
|
||||
size_t *aDataLengthOut);
|
||||
|
||||
/**
|
||||
* \brief Retrieve the metadata about the provided uid
|
||||
*
|
||||
* \param[in] aUid The uid value
|
||||
* \param[out] aInfo A pointer to the `psa_storage_info_t` struct that will be populated with the metadata
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
|
||||
* \retval #PSA_ERROR_DATA_CORRUPT The operation failed because stored data has been corrupted
|
||||
* \retval #PSA_ERROR_INVALID_ARGUMENT The operation failed because one of the provided pointers(`p_info`)
|
||||
* is invalid, for example is `NULL` or references memory the caller cannot access
|
||||
*/
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t aUid,
|
||||
struct psa_storage_info_t *aInfo);
|
||||
|
||||
/**
|
||||
* \brief Remove the provided key and its associated data from the storage
|
||||
*
|
||||
* \param[in] aUid The uid value
|
||||
*
|
||||
* \return A status indicating the success/failure of the operation
|
||||
*
|
||||
* \retval #PSA_SUCCESS The operation completed successfully
|
||||
* \retval #PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided key value was not found in the storage
|
||||
* \retval #PSA_ERROR_NOT_PERMITTED The operation failed because the provided key value was created with PSA_STORAGE_FLAG_WRITE_ONCE
|
||||
* \retval #PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
|
||||
*/
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t aUid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_INTERNAL_TRUSTED_STORAGE_H__ */
|
||||
+384
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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 an exemplary ITS working on files.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define VerifyOrExit(aCondition, aAction) \
|
||||
do \
|
||||
{ \
|
||||
if (!(aCondition)) \
|
||||
{ \
|
||||
aAction; \
|
||||
goto exit; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* @def ITS_FILE_DEFAULT_FILE_PREFIX
|
||||
*
|
||||
* The default directory prefix if the user does not override it by changing
|
||||
* the global variable @c gItsFileNamePrefix.
|
||||
*/
|
||||
#define ITS_FILE_DEFAULT_FILE_PREFIX "tmp/"
|
||||
|
||||
/**
|
||||
* @def ITS_FILE_PATH_MAX
|
||||
*
|
||||
* The maximum allowed length (in bytes) for file paths.
|
||||
*/
|
||||
#define ITS_FILE_PATH_MAX 256
|
||||
|
||||
/**
|
||||
* @def ITS_DIR_MODE
|
||||
*
|
||||
* The mode used when creating directories (0777 gives full permissions to owner,
|
||||
* group, and others).
|
||||
*/
|
||||
#define ITS_DIR_MODE 0777
|
||||
|
||||
/**
|
||||
* @def ITS_FILE_HEADER_SIZE
|
||||
*
|
||||
* The size (in bytes) of the file header: 4 bytes for flags plus 4 bytes for total data length.
|
||||
*/
|
||||
#define ITS_FILE_HEADER_SIZE (sizeof(uint32_t) + sizeof(uint32_t))
|
||||
|
||||
/**
|
||||
* @def ITS_FILE_NAME_FORMAT
|
||||
*
|
||||
* The format string for building the file path.
|
||||
*/
|
||||
#define ITS_FILE_NAME_FORMAT "%suid_%llu.psa_its"
|
||||
|
||||
/**
|
||||
* A global variable that determines where PSA ITS files are stored.
|
||||
*
|
||||
* By default, it is @ref ITS_FILE_DEFAULT_FILE_PREFIX. You can override
|
||||
* it at runtime:
|
||||
* @code
|
||||
* gItsFileNamePrefix = "tmp/its_node_3_offset_12";
|
||||
* @endcode
|
||||
*/
|
||||
const char *gItsFileNamePrefix = ITS_FILE_DEFAULT_FILE_PREFIX;
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that the directory (specified by `gItsFileNamePrefix`) exists.
|
||||
*/
|
||||
static bool ensureDirectoryExists(void)
|
||||
{
|
||||
bool success = true;
|
||||
struct stat st;
|
||||
char filePrefix[ITS_FILE_PATH_MAX];
|
||||
char *dir;
|
||||
|
||||
// Copy prefix to local buffer, because dirname() modifies its argument
|
||||
strncpy(filePrefix, gItsFileNamePrefix, sizeof(filePrefix));
|
||||
filePrefix[sizeof(filePrefix) - 1] = '\0';
|
||||
|
||||
dir = dirname(filePrefix);
|
||||
|
||||
// 1) Check if path already exists
|
||||
if (stat(dir, &st) == 0)
|
||||
{
|
||||
// Exists - must be a directory
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Path doesn't exist, attempt to create one.
|
||||
if (mkdir(dir, ITS_DIR_MODE) != 0)
|
||||
{
|
||||
// Retry with stat again.
|
||||
if (stat(dir, &st) != 0 || !S_ISDIR(st.st_mode))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the file path for a given UID.
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
static int buildFilePath(psa_storage_uid_t aUid, char *aPath, size_t aPathSize)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
// Attempt to format
|
||||
int ret = snprintf(aPath, aPathSize, ITS_FILE_NAME_FORMAT,
|
||||
gItsFileNamePrefix, (unsigned long long)aUid);
|
||||
|
||||
// If ret < 0 or ret >= aPathSize, return an error.
|
||||
VerifyOrExit((ret >= 0) && ((size_t)ret < aPathSize), result = -1);
|
||||
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an 8-byte header from the given file:
|
||||
* - 4 bytes for flags (psa_storage_create_flags_t)
|
||||
* - 4 bytes for data length
|
||||
*
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
static int readHeader(FILE *aFile, psa_storage_create_flags_t *aFlags, uint32_t *aDataLen)
|
||||
{
|
||||
int result = 0;
|
||||
uint32_t flagsTmp;
|
||||
uint32_t lenTmp;
|
||||
|
||||
// Read flags
|
||||
VerifyOrExit(fread(&flagsTmp, sizeof(flagsTmp), 1, aFile) == 1, result = -1);
|
||||
|
||||
// Read length
|
||||
VerifyOrExit(fread(&lenTmp, sizeof(lenTmp), 1, aFile) == 1, result = -1);
|
||||
|
||||
*aFlags = flagsTmp;
|
||||
*aDataLen = lenTmp;
|
||||
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an 8-byte header to the given file:
|
||||
* - 4 bytes for flags
|
||||
* - 4 bytes for data length
|
||||
*
|
||||
* Returns 0 on success, -1 on error.
|
||||
*/
|
||||
static int writeHeader(FILE *aFile, psa_storage_create_flags_t aFlags, uint32_t aDataLen)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
// Write flags
|
||||
VerifyOrExit(fwrite(&aFlags, sizeof(aFlags), 1, aFile) == 1, result = -1);
|
||||
|
||||
// Write length
|
||||
VerifyOrExit(fwrite(&aDataLen, sizeof(aDataLen), 1, aFile) == 1, result = -1);
|
||||
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_set(psa_storage_uid_t aUid,
|
||||
uint32_t aDataLength,
|
||||
const void *aData,
|
||||
psa_storage_create_flags_t aCreateFlags)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
FILE *file = NULL;
|
||||
char path[ITS_FILE_PATH_MAX];
|
||||
|
||||
// Validate arguments
|
||||
VerifyOrExit((aData != NULL && aDataLength > 0), status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
// Only NONE or WRITE_ONCE => no other flags supported
|
||||
VerifyOrExit((aCreateFlags & ~(PSA_STORAGE_FLAG_WRITE_ONCE)) == 0, status = PSA_ERROR_NOT_SUPPORTED);
|
||||
|
||||
// Ensure directory
|
||||
VerifyOrExit(ensureDirectoryExists(), status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
// Build path
|
||||
VerifyOrExit(buildFilePath(aUid, path, sizeof(path)) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
// If file exists, check WRITE_ONCE
|
||||
file = fopen(path, "rb");
|
||||
if (file)
|
||||
{
|
||||
psa_storage_create_flags_t oldFlags;
|
||||
uint32_t oldLen;
|
||||
|
||||
if (readHeader(file, &oldFlags, &oldLen) == 0)
|
||||
{
|
||||
VerifyOrExit(!(oldFlags & PSA_STORAGE_FLAG_WRITE_ONCE), status = PSA_ERROR_NOT_PERMITTED);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
// Create/overwrite
|
||||
file = fopen(path, "wb");
|
||||
VerifyOrExit(file != NULL, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
// Write header
|
||||
VerifyOrExit(writeHeader(file, aCreateFlags, aDataLength) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
// Write data
|
||||
if (aDataLength > 0 && aData != NULL)
|
||||
{
|
||||
size_t written = fwrite(aData, 1, aDataLength, file);
|
||||
VerifyOrExit(written == aDataLength, status = PSA_ERROR_GENERIC_ERROR);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get(psa_storage_uid_t aUid,
|
||||
uint32_t aDataOffset,
|
||||
uint32_t aDataLength,
|
||||
void *aData,
|
||||
size_t *aDataLengthOut)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
FILE *file = NULL;
|
||||
char path[ITS_FILE_PATH_MAX];
|
||||
|
||||
VerifyOrExit(aDataLengthOut != NULL, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
if (aDataLength > 0)
|
||||
{
|
||||
VerifyOrExit(aData != NULL, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
VerifyOrExit(buildFilePath(aUid, path, sizeof(path)) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
file = fopen(path, "rb");
|
||||
VerifyOrExit(file != NULL, status = PSA_ERROR_DOES_NOT_EXIST);
|
||||
|
||||
{
|
||||
psa_storage_create_flags_t flags;
|
||||
uint32_t totalLen;
|
||||
|
||||
VerifyOrExit(readHeader(file, &flags, &totalLen) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
VerifyOrExit(aDataOffset <= totalLen, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
size_t available = totalLen - aDataOffset;
|
||||
size_t toCopy = (aDataLength <= available) ? aDataLength : available;
|
||||
|
||||
VerifyOrExit(fseek(file, aDataOffset, SEEK_CUR) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
if (toCopy > 0 && aData != NULL)
|
||||
{
|
||||
VerifyOrExit(fread(aData, 1, toCopy, file) == toCopy, status = PSA_ERROR_GENERIC_ERROR);
|
||||
}
|
||||
|
||||
*aDataLengthOut = toCopy;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t aUid,
|
||||
struct psa_storage_info_t *aInfo)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
FILE *file = NULL;
|
||||
char path[ITS_FILE_PATH_MAX];
|
||||
psa_storage_create_flags_t flags;
|
||||
uint32_t totalLen;
|
||||
|
||||
VerifyOrExit(aInfo != NULL, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
VerifyOrExit(buildFilePath(aUid, path, sizeof(path)) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
file = fopen(path, "rb");
|
||||
VerifyOrExit(file != NULL, status = PSA_ERROR_DOES_NOT_EXIST);
|
||||
|
||||
VerifyOrExit(readHeader(file, &flags, &totalLen) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
aInfo->size = totalLen;
|
||||
aInfo->flags = flags;
|
||||
|
||||
exit:
|
||||
if (file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t aUid)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
FILE *file = NULL;
|
||||
char path[ITS_FILE_PATH_MAX];
|
||||
psa_storage_create_flags_t flags;
|
||||
uint32_t totalLen;
|
||||
|
||||
VerifyOrExit(buildFilePath(aUid, path, sizeof(path)) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
file = fopen(path, "rb");
|
||||
VerifyOrExit(file != NULL, status = PSA_ERROR_DOES_NOT_EXIST);
|
||||
|
||||
VerifyOrExit(readHeader(file, &flags, &totalLen) == 0, status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
// If WRITE_ONCE is set, we cannot remove it.
|
||||
VerifyOrExit(!(flags & PSA_STORAGE_FLAG_WRITE_ONCE), status = PSA_ERROR_NOT_PERMITTED);
|
||||
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
|
||||
VerifyOrExit((unlink(path) == 0), status = PSA_ERROR_GENERIC_ERROR);
|
||||
|
||||
exit:
|
||||
if (file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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 a simple in-RAM PSA ITS backend for demonstration and testing.
|
||||
*
|
||||
* All data is stored in memory and is not persisted after process termination.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
|
||||
#include "psa/error.h"
|
||||
#include "psa/internal_trusted_storage.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define VerifyOrExit(aCondition, aAction) \
|
||||
do \
|
||||
{ \
|
||||
if (!(aCondition)) \
|
||||
{ \
|
||||
aAction; \
|
||||
goto exit; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @def RAM_ITS_MAX_KEYS
|
||||
*
|
||||
* The maximum number of PSA ITS entries that can be stored in RAM.
|
||||
*/
|
||||
#define RAM_ITS_MAX_KEYS 64
|
||||
|
||||
/**
|
||||
* @def RAM_ITS_MAX_DATA_SIZE
|
||||
*
|
||||
* The maximum size (in bytes) of data that can be stored for each entry.
|
||||
*/
|
||||
#define RAM_ITS_MAX_DATA_SIZE 128
|
||||
|
||||
|
||||
/**
|
||||
* Represents a single PSA ITS record stored in RAM.
|
||||
*
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
bool mInUse; // Whether this slot is occupied
|
||||
psa_storage_uid_t mUid; // Unique ID
|
||||
psa_storage_create_flags_t mFlags; // Storage flags (e.g. WRITE_ONCE)
|
||||
uint32_t mDataLen; // Current size of stored data
|
||||
uint8_t mData[RAM_ITS_MAX_DATA_SIZE]; // Raw data storage
|
||||
} RamItsEntry;
|
||||
|
||||
/**
|
||||
* Array of entries for RAM-based ITS storage.
|
||||
*
|
||||
*/
|
||||
static RamItsEntry sRamItsEntries[RAM_ITS_MAX_KEYS];
|
||||
|
||||
/**
|
||||
* Finds an existing entry by UID.
|
||||
*
|
||||
* @param[in] aUid The UID value to search for.
|
||||
*
|
||||
* @returns The index of the matching entry, or -1 if not found.
|
||||
*
|
||||
*/
|
||||
static int RamItsFindEntry(psa_storage_uid_t aUid)
|
||||
{
|
||||
for (int i = 0; i < RAM_ITS_MAX_KEYS; i++)
|
||||
{
|
||||
if (sRamItsEntries[i].mInUse && (sRamItsEntries[i].mUid == aUid))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a free slot in the storage array.
|
||||
*
|
||||
* @returns The index of a free slot, or -1 if none is available.
|
||||
*
|
||||
*/
|
||||
static int RamItsFindFreeSlot(void)
|
||||
{
|
||||
for (int i = 0; i < RAM_ITS_MAX_KEYS; i++)
|
||||
{
|
||||
if (!sRamItsEntries[i].mInUse)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_set(psa_storage_uid_t aUid,
|
||||
uint32_t aDataLength,
|
||||
const void *aData,
|
||||
psa_storage_create_flags_t aCreateFlags)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
int idx = -1;
|
||||
|
||||
VerifyOrExit(!(aData == NULL && aDataLength > 0), status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
// Allow only NONE or WRITE_ONCE flags. Any others => Not supported.
|
||||
VerifyOrExit((aCreateFlags & ~(PSA_STORAGE_FLAG_WRITE_ONCE)) == 0,
|
||||
status = PSA_ERROR_NOT_SUPPORTED);
|
||||
|
||||
// Data length must not exceed our internal buffer size.
|
||||
VerifyOrExit(aDataLength <= RAM_ITS_MAX_DATA_SIZE, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
// Find existing entry, if any.
|
||||
idx = RamItsFindEntry(aUid);
|
||||
if (idx >= 0)
|
||||
{
|
||||
// Entry already exists.
|
||||
|
||||
// If WRITE_ONCE is set, we cannot overwrite it.
|
||||
VerifyOrExit(!(sRamItsEntries[idx].mFlags & PSA_STORAGE_FLAG_WRITE_ONCE), status = PSA_ERROR_NOT_PERMITTED);
|
||||
|
||||
// Overwrite existing entry.
|
||||
sRamItsEntries[idx].mDataLen = aDataLength;
|
||||
|
||||
if (aDataLength > 0 && aData != NULL)
|
||||
{
|
||||
memcpy(sRamItsEntries[idx].mData, aData, aDataLength);
|
||||
}
|
||||
|
||||
sRamItsEntries[idx].mFlags = aCreateFlags;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Need a new entry.
|
||||
idx = RamItsFindFreeSlot();
|
||||
VerifyOrExit(idx >= 0, status = PSA_ERROR_INSUFFICIENT_STORAGE);
|
||||
|
||||
sRamItsEntries[idx].mInUse = true;
|
||||
sRamItsEntries[idx].mUid = aUid;
|
||||
sRamItsEntries[idx].mFlags = aCreateFlags;
|
||||
sRamItsEntries[idx].mDataLen = aDataLength;
|
||||
|
||||
if (aDataLength > 0 && aData != NULL)
|
||||
{
|
||||
memcpy(sRamItsEntries[idx].mData, aData, aDataLength);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get(psa_storage_uid_t aUid,
|
||||
uint32_t aDataOffset,
|
||||
uint32_t aDataLength,
|
||||
void *aData,
|
||||
size_t *aDataLengthOut)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
int idx;
|
||||
|
||||
// Validate pointers.
|
||||
VerifyOrExit(aDataLengthOut != NULL, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
if (aDataLength > 0)
|
||||
{
|
||||
VerifyOrExit(aData != NULL, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
idx = RamItsFindEntry(aUid);
|
||||
VerifyOrExit(idx >= 0, status = PSA_ERROR_DOES_NOT_EXIST);
|
||||
|
||||
// Check offset validity.
|
||||
VerifyOrExit(aDataOffset <= sRamItsEntries[idx].mDataLen, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
// Determine how many bytes to copy.
|
||||
{
|
||||
size_t available = sRamItsEntries[idx].mDataLen - aDataOffset;
|
||||
size_t toCopy = (aDataLength <= available) ? aDataLength : available;
|
||||
|
||||
if (toCopy > 0)
|
||||
{
|
||||
memcpy(aData, &sRamItsEntries[idx].mData[aDataOffset], toCopy);
|
||||
}
|
||||
|
||||
*aDataLengthOut = toCopy;
|
||||
}
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_get_info(psa_storage_uid_t aUid,
|
||||
struct psa_storage_info_t *aInfo)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
int idx;
|
||||
|
||||
VerifyOrExit(aInfo != NULL, status = PSA_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
idx = RamItsFindEntry(aUid);
|
||||
VerifyOrExit(idx >= 0, status = PSA_ERROR_DOES_NOT_EXIST);
|
||||
|
||||
aInfo->size = sRamItsEntries[idx].mDataLen;
|
||||
aInfo->flags = sRamItsEntries[idx].mFlags;
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_its_remove(psa_storage_uid_t aUid)
|
||||
{
|
||||
psa_status_t status = PSA_SUCCESS;
|
||||
int idx;
|
||||
|
||||
idx = RamItsFindEntry(aUid);
|
||||
VerifyOrExit(idx >= 0, status = PSA_ERROR_DOES_NOT_EXIST);
|
||||
|
||||
// If WRITE_ONCE is set, we cannot remove it.
|
||||
VerifyOrExit(!(sRamItsEntries[idx].mFlags & PSA_STORAGE_FLAG_WRITE_ONCE),
|
||||
status = PSA_ERROR_NOT_PERMITTED);
|
||||
|
||||
// Clear the slot.
|
||||
memset(sRamItsEntries[idx].mData, 0, sizeof(sRamItsEntries[idx].mData));
|
||||
sRamItsEntries[idx].mDataLen = 0;
|
||||
sRamItsEntries[idx].mUid = 0;
|
||||
sRamItsEntries[idx].mFlags = 0;
|
||||
sRamItsEntries[idx].mInUse = false;
|
||||
|
||||
exit:
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif // #if OPENTHREAD_CONFIG_CRYPTO_LIB == OPENTHREAD_CONFIG_CRYPTO_LIB_PSA
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
// Spans multiple lines to avoid being processed by unifdef
|
||||
#ifndef \
|
||||
PSA_CRYPTO_CONFIG_H
|
||||
#define PSA_CRYPTO_CONFIG_H
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/config.h>
|
||||
|
||||
#define PSA_WANT_ALG_CBC_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_CBC_PKCS7 1
|
||||
#define PSA_WANT_ALG_CCM 1
|
||||
#define PSA_WANT_ALG_CCM_STAR_NO_TAG 1
|
||||
#define PSA_WANT_ALG_CMAC 1
|
||||
#define PSA_WANT_ALG_CFB 1
|
||||
#define PSA_WANT_ALG_CTR 1
|
||||
#define PSA_WANT_ALG_DETERMINISTIC_ECDSA 1
|
||||
#define PSA_WANT_ALG_ECB_NO_PADDING 1
|
||||
#define PSA_WANT_ALG_ECDH 1
|
||||
#define PSA_WANT_ALG_ECDSA 1
|
||||
#define PSA_WANT_ALG_JPAKE 1
|
||||
#define PSA_WANT_ALG_GCM 1
|
||||
#define PSA_WANT_ALG_HKDF 1
|
||||
#define PSA_WANT_ALG_HKDF_EXTRACT 1
|
||||
#define PSA_WANT_ALG_HKDF_EXPAND 1
|
||||
#define PSA_WANT_ALG_HMAC 1
|
||||
#define PSA_WANT_ALG_PBKDF2_HMAC 1
|
||||
#define PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 1
|
||||
#define PSA_WANT_ALG_RIPEMD160 1
|
||||
#define PSA_WANT_ALG_SHA_1 1
|
||||
#define PSA_WANT_ALG_SHA_224 1
|
||||
#define PSA_WANT_ALG_SHA_256 1
|
||||
#define PSA_WANT_ALG_TLS12_PRF 1
|
||||
#define PSA_WANT_ALG_TLS12_PSK_TO_MS 1
|
||||
#define PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS 1
|
||||
|
||||
#define PSA_WANT_ECC_SECP_K1_256 1
|
||||
#define PSA_WANT_ECC_SECP_R1_256 1
|
||||
|
||||
#define PSA_WANT_KEY_TYPE_DERIVE 1
|
||||
#define PSA_WANT_KEY_TYPE_PASSWORD 1
|
||||
#define PSA_WANT_KEY_TYPE_PASSWORD_HASH 1
|
||||
#define PSA_WANT_KEY_TYPE_HMAC 1
|
||||
#define PSA_WANT_KEY_TYPE_AES 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY 1
|
||||
#define PSA_WANT_KEY_TYPE_RAW_DATA 1
|
||||
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE 1
|
||||
#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE 1
|
||||
|
||||
#endif /* PSA_CRYPTO_CONFIG_H */
|
||||
Reference in New Issue
Block a user