Skip to content

PSA storage: Conform to "PSA 1.0.0" spec release #10847

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 50 additions & 9 deletions TESTS/psa/its_ps/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@
#include "psa/internal_trusted_storage.h"
#include "psa/protected_storage.h"
#include "psa/lifecycle.h"
#include "KVMap.h"
#include "KVStore.h"
#include "kv_config.h"
#include "psa_storage_common_impl.h"

using namespace utest::v1;

#define TEST_BUFF_SIZE 16
#define STR_EXPAND(tok) #tok

typedef enum {
its,
Expand All @@ -40,20 +45,20 @@ typedef enum {

extern "C" psa_status_t psa_ps_reset();

static psa_status_t set_func(storage_type_t stype, psa_storage_uid_t uid, uint32_t data_length,
static psa_status_t set_func(storage_type_t stype, psa_storage_uid_t uid, size_t data_length,
const void *p_data, psa_storage_create_flags_t create_flags)
{
return (stype == its) ?
psa_its_set(uid, data_length, p_data, create_flags) :
psa_ps_set(uid, data_length, p_data, create_flags);
}

static psa_status_t get_func(storage_type_t stype, psa_storage_uid_t uid, uint32_t data_offset,
uint32_t data_length, void *p_data)
static psa_status_t get_func(storage_type_t stype, psa_storage_uid_t uid, size_t data_offset,
size_t data_length, void *p_data, size_t *actual_length)
{
return (stype == its) ?
psa_its_get(uid, data_offset, data_length, p_data) :
psa_ps_get(uid, data_offset, data_length, p_data);
psa_its_get(uid, data_offset, data_length, p_data, actual_length) :
psa_ps_get(uid, data_offset, data_length, p_data, actual_length);
}

static psa_status_t get_info_func(storage_type_t stype, psa_storage_uid_t uid,
Expand All @@ -78,6 +83,8 @@ void pits_ps_test()
psa_status_t status = PSA_SUCCESS;
uint8_t write_buff[TEST_BUFF_SIZE] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
uint8_t read_buff[TEST_BUFF_SIZE] = {0};
size_t actual_size;
psa_storage_create_flags_t flags;
struct psa_storage_info_t info = {0, PSA_STORAGE_FLAG_WRITE_ONCE};
memset(read_buff, 0, TEST_BUFF_SIZE);

Expand All @@ -92,15 +99,15 @@ void pits_ps_test()
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(0, info.flags);

status = get_func(stype, 5, 0, TEST_BUFF_SIZE, read_buff);
status = get_func(stype, 5, 0, TEST_BUFF_SIZE, read_buff, &actual_size);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff, read_buff, TEST_BUFF_SIZE);

memset(read_buff, 0, TEST_BUFF_SIZE);
status = get_func(stype, 5, 1, TEST_BUFF_SIZE, read_buff);
status = get_func(stype, 5, 1, TEST_BUFF_SIZE, read_buff, &actual_size);
TEST_ASSERT_NOT_EQUAL(PSA_SUCCESS, status);

status = get_func(stype, 5, 1, TEST_BUFF_SIZE - 1, read_buff);
status = get_func(stype, 5, 1, TEST_BUFF_SIZE - 1, read_buff, &actual_size);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL_MEMORY(write_buff + 1, read_buff, TEST_BUFF_SIZE - 1);

Expand All @@ -109,6 +116,38 @@ void pits_ps_test()

status = get_info_func(stype, 5, &info);
TEST_ASSERT_EQUAL(PSA_ERROR_DOES_NOT_EXIST, status);

if (stype == its) {
return;
}

mbed::KVMap &kv_map = mbed::KVMap::get_instance();
mbed::KVStore *kvstore = kv_map.get_main_kv_instance(STR_EXPAND(MBED_CONF_STORAGE_DEFAULT_KV));
uint32_t kv_get_flags;

flags = PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION;
status = set_func(stype, 6, TEST_BUFF_SIZE, write_buff, flags);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);

status = get_info_func(stype, 6, &info);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(flags, info.flags);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we know that the KvStore flags are correct in this test? Should we also do an assert to make sure KVStore::REQUIRE_REPLAY_PROTECTION_FLAG is clear in kv_info.flags, to ensure our translation went properly?

I understand the get_info_func() as currently implemented will do the translation from kv_info.flags to PSA flags, but if in the future that get_info_func() gets a bug or simply replies with previously saved PSA flag values, we would miss out on test coverage. From a defensive programming point of view, we should check directly what we want to know about what KvStore is doing; it'll be a more robust check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this test is a kind of a black box test, in the sense that we work with what the APIs provide us (PSA flags in that case). What you suggest here is a "white box" test, which tests the various impacts of the APIs on the internal components. Seems a bit excessive to me - this should IMO be part of the unit tests. Otherwise, one could argue that we shouldn't only check the KVStore flags, but also the key name, sizes etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can think of a way to ensure that the correct flags took actual effect (for example, that storage is actually encrypted when needed, not encrypted when using internally-backed PS storage) with a black box test, that'd work too. I think whitebox would be easier, though, if you trust the underlying KvStore tests. As written now, the test is too easy to fool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KVStore tests (namely the SecureStore test) check that the actual encryption is performed on storage. But yet again, saying that the test is "easy to fool" can be applied on many other part of this test (for instance, checking that the stored key is what we expect, not only the flags) or other tests as well. My point here is that the KVStore flags shouldn't be "superior" in that sense.

Copy link
Contributor

@Patater Patater Jun 26, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"KVStore tests (namely the SecureStore test) check that the actual encryption is performed on storage" given that it uses the flag that tells it to do the encryption. However, we have no visibility from the PSA level that KvStore will use the right flags. We don't have any test that if PSA requests encryption, KvStore will use encryption. We have a test that PSA will be told that the encryption flag it asked for was in fact asked for and remembered, but no test that the KvStore will listen to that flag. We could get a better guarantee of this if we check the KvStore flags used for the storage backing the request from PSA.

We don't need to do integration testing to check that the storage is actually encrypted, but we do need at a minimum to unit test flag translation (psa_ps_set().)

Could we break out the flag translation logic from psa_ps_set() so that we can test PSA flags as input, and KvStore flags as output, ensuring that for all combinations of PSA input flags, we get the expected KvStore flags? The test would not ask KvStore for anything, nor would it be dependent on physical storage or any of its properties. We should do the same for the flag translation logic in psa_ps_get_info(), breaking it out into its own function so that we can test it in isolation from KvStore.

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but I really have to disagree. What you are actually suggesting here is to expose the implementation of KVStore flags to the outside world. However, this is part of the internal implementation of psa_ps_set and psa_ps_get_info APIs. Exposing this implementation to the outside world gives us nothing other than the ability to test the implementation, which again is something that should be tested by unit tests. However, the real downside here is that if we decide at some point to change the implementation of these APIs (for instance, to abandon KVStore), we will have a much harder time to do that following the exposure of these flags, as it would lead to a breaking change. This is not far fetched: the initial implementation of the device key used NVStore, which was later replaced by KVStore.
If you are worried about how the KVStore flags behave when calling these APIs, I can attach their print log following these actions. Don't think anything beyond this is required.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm suggesting to test the flag translation logic. This is not currently being done adequately. Exposing the KVStore flag translation functions to the outside world isn't required as only unit tests need to use it.

If KvStore is no longer used in the future, then the flag translation functions no longer need testing and the tests can be changed or removed. It's pretty common to update tests at the same time an implementation changes significantly.

The flag translation is quite tricky and deserves testing in isolation with a unit test. Crypto and many other services and applications depend on storage to provide the security guarantees they request from storage. The impact of a bug in this area is quite high, so please adequately test this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Translation logic is really not that complicated - two flags that use reverse logic in PSA Storage & KVStore. Translation of uid to KVStore key is much more complex, to give one example. Breaking the implementation to a function that exposes an internal implementation in a header file (even if only internally used by test code) seems like a total overshoot to me. That's what unit testing is for IMHO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what unit testing is for IMHO.

Yes, I'm only asking for a unit test of the flag translation logic. High risk of trouble if this translation code does something wrong, even if we don't think it's that complicated.

Requesting unit tests for flag translation logic shouldn't also require adding unit tests for uid to KVStore keys. Although you really should have unit tests for that as well, given that you've shipped that already, I'd say fixing it is out of scope of this PR. I would like to prevent more code from being added to Mbed OS that isn't sufficiently tested, however.

Where are the unit tests? Not part of Mbed OS? Someplace else?


status = psa_storage_get_info_impl(kvstore, 1, 6, &info, &kv_get_flags);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(kv_get_flags, mbed::KVStore::REQUIRE_CONFIDENTIALITY_FLAG);

flags = PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION | PSA_STORAGE_FLAG_NO_CONFIDENTIALITY | PSA_STORAGE_FLAG_WRITE_ONCE;
status = set_func(stype, 6, TEST_BUFF_SIZE, write_buff, flags);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);

status = get_info_func(stype, 6, &info);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(flags, info.flags);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we know that the KvStore flags are correct in this test? Should we also do an assert to make sure both KVStore::REQUIRE_REPLAY_PROTECTION_FLAG and KVStore::REQUIRE_CONFIDENTIALITY_FLAG are clear in kv_info.flags, to ensure our translation went properly?


status = psa_storage_get_info_impl(kvstore, 1, 6, &info, &kv_get_flags);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(kv_get_flags, mbed::KVStore::WRITE_ONCE_FLAG);
}

template <storage_type_t stype>
Expand All @@ -117,6 +156,7 @@ void pits_ps_write_once_test()
psa_status_t status = PSA_SUCCESS;
uint8_t write_buff[TEST_BUFF_SIZE] = {0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};
uint8_t read_buff[TEST_BUFF_SIZE] = {0};
size_t actual_size;
struct psa_storage_info_t info = {0, 0};

status = get_info_func(stype, 5, &info);
Expand All @@ -132,8 +172,9 @@ void pits_ps_write_once_test()
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, info.size);
TEST_ASSERT_EQUAL(PSA_STORAGE_FLAG_WRITE_ONCE, info.flags);

status = get_func(stype, 5, 0, TEST_BUFF_SIZE, read_buff);
status = get_func(stype, 5, 0, TEST_BUFF_SIZE, read_buff, &actual_size);
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
TEST_ASSERT_EQUAL(TEST_BUFF_SIZE, actual_size);
TEST_ASSERT_EQUAL_MEMORY(write_buff, read_buff, TEST_BUFF_SIZE);

status = set_func(stype, 5, TEST_BUFF_SIZE, write_buff, PSA_STORAGE_FLAG_WRITE_ONCE);
Expand Down
18 changes: 10 additions & 8 deletions components/TARGET_PSA/inc/psa/protected_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ extern "C" {
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure
*/
psa_status_t psa_ps_set(psa_storage_uid_t uid,
uint32_t data_length,
size_t data_length,
const void *p_data,
psa_storage_create_flags_t create_flags);

Expand All @@ -65,22 +65,24 @@ psa_status_t psa_ps_set(psa_storage_uid_t uid,
* \param[in] data_offset The offset within the data associated with the `uid` to start retrieving data
* \param[in] data_length The amount of data to read (and the minimum allocated size of the `p_data` buffer)
* \param[out] p_data The buffer where the data will be placed upon successful completion
* \param[out] p_data_length The actual amount of data returned
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The operation completed successfully
* \retval PSA_ERROR_INVALID_ARGUMENT The operation failed because one or more of the given arguments were invalid (null pointer, wrong flags etc.)
* \retval PSA_ERROR_DOES_NOT_EXIST The operation failed because the provided uid value was not found in the storage
* \retval PSA_ERROR_BUFFER_TOO_SMALL The operation failed because the data associated with provided uid is not the same size as `data_size`
* \retval PSA_ERROR_BUFFER_TOO_SMALL The operation failed because the data associated with provided uid does not fit `data_size`
* \retval PSA_ERROR_STORAGE_FAILURE The operation failed because the physical storage has failed (Fatal error)
* \retval PSA_ERROR_GENERIC_ERROR The operation failed because of an unspecified internal failure
* \retval PSA_ERROR_DATA_CORRUPT The operation failed because of an authentication failure when attempting to get the key
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the data associated with the UID failed authentication
*/
psa_status_t psa_ps_get(psa_storage_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
void *p_data);
size_t data_offset,
size_t data_length,
void *p_data,
size_t *p_data_length);

/**
* \brief Retrieve the metadata about the provided uid
Expand Down Expand Up @@ -149,7 +151,7 @@ psa_status_t psa_ps_remove(psa_storage_uid_t uid);
* \retval PSA_ERROR_GENERIC_ERROR The operation has failed due to an unspecified error
*/
psa_status_t psa_ps_create(psa_storage_uid_t uid,
uint32_t size,
size_t size,
psa_storage_create_flags_t create_flags);

/**
Expand Down Expand Up @@ -179,8 +181,8 @@ psa_status_t psa_ps_create(psa_storage_uid_t uid,
* \retval PSA_ERROR_INVALID_SIGNATURE The operation failed because the existing data failed authentication (MAC check failed)
*/
psa_status_t psa_ps_set_extended(psa_storage_uid_t uid,
uint32_t data_offset,
uint32_t data_length,
size_t data_offset,
size_t data_length,
const void *p_data);

/**
Expand Down
9 changes: 6 additions & 3 deletions components/TARGET_PSA/inc/psa/storage_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ extern "C" {
*/
typedef uint32_t psa_storage_create_flags_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`*/
#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`*/
#define PSA_STORAGE_FLAG_NO_CONFIDENTIALITY (1 << 1) /**< The data associated with the uid is public and therefore does not require confidentiality. It therefore only needs to be integrity protected */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the spec linked, this should be PSA_STORAGE_FLAG_INTEGRITY_ONLY, not PSA_STORAGE_FLAG_NO_CONFIDENTIALITY.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please look at the up to date version of storage_common.h in master. It holds the PSA_STORAGE_FLAG_NO_CONFIDENTIALITY value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we ask for a release tag in psa_trusted_storage_api? The latest release, Release-PSA1.0RC2 looks out of date.

Then, we can reference the fresh tag from this PR's commits so it's clear which version of the PSA Storage API Mbed OS implements.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asked for it in there.

#define PSA_STORAGE_FLAG_NO_REPLAY_PROTECTION (1 << 2) /**< The data associated with the uid does not require replay protection. This may permit faster storage - but it permits an attecker with physical access to revert to an earlier version of the data. */

/** \brief A type for UIDs used for identifying data
*/
Expand All @@ -44,7 +46,8 @@ typedef uint64_t psa_storage_uid_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 **/
size_t capacity; /**< The allocated capacity of the storage associated with a UID **/
size_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 **/
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ static void generate_fn(char *tdb_filename, uint32_t tdb_filename_size, psa_stor
}

psa_status_t psa_storage_set_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid,
uint32_t data_length, const void *p_data,
size_t data_length, const void *p_data,
uint32_t kv_create_flags)
{
if (uid == 0) {
Expand All @@ -200,7 +200,7 @@ psa_status_t psa_storage_set_impl(KVStore *kvstore, int32_t pid, psa_storage_uid
}

psa_status_t psa_storage_get_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid,
uint32_t data_offset, uint32_t data_length, void *p_data)
size_t data_offset, size_t data_length, void *p_data, size_t *p_data_length)
{
if (uid == 0) {
return PSA_ERROR_INVALID_ARGUMENT;
Expand All @@ -227,18 +227,14 @@ psa_status_t psa_storage_get_impl(KVStore *kvstore, int32_t pid, psa_storage_uid
return PSA_ERROR_BUFFER_TOO_SMALL;
}

size_t actual_size = 0;
status = kvstore->get(kv_key, p_data, data_length, &actual_size, data_offset);
if ((status == MBED_SUCCESS) && (actual_size < data_length)) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
status = kvstore->get(kv_key, p_data, data_length, p_data_length, data_offset);
}

return convert_status(status);
}

psa_status_t psa_storage_get_info_impl(KVStore *kvstore, int32_t pid, psa_storage_uid_t uid,
struct psa_storage_info_t *p_info)
struct psa_storage_info_t *p_info, uint32_t *kv_get_flags)
{

if (uid == 0) {
Expand All @@ -257,7 +253,9 @@ psa_status_t psa_storage_get_info_impl(KVStore *kvstore, int32_t pid, psa_storag
if (kv_info.flags & KVStore::WRITE_ONCE_FLAG) {
p_info->flags |= PSA_STORAGE_FLAG_WRITE_ONCE;
}
p_info->size = (uint32_t)(kv_info.size); // kv_info.size is of type size_t
*kv_get_flags = kv_info.flags;
p_info->size = kv_info.size;
p_info->capacity = kv_info.size;
}

return convert_status(status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ typedef psa_status_t (*migrate_func_t)(mbed::KVStore *kvstore, const psa_storage

void psa_storage_handle_version(mbed::KVStore *kvstore, const char *version_key, const psa_storage_version_t *version,
migrate_func_t migrate_func);
psa_status_t psa_storage_set_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, uint32_t data_length, const void *p_data, uint32_t kv_create_flags);
psa_status_t psa_storage_get_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data);
psa_status_t psa_storage_get_info_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info);
psa_status_t psa_storage_set_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, size_t data_length, const void *p_data, uint32_t kv_create_flags);
psa_status_t psa_storage_get_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, size_t data_offset, size_t data_length, void *p_data, size_t *p_data_length);
psa_status_t psa_storage_get_info_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info, uint32_t *kv_get_flags);
psa_status_t psa_storage_remove_impl(mbed::KVStore *kvstore, int32_t pid, psa_storage_uid_t uid);
psa_status_t psa_storage_reset_impl(mbed::KVStore *kvstore);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
// So here we set a global pid value to be used for when calling IMPL functions
#define PSA_ITS_EMUL_PID 1

psa_status_t psa_its_set(psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
psa_status_t psa_its_set(psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
{
if (!p_data && data_length) {
return PSA_ERROR_INVALID_ARGUMENT;
Expand All @@ -47,9 +47,9 @@ psa_status_t psa_its_set(psa_storage_uid_t uid, uint32_t data_length, const void
return res;
}

psa_status_t psa_its_get(psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
psa_status_t psa_its_get(psa_storage_uid_t uid, size_t data_offset, size_t data_length, void *p_data, size_t *p_data_length)
{
if (!p_data && data_length) {
if ((!p_data && data_length) || !p_data_length) {
return PSA_ERROR_INVALID_ARGUMENT;
}

Expand All @@ -61,7 +61,7 @@ psa_status_t psa_its_get(psa_storage_uid_t uid, uint32_t data_offset, uint32_t d
return PSA_ERROR_STORAGE_FAILURE;
}

return psa_its_get_impl(PSA_ITS_EMUL_PID, uid, data_offset, data_length, p_data);
return psa_its_get_impl(PSA_ITS_EMUL_PID, uid, data_offset, data_length, p_data, p_data_length);
}

psa_status_t psa_its_get_info(psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ extern "C"
#define ITS_VERSION_KEY "PSA_ITS_VERSION" // ITS version entry identifier in TDBStore

static KVStore *kvstore = NULL;

static bool initialized = false;


MBED_WEAK psa_status_t its_version_migrate(KVStore *kvstore,
Expand Down Expand Up @@ -72,18 +72,20 @@ static void its_init(void)
}

psa_storage_handle_version(kvstore, ITS_VERSION_KEY, &version, its_version_migrate);
initialized = true;
}

// used from test only
void its_deinit(void)
{
kvstore = NULL;
initialized = false;
}


psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags)
{
if (!kvstore) {
if (!initialized) {
its_init();
}

Expand All @@ -94,27 +96,28 @@ psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_
return psa_storage_set_impl(kvstore, pid, uid, data_length, p_data, create_flags);
}

psa_status_t psa_its_get_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data)
psa_status_t psa_its_get_impl(int32_t pid, psa_storage_uid_t uid, size_t data_offset, size_t data_length, void *p_data, size_t *p_data_length)
{
if (!kvstore) {
if (!initialized) {
its_init();
}

return psa_storage_get_impl(kvstore, pid, uid, data_offset, data_length, p_data);
return psa_storage_get_impl(kvstore, pid, uid, data_offset, data_length, p_data, p_data_length);
}

psa_status_t psa_its_get_info_impl(int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info)
{
if (!kvstore) {
uint32_t kv_get_flags;
if (!initialized) {
its_init();
}

return psa_storage_get_info_impl(kvstore, pid, uid, p_info);
return psa_storage_get_info_impl(kvstore, pid, uid, p_info, &kv_get_flags);
}

psa_status_t psa_its_remove_impl(int32_t pid, psa_storage_uid_t uid)
{
if (!kvstore) {
if (!initialized) {
its_init();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ extern "C"
{
#endif

psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_length, const void *p_data, psa_storage_create_flags_t create_flags);
psa_status_t psa_its_get_impl(int32_t pid, psa_storage_uid_t uid, uint32_t data_offset, uint32_t data_length, void *p_data);
psa_status_t psa_its_set_impl(int32_t pid, psa_storage_uid_t uid, size_t data_length, const void *p_data, psa_storage_create_flags_t create_flags);
psa_status_t psa_its_get_impl(int32_t pid, psa_storage_uid_t uid, size_t data_offset, size_t data_length, void *p_data, size_t *p_data_length);
psa_status_t psa_its_get_info_impl(int32_t pid, psa_storage_uid_t uid, struct psa_storage_info_t *p_info);
psa_status_t psa_its_remove_impl(int32_t pid, psa_storage_uid_t uid);
psa_status_t psa_its_reset_impl();
Expand Down
Loading