Skip to content

Commit 5dbf6f9

Browse files
author
Seppo Takalo
committed
SecureStore: Validate internal RBP data first
Previous logic was allowing external storage to be tampered by setting write-protected keys, so values could not be updated, but it was still used by get().
1 parent b2cf585 commit 5dbf6f9

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

features/storage/kvstore/securestore/SecureStore.cpp

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -200,31 +200,37 @@ int SecureStore::set_start(set_handle_t *handle, const char *key, size_t final_d
200200

201201
_mutex.lock();
202202

203-
ret = _underlying_kv->get(key, &ih->metadata, sizeof(record_metadata_t));
204-
if (ret == MBED_SUCCESS) {
205-
// Must not remove RP flag
206-
if (!(create_flags & REQUIRE_REPLAY_PROTECTION_FLAG) && (ih->metadata.create_flags & REQUIRE_REPLAY_PROTECTION_FLAG)) {
207-
ret = MBED_ERROR_INVALID_ARGUMENT;
208-
goto fail;
209-
}
210-
} else if (ret != MBED_ERROR_ITEM_NOT_FOUND) {
211-
ret = MBED_ERROR_READ_FAILED;
212-
goto fail;
213-
}
214-
215-
if (ih->metadata.create_flags & WRITE_ONCE_FLAG) {
216-
// If write once flag set, check whether key exists in either of the underlying and RBP stores
217-
if (ret != MBED_ERROR_ITEM_NOT_FOUND) {
218-
ret = MBED_ERROR_WRITE_PROTECTED;
203+
// Validate internal RBP data
204+
if (_rbp_kv) {
205+
ret = _rbp_kv->get_info(key, &info);
206+
if (ret == MBED_SUCCESS) {
207+
if (info.flags & WRITE_ONCE_FLAG) {
208+
// Trying to re-write a key that is write protected
209+
ret = MBED_ERROR_WRITE_PROTECTED;
210+
goto fail;
211+
}
212+
if (!(create_flags & REQUIRE_REPLAY_PROTECTION_FLAG)) {
213+
// Trying to re-write a key that that has REPLAY_PROTECTION
214+
// with a new key that has this flag not set.
215+
ret = MBED_ERROR_INVALID_ARGUMENT;
216+
goto fail;
217+
}
218+
} else if (ret != MBED_ERROR_ITEM_NOT_FOUND) {
219+
ret = MBED_ERROR_READ_FAILED;
219220
goto fail;
220221
}
221-
222-
if (_rbp_kv) {
223-
ret = _rbp_kv->get_info(key, &info);
224-
if (ret != MBED_ERROR_ITEM_NOT_FOUND) {
225-
if (ret == MBED_SUCCESS) {
226-
ret = MBED_ERROR_WRITE_PROTECTED;
227-
}
222+
} else {
223+
// Only trust external flags, if internal RBP is not in use
224+
ret = _underlying_kv->get(key, &ih->metadata, sizeof(record_metadata_t));
225+
if (ret == MBED_SUCCESS) {
226+
// Must not remove RP flag, even though internal RBP KV is not in use.
227+
if (!(create_flags & REQUIRE_REPLAY_PROTECTION_FLAG) && (ih->metadata.create_flags & REQUIRE_REPLAY_PROTECTION_FLAG)) {
228+
ret = MBED_ERROR_INVALID_ARGUMENT;
229+
goto fail;
230+
}
231+
// Existing key is write protected
232+
if (ih->metadata.create_flags & WRITE_ONCE_FLAG) {
233+
ret = MBED_ERROR_WRITE_PROTECTED;
228234
goto fail;
229235
}
230236
}
@@ -531,6 +537,7 @@ int SecureStore::do_get(const char *key, void *buffer, size_t buffer_size, size_
531537
bool enc_started = false, auth_started = false;
532538
uint32_t create_flags;
533539
size_t read_len;
540+
info_t rbp_info;
534541

535542
if (!is_valid_key(key)) {
536543
return MBED_ERROR_INVALID_ARGUMENT;
@@ -541,9 +548,16 @@ int SecureStore::do_get(const char *key, void *buffer, size_t buffer_size, size_
541548
inc_set_handle_t *ih = static_cast<inc_set_handle_t *>(_inc_set_handle);
542549

543550
if (_rbp_kv) {
544-
ret = _rbp_kv->get(key, rbp_cmac, cmac_size, 0);
545-
if (!ret) {
551+
ret = _rbp_kv->get_info(key, &rbp_info);
552+
if (ret == MBED_SUCCESS) {
546553
rbp_key_exists = true;
554+
ret = _rbp_kv->get(key, rbp_cmac, cmac_size, &read_len);
555+
if (ret) {
556+
goto end;
557+
}
558+
if ((read_len != cmac_size) || (rbp_info.size != cmac_size)) {
559+
ret = MBED_ERROR_RBP_AUTHENTICATION_FAILED;
560+
}
547561
} else if (ret != MBED_ERROR_ITEM_NOT_FOUND) {
548562
goto end;
549563
}

0 commit comments

Comments
 (0)