diff options
author | Julian Hall <julian.hall@arm.com> | 2021-11-18 09:24:55 +0000 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2021-11-26 05:05:42 +0100 |
commit | 919b558abde8b042e6301a334874058d24c1d230 (patch) | |
tree | ae2e967c9d1f87fc086fe1db55aee68f6237d1c2 | |
parent | 65f7eb400f3f4b02a631d48af9dce153b419412b (diff) | |
download | trusted-services-919b558abde8b042e6301a334874058d24c1d230.tar.gz |
Add uefi variable store tests
Component tests for the uefi variable store are added and
bugs fixed such that all added tests pass. Tests are added
to the component-test deployment.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: Idde768a9fac1f18b370069d104f823fac6456ae5
4 files changed, 801 insertions, 0 deletions
diff --git a/components/service/smm_variable/backend/test/component.cmake b/components/service/smm_variable/backend/test/component.cmake new file mode 100644 index 000000000..8464e6e2d --- /dev/null +++ b/components/service/smm_variable/backend/test/component.cmake @@ -0,0 +1,14 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/variable_index_tests.cpp" + "${CMAKE_CURRENT_LIST_DIR}/variable_store_tests.cpp" + ) diff --git a/components/service/smm_variable/backend/test/variable_index_tests.cpp b/components/service/smm_variable/backend/test/variable_index_tests.cpp new file mode 100644 index 000000000..0c9cafe97 --- /dev/null +++ b/components/service/smm_variable/backend/test/variable_index_tests.cpp @@ -0,0 +1,391 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <wchar.h> +#include <string> +#include <vector> +#include <CppUTest/TestHarness.h> +#include <service/smm_variable/backend/variable_index.h> + + +TEST_GROUP(UefiVariableIndexTests) +{ + void setup() + { + efi_status_t status = variable_index_init(&m_variable_index, MAX_VARIABLES); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + guid_1.Data1 = 0x12341234; + guid_1.Data2 = 0x1234; + guid_1.Data3 = 0x1234; + guid_1.Data4[0] = 0x00; + guid_1.Data4[1] = 0x01; + guid_1.Data4[2] = 0x02; + guid_1.Data4[3] = 0x03; + guid_1.Data4[4] = 0x04; + guid_1.Data4[5] = 0x05; + guid_1.Data4[6] = 0x06; + guid_1.Data4[7] = 0x07; + + guid_2.Data1 = 0x55443322; + guid_2.Data2 = 0x2345; + guid_2.Data3 = 0x2345; + guid_2.Data4[0] = 0x10; + guid_2.Data4[1] = 0x11; + guid_2.Data4[2] = 0x12; + guid_2.Data4[3] = 0x13; + guid_2.Data4[4] = 0x14; + guid_2.Data4[5] = 0x15; + guid_2.Data4[6] = 0x16; + guid_2.Data4[7] = 0x17; + + name_1 = to_variable_name(L"var1"); + name_2 = to_variable_name(L"var2_nv"); + name_3 = to_variable_name(L"var3_nv"); + } + + void teardown() + { + variable_index_deinit(&m_variable_index); + } + + std::vector<int16_t> to_variable_name(const std::wstring &string) + { + std::vector<int16_t> var_name; + + for (size_t i = 0; i < string.size(); i++) { + + var_name.push_back((int16_t)string[i]); + } + + var_name.push_back(0); + + return var_name; + } + + void create_variables() + { + const struct variable_info *info = NULL; + + info = variable_index_add( + &m_variable_index, + &guid_1, + name_1.size() * sizeof(int16_t), + name_1.data(), + EFI_VARIABLE_BOOTSERVICE_ACCESS); + + CHECK_TRUE(info); + + info = variable_index_add( + &m_variable_index, + &guid_2, + name_2.size() * sizeof(int16_t), + name_2.data(), + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS); + + CHECK_TRUE(info); + + info = variable_index_add( + &m_variable_index, + &guid_1, + name_3.size() * sizeof(int16_t), + name_3.data(), + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS); + + CHECK_TRUE(info); + } + + static const size_t MAX_VARIABLES = 10; + + struct variable_index m_variable_index; + EFI_GUID guid_1; + EFI_GUID guid_2; + std::vector<int16_t> name_1; + std::vector<int16_t> name_2; + std::vector<int16_t> name_3; +}; + +TEST(UefiVariableIndexTests, emptyIndexOperations) +{ + const struct variable_info *info = NULL; + + /* Expect not to find a variable */ + info = variable_index_find( + &m_variable_index, + &guid_1, + name_1.size() * sizeof(int16_t), + name_1.data()); + POINTERS_EQUAL(NULL, info); + + /* Expect also not to find the next variable */ + info = variable_index_find_next( + &m_variable_index, + &guid_1, + name_1.size() * sizeof(int16_t), + name_1.data()); + POINTERS_EQUAL(NULL, info); + + /* Remove should silently return */ + variable_index_remove( + &m_variable_index, + &guid_1, + name_1.size() * sizeof(int16_t), + name_1.data()); +} + +TEST(UefiVariableIndexTests, addWithOversizedName) +{ + const struct variable_info *info = NULL; + std::vector<int16_t> name; + + name = to_variable_name(L"a long variable name that exceeds the length limit"); + + info = variable_index_add( + &m_variable_index, + &guid_1, + name.size() * sizeof(int16_t), + name.data(), + EFI_VARIABLE_BOOTSERVICE_ACCESS); + + /* Expect the add to fail because of an oversized name */ + POINTERS_EQUAL(NULL, info); + + name = to_variable_name(L"a long variable name that fits!"); + + info = variable_index_add( + &m_variable_index, + &guid_1, + name.size() * sizeof(int16_t), + name.data(), + EFI_VARIABLE_BOOTSERVICE_ACCESS); + + /* Expect the add succeed */ + CHECK_TRUE(info); +} + +TEST(UefiVariableIndexTests, variableIndexFull) +{ + const struct variable_info *info = NULL; + EFI_GUID guid = guid_1; + + /* Expect to be able to fill the index */ + for (size_t i = 0; i < MAX_VARIABLES; ++i) { + + info = variable_index_add( + &m_variable_index, + &guid, + name_1.size() * sizeof(int16_t), + name_1.data(), + EFI_VARIABLE_BOOTSERVICE_ACCESS); + + CHECK_TRUE(info); + + /* Modify the guid for the next add */ + guid.Data1 += 1; + } + + /* Variable index should now be full */ + info = variable_index_add( + &m_variable_index, + &guid, + name_1.size() * sizeof(int16_t), + name_1.data(), + EFI_VARIABLE_BOOTSERVICE_ACCESS); + + POINTERS_EQUAL(NULL, info); +} + + +TEST(UefiVariableIndexTests, enumerateStore) +{ + const struct variable_info *info = NULL; + const std::vector<int16_t> null_name = to_variable_name(L""); + + create_variables(); + + info = variable_index_find_next( + &m_variable_index, + &guid_1, + null_name.size() * sizeof(int16_t), + null_name.data()); + CHECK_TRUE(info); + LONGS_EQUAL(EFI_VARIABLE_BOOTSERVICE_ACCESS, info->attributes); + MEMCMP_EQUAL(&guid_1, &info->guid, sizeof(EFI_GUID)); + MEMCMP_EQUAL(name_1.data(), info->name, name_1.size()); + + info = variable_index_find_next( + &m_variable_index, + &info->guid, + info->name_size, + info->name); + CHECK_TRUE(info); + LONGS_EQUAL(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, info->attributes); + MEMCMP_EQUAL(&guid_2, &info->guid, sizeof(EFI_GUID)); + MEMCMP_EQUAL(name_2.data(), info->name, name_2.size()); + + info = variable_index_find_next( + &m_variable_index, + &info->guid, + info->name_size, + info->name); + CHECK_TRUE(info); + LONGS_EQUAL(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS, info->attributes); + MEMCMP_EQUAL(&guid_1, &info->guid, sizeof(EFI_GUID)); + MEMCMP_EQUAL(name_3.data(), info->name, name_3.size()); + + info = variable_index_find_next( + &m_variable_index, + &info->guid, + info->name_size, + info->name); + POINTERS_EQUAL(NULL, info); +} + +TEST(UefiVariableIndexTests, dumpLoadRoadtrip) +{ + uint8_t buffer[MAX_VARIABLES * sizeof(struct variable_info)]; + + create_variables(); + + /* Expect the info for two NV variables to have been dumped */ + size_t dump_len = 0; + bool is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len); + + CHECK_TRUE(is_dirty); + UNSIGNED_LONGS_EQUAL((sizeof(struct variable_info) * 2), dump_len); + + /* Expect no records to be dirty when the dump is repeated */ + dump_len = 0; + is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len); + + CHECK_FALSE(is_dirty); + UNSIGNED_LONGS_EQUAL((sizeof(struct variable_info) * 2), dump_len); + + /* Tear down and reinitialize to simulate a reboot */ + variable_index_deinit(&m_variable_index); + efi_status_t status = variable_index_init(&m_variable_index, MAX_VARIABLES); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Load the dumped contents */ + size_t load_len = variable_index_restore(&m_variable_index, dump_len, buffer); + UNSIGNED_LONGS_EQUAL(dump_len, load_len); + + /* Enumerate and now expect only NV variables to be present */ + const struct variable_info *info = NULL; + std::vector<int16_t> null_name = to_variable_name(L""); + + info = variable_index_find_next( + &m_variable_index, + &guid_1, + null_name.size() * sizeof(int16_t), + null_name.data()); + CHECK_TRUE(info); + UNSIGNED_LONGS_EQUAL(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + info->attributes); + + info = variable_index_find_next( + &m_variable_index, + &info->guid, + info->name_size, + info->name); + CHECK_TRUE(info); + UNSIGNED_LONGS_EQUAL(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS, + info->attributes); + + info = variable_index_find_next( + &m_variable_index, + &info->guid, + info->name_size, + info->name); + POINTERS_EQUAL(NULL, info); +} + +TEST(UefiVariableIndexTests, dumpBufferTooSmall) +{ + uint8_t buffer[1 * sizeof(struct variable_info) + 1]; + + create_variables(); + + /* There should be two NV variables whose info needs saving. The buffer provided + * however is only big enough for one. Expect the dumped data length to not + * exceed the length of the buffer. + */ + size_t dump_len = 0; + bool is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len); + + CHECK_TRUE(is_dirty); + UNSIGNED_LONGS_EQUAL(sizeof(struct variable_info) * 1, dump_len); +} + + +TEST(UefiVariableIndexTests, removeVariable) +{ + uint8_t buffer[MAX_VARIABLES * sizeof(struct variable_info)]; + + create_variables(); + + /* Remove one of the NV variables */ + variable_index_remove( + &m_variable_index, + &guid_2, + name_2.size() * sizeof(int16_t), + name_2.data()); + + /* Expect index to be dirty and for only one NV variable to be left */ + size_t dump_len = 0; + bool is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len); + + CHECK_TRUE(is_dirty); + UNSIGNED_LONGS_EQUAL((sizeof(struct variable_info) * 1), dump_len); + + /* Remove the volatile variable */ + variable_index_remove( + &m_variable_index, + &guid_1, + name_1.size() * sizeof(int16_t), + name_1.data()); + + /* Expect index not to be dirty because there was no change to any NV variable */ + dump_len = 0; + is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len); + + CHECK_FALSE(is_dirty); + UNSIGNED_LONGS_EQUAL((sizeof(struct variable_info) * 1), dump_len); + + /* Remove the remaining NV variable */ + variable_index_remove( + &m_variable_index, + &guid_1, + name_3.size() * sizeof(int16_t), + name_3.data()); + + /* Expect index to be dirty and dump to now be empty */ + dump_len = 0; + is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len); + + CHECK_TRUE(is_dirty); + UNSIGNED_LONGS_EQUAL((sizeof(struct variable_info) * 0), dump_len); + + /* Repeat the remove on an empty index. This should have no effect on the empty state + * of the index. + */ + variable_index_remove( + &m_variable_index, + &guid_1, + name_3.size(), + name_3.data()); + + /* Enumerate and now expect an empty index */ + const struct variable_info *info = NULL; + std::vector<int16_t> null_name = to_variable_name(L""); + + info = variable_index_find_next( + &m_variable_index, + &guid_1, + null_name.size() * sizeof(int16_t), + null_name.data()); + POINTERS_EQUAL(NULL, info); +} diff --git a/components/service/smm_variable/backend/test/variable_store_tests.cpp b/components/service/smm_variable/backend/test/variable_store_tests.cpp new file mode 100644 index 000000000..66def8f8a --- /dev/null +++ b/components/service/smm_variable/backend/test/variable_store_tests.cpp @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <string> +#include <vector> +#include <string.h> +#include <CppUTest/TestHarness.h> +#include <service/smm_variable/backend/uefi_variable_store.h> +#include <service/secure_storage/backend/mock_store/mock_store.h> + +TEST_GROUP(UefiVariableStoreTests) +{ + void setup() + { + m_persistent_backend = mock_store_init(&m_persistent_store); + m_volatile_backend = mock_store_init(&m_volatile_store); + + efi_status_t status = uefi_variable_store_init( + &m_uefi_variable_store, + OWNER_ID, + MAX_VARIABLES, + m_persistent_backend, + m_volatile_backend); + + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + setup_common_guid(); + } + + void teardown() + { + uefi_variable_store_deinit(&m_uefi_variable_store); + } + + void setup_common_guid() + { + m_common_guid.Data1 = 0x12341234; + m_common_guid.Data2 = 0x1234; + m_common_guid.Data3 = 0x1234; + m_common_guid.Data4[0] = 0x00; + m_common_guid.Data4[1] = 0x01; + m_common_guid.Data4[2] = 0x02; + m_common_guid.Data4[3] = 0x03; + m_common_guid.Data4[4] = 0x04; + m_common_guid.Data4[5] = 0x05; + m_common_guid.Data4[6] = 0x06; + m_common_guid.Data4[7] = 0x07; + } + + std::vector<int16_t> to_variable_name(const std::wstring &string) + { + std::vector<int16_t> var_name; + + for (size_t i = 0; i < string.size(); i++) { + + var_name.push_back((int16_t)string[i]); + } + + /* Add mandatory null terminator */ + var_name.push_back(0); + + return var_name; + } + + bool compare_variable_name( + const std::wstring &expected, + const int16_t *name, + size_t name_size) { + + bool is_equal = (expected.size() + 1 <= name_size / sizeof(int16_t)); + + for (size_t i = 0; is_equal && i < expected.size(); i++) { + + if (name[i] != (int16_t)expected[i]) { + + is_equal = false; + break; + } + } + + return is_equal; + } + + efi_status_t set_variable( + const std::wstring &name, + const std::string &data, + uint32_t attributes) + { + std::vector<int16_t> var_name = to_variable_name(name); + size_t name_size = var_name.size() * sizeof(int16_t); + size_t data_size = data.size(); + uint8_t msg_buffer[SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_SIZE(name_size, data_size)]; + + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_variable = + (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)msg_buffer; + + access_variable->Guid = m_common_guid; + access_variable->Attributes = attributes; + + access_variable->NameSize = name_size; + memcpy(access_variable->Name, var_name.data(), name_size); + + access_variable->DataSize = data_size; + memcpy(&msg_buffer[SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable)], + data.c_str(), data_size); + + efi_status_t status = uefi_variable_store_set_variable( + &m_uefi_variable_store, + access_variable); + + return status; + } + + efi_status_t get_variable( + const std::wstring &name, + std::string &data) + { + std::vector<int16_t> var_name = to_variable_name(name); + size_t name_size = var_name.size() * sizeof(int16_t); + size_t total_size = 0; + uint8_t msg_buffer[VARIABLE_BUFFER_SIZE]; + + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_variable = + (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE*)msg_buffer; + + access_variable->Guid = m_common_guid; + access_variable->Attributes = 0; + + access_variable->NameSize = name_size; + memcpy(access_variable->Name, var_name.data(), name_size); + + access_variable->DataSize = 0; + + efi_status_t status = uefi_variable_store_get_variable( + &m_uefi_variable_store, + access_variable, + VARIABLE_BUFFER_SIZE - + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable), + &total_size); + + if (status == EFI_SUCCESS) { + + const char *data_start = (const char*)(msg_buffer + + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(access_variable)); + + data = std::string(data_start, access_variable->DataSize); + } + + return status; + } + + void power_cycle() + { + /* Simulate a power-cycle */ + uefi_variable_store_deinit(&m_uefi_variable_store); + + /* Lose volatile store contents */ + mock_store_reset(&m_volatile_store); + + efi_status_t status = uefi_variable_store_init( + &m_uefi_variable_store, + OWNER_ID, + MAX_VARIABLES, + m_persistent_backend, + m_volatile_backend); + + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + } + + static const size_t MAX_VARIABLES = 10; + static const uint32_t OWNER_ID = 100; + static const size_t VARIABLE_BUFFER_SIZE = 1024; + + struct uefi_variable_store m_uefi_variable_store; + struct mock_store m_persistent_store; + struct mock_store m_volatile_store; + struct storage_backend *m_persistent_backend; + struct storage_backend *m_volatile_backend; + EFI_GUID m_common_guid; +}; + +TEST(UefiVariableStoreTests, setGetRoundtrip) +{ + efi_status_t status = EFI_SUCCESS; + std::wstring var_name = L"test_variable"; + std::string input_data = "quick brown fox"; + std::string output_data; + + status = set_variable(var_name, input_data, 0); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + status = get_variable(var_name, output_data); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Expect got variable data to be the same as the set value */ + UNSIGNED_LONGS_EQUAL(input_data.size(), output_data.size()); + LONGS_EQUAL(0, input_data.compare(output_data)); +} + +TEST(UefiVariableStoreTests, persistentSetGet) +{ + efi_status_t status = EFI_SUCCESS; + std::wstring var_name = L"test_variable"; + std::string input_data = "quick brown fox"; + std::string output_data; + + status = set_variable(var_name, input_data, EFI_VARIABLE_NON_VOLATILE); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + status = get_variable(var_name, output_data); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Expect got variable data to be the same as the set value */ + UNSIGNED_LONGS_EQUAL(input_data.size(), output_data.size()); + LONGS_EQUAL(0, input_data.compare(output_data)); + + /* Expect the variable to survive a power cycle */ + power_cycle(); + + output_data = std::string(); + status = get_variable(var_name, output_data); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Still expect got variable data to be the same as the set value */ + UNSIGNED_LONGS_EQUAL(input_data.size(), output_data.size()); + LONGS_EQUAL(0, input_data.compare(output_data)); +} + +TEST(UefiVariableStoreTests, bootServiceAccess) +{ + efi_status_t status = EFI_SUCCESS; + std::wstring var_name = L"test_variable"; + std::string input_data = "a variable with access restricted to boot"; + std::string output_data; + + status = set_variable( + var_name, + input_data, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* 'Reboot' */ + power_cycle(); + + /* Expect access to be permitted */ + status = get_variable(var_name, output_data); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + UNSIGNED_LONGS_EQUAL(input_data.size(), output_data.size()); + LONGS_EQUAL(0, input_data.compare(output_data)); + + /* End of boot phase */ + status = uefi_variable_store_exit_boot_service(&m_uefi_variable_store); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Expect access to be blocked */ + status = get_variable(var_name, output_data); + UNSIGNED_LONGS_EQUAL(EFI_ACCESS_DENIED, status); +} + +TEST(UefiVariableStoreTests, runtimeAccess) +{ + efi_status_t status = EFI_SUCCESS; + std::wstring var_name = L"test_variable"; + std::string input_data = "a variable with access restricted to runtime"; + std::string output_data; + + status = set_variable( + var_name, + input_data, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* 'Reboot' */ + power_cycle(); + + status = get_variable(var_name, output_data); + + UNSIGNED_LONGS_EQUAL(EFI_ACCESS_DENIED, status); + /* End of boot phase */ + status = uefi_variable_store_exit_boot_service(&m_uefi_variable_store); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Expect access to be permitted */ + status = get_variable(var_name, output_data); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + UNSIGNED_LONGS_EQUAL(input_data.size(), output_data.size()); + LONGS_EQUAL(0, input_data.compare(output_data)); +} + +TEST(UefiVariableStoreTests, enumerateStoreContents) +{ + efi_status_t status = EFI_SUCCESS; + std::wstring var_name_1 = L"test_variable_1"; + std::wstring var_name_2 = L"test_variable_2"; + std::wstring var_name_3 = L"test_variable_3"; + std::string input_data = "blah blah"; + + /* Add some variables - a mixture of NV and volatile */ + status = set_variable( + var_name_1, + input_data, + EFI_VARIABLE_NON_VOLATILE); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + status = set_variable( + var_name_2, + input_data, + 0); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + status = set_variable( + var_name_3, + input_data, + EFI_VARIABLE_NON_VOLATILE); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + + /* Prepare to enumerate */ + uint8_t msg_buffer[VARIABLE_BUFFER_SIZE]; + SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name = + (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME*)msg_buffer; + size_t max_name_len = VARIABLE_BUFFER_SIZE - + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET; + + /* Enumerate store contents */ + size_t total_len = 0; + next_name->NameSize = sizeof(int16_t); + next_name->Name[0] = 0; + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize)); + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + CHECK_TRUE(compare_variable_name(var_name_2, next_name->Name, next_name->NameSize)); + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + CHECK_TRUE(compare_variable_name(var_name_3, next_name->Name, next_name->NameSize)); + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGS_EQUAL(EFI_NOT_FOUND, status); + + power_cycle(); + + /* Enumerate again - should be left with just NV variables. + * Use a different but equally valid null name. + */ + next_name->NameSize = 10 * sizeof(int16_t); + memset(next_name->Name, 0, next_name->NameSize); + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status); + CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize)); + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status); + CHECK_TRUE(compare_variable_name(var_name_3, next_name->Name, next_name->NameSize)); + + status = uefi_variable_store_get_next_variable_name( + &m_uefi_variable_store, + next_name, + max_name_len, + &total_len); + UNSIGNED_LONGS_EQUAL(EFI_NOT_FOUND, status); +} diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake index d89443fa6..1ffcb695f 100644 --- a/deployments/component-test/component-test.cmake +++ b/deployments/component-test/component-test.cmake @@ -16,6 +16,7 @@ add_components( COMPONENTS "components/app/ts-demo" "components/app/ts-demo/test" + "components/common/utils" "components/common/uuid" "components/common/uuid/test" "components/common/tlv" @@ -117,6 +118,8 @@ add_components( "components/service/test_runner/provider" "components/service/test_runner/provider/serializer/packed-c" "components/service/test_runner/provider/backend/null" + "components/service/smm_variable/backend" + "components/service/smm_variable/backend/test" "protocols/rpc/common/protobuf" "protocols/rpc/common/packed-c" "protocols/service/crypto/packed-c" |