mirror of
https://github.com/espressif/openthread.git
synced 2026-08-08 11:47:46 +00:00
[crypto] PSA API: introduce example native ITS implementations
This commit implements two example native ITS for linux-based platform.
This commit is contained in:
+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
|
||||
Reference in New Issue
Block a user