Update power on handling to allow an alternative hash engine to be used.

This commit is contained in:
Christopher Weimer 2020-09-29 16:40:24 +00:00
Родитель b7beaeb89c
Коммит 208e2a84bd
5 изменённых файлов: 271 добавлений и 30 удалений

Просмотреть файл

@ -8,15 +8,24 @@
#include "host_logging.h"
int host_irq_handler_power_on (struct host_irq_handler *handler, bool allow_unsecure)
int host_irq_handler_power_on (struct host_irq_handler *handler, bool allow_unsecure,
struct hash_engine *hash)
{
int status;
int retries;
bool flash_switched = false;
if (handler == NULL) {
return HOST_IRQ_HANDLER_INVALID_ARGUMENT;
}
if (hash == NULL) {
hash = handler->hash;
}
retries = 1;
do {
status = handler->host->power_on_reset (handler->host, handler->hash, handler->rsa);
status = handler->host->power_on_reset (handler->host, hash, handler->rsa);
if (status != 0) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_ERROR, DEBUG_LOG_COMPONENT_HOST_FW,
HOST_LOGGING_POWER_ON_RESET, host_processor_get_port (handler->host), status);
@ -26,8 +35,7 @@ int host_irq_handler_power_on (struct host_irq_handler *handler, bool allow_unse
retries = 2;
while ((status != 0) && (status != HOST_PROCESSOR_NO_ROLLBACK) &&
(status != HOST_PROCESSOR_ROLLBACK_DIRTY) && (retries--)) {
status = handler->host->flash_rollback (handler->host, handler->hash, handler->rsa, true,
true);
status = handler->host->flash_rollback (handler->host, hash, handler->rsa, true, true);
/* Errors logged in the handler. */
}

Просмотреть файл

@ -21,10 +21,13 @@ struct host_irq_handler {
* @param handler The handler context.
* @param allow_unsecure Flag indicating if the host should be allowed to boot regardless of the
* authentication status.
* @param hash Optional argument to override the hash engine used for power on validation. If
* this is set to null, the internal hash engine will be used for this validation.
*
* @return 0 if power on processing was successful or an error code.
*/
int (*power_on) (struct host_irq_handler *handler, bool allow_unsecure);
int (*power_on) (struct host_irq_handler *handler, bool allow_unsecure,
struct hash_engine *hash);
/**
* Handler for when the host processor signals that it has been reset.
@ -73,7 +76,8 @@ void host_irq_handler_release (struct host_irq_handler *handler);
int host_irq_handler_set_host (struct host_irq_handler *handler, struct host_processor *host);
/* Internal functions for use by derived types. */
int host_irq_handler_power_on (struct host_irq_handler *handler, bool allow_unsecure);
int host_irq_handler_power_on (struct host_irq_handler *handler, bool allow_unsecure,
struct hash_engine *hash);
int host_irq_handler_enter_reset (struct host_irq_handler *handler);
void host_irq_handler_exit_reset (struct host_irq_handler *handler);
void host_irq_handler_assert_cs0 (struct host_irq_handler *handler);

Просмотреть файл

@ -752,7 +752,7 @@ static void host_irq_handler_test_power_on (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -767,6 +767,57 @@ static void host_irq_handler_test_power_on (CuTest *test)
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_alternate_hash (CuTest *test)
{
HASH_TESTING_ENGINE hash;
HASH_TESTING_ENGINE hash2;
RSA_TESTING_ENGINE rsa;
struct host_processor_mock host;
struct bmc_recovery_mock recovery;
struct host_irq_handler handler;
int status;
TEST_START;
status = HASH_TESTING_ENGINE_INIT (&hash);
CuAssertIntEquals (test, 0, status);
status = HASH_TESTING_ENGINE_INIT (&hash2);
CuAssertIntEquals (test, 0, status);
status = RSA_TESTING_ENGINE_INIT (&rsa);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_init (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_init (&recovery);
CuAssertIntEquals (test, 0, status);
status = host_irq_handler_init (&handler, &host.base, &hash.base, &rsa.base, &recovery.base);
CuAssertIntEquals (test, 0, status);
status = mock_expect (&host.mock, host.base.power_on_reset, &host, 0, MOCK_ARG (&hash2),
MOCK_ARG (&rsa));
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false, &hash2.base);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_validate_and_release (&recovery);
CuAssertIntEquals (test, 0, status);
host_irq_handler_release (&handler);
HASH_TESTING_ENGINE_RELEASE (&hash);
HASH_TESTING_ENGINE_RELEASE (&hash2);
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_validation_fail (CuTest *test)
{
HASH_TESTING_ENGINE hash;
@ -800,7 +851,7 @@ static void host_irq_handler_test_power_on_validation_fail (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -848,7 +899,7 @@ static void host_irq_handler_test_power_on_blank_fail (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -896,7 +947,7 @@ static void host_irq_handler_test_power_on_unknown_version (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -944,7 +995,7 @@ static void host_irq_handler_test_power_on_error (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -995,7 +1046,7 @@ static void host_irq_handler_test_power_on_flash_rollback (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1010,6 +1061,62 @@ static void host_irq_handler_test_power_on_flash_rollback (CuTest *test)
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_flash_rollback_alternate_hash (CuTest *test)
{
HASH_TESTING_ENGINE hash;
HASH_TESTING_ENGINE hash2;
RSA_TESTING_ENGINE rsa;
struct host_processor_mock host;
struct bmc_recovery_mock recovery;
struct host_irq_handler handler;
int status;
TEST_START;
status = HASH_TESTING_ENGINE_INIT (&hash);
CuAssertIntEquals (test, 0, status);
status = HASH_TESTING_ENGINE_INIT (&hash2);
CuAssertIntEquals (test, 0, status);
status = RSA_TESTING_ENGINE_INIT (&rsa);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_init (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_init (&recovery);
CuAssertIntEquals (test, 0, status);
status = host_irq_handler_init (&handler, &host.base, &hash.base, &rsa.base, &recovery.base);
CuAssertIntEquals (test, 0, status);
status = mock_expect (&host.mock, host.base.power_on_reset, &host, HOST_PROCESSOR_POR_FAILED,
MOCK_ARG (&hash2), MOCK_ARG (&rsa));
status |= mock_expect (&host.mock, host.base.power_on_reset, &host, HOST_PROCESSOR_POR_FAILED,
MOCK_ARG (&hash2), MOCK_ARG (&rsa));
status |= mock_expect (&host.mock, host.base.flash_rollback, &host, 0, MOCK_ARG (&hash2),
MOCK_ARG (&rsa), MOCK_ARG (true), MOCK_ARG (true));
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false, &hash2.base);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_validate_and_release (&recovery);
CuAssertIntEquals (test, 0, status);
host_irq_handler_release (&handler);
HASH_TESTING_ENGINE_RELEASE (&hash);
HASH_TESTING_ENGINE_RELEASE (&hash2);
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_flash_rollback_validation_fail (CuTest *test)
{
HASH_TESTING_ENGINE hash;
@ -1048,7 +1155,7 @@ static void host_irq_handler_test_power_on_flash_rollback_validation_fail (CuTes
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1101,7 +1208,7 @@ static void host_irq_handler_test_power_on_flash_rollback_blank_fail (CuTest *te
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1155,7 +1262,7 @@ static void host_irq_handler_test_power_on_flash_rollback_unknown_version (CuTes
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1209,7 +1316,7 @@ static void host_irq_handler_test_power_on_flash_rollback_error (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1262,7 +1369,7 @@ static void host_irq_handler_test_power_on_flash_rollback_no_rollback (CuTest *t
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1316,7 +1423,7 @@ static void host_irq_handler_test_power_on_flash_rollback_rollback_dirty (CuTest
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1373,7 +1480,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1388,6 +1495,68 @@ static void host_irq_handler_test_power_on_apply_recovery_image (CuTest *test)
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_apply_recovery_image_alternate_hash (CuTest *test)
{
HASH_TESTING_ENGINE hash;
HASH_TESTING_ENGINE hash2;
RSA_TESTING_ENGINE rsa;
struct host_processor_mock host;
struct bmc_recovery_mock recovery;
struct host_irq_handler handler;
int status;
TEST_START;
status = HASH_TESTING_ENGINE_INIT (&hash);
CuAssertIntEquals (test, 0, status);
status = HASH_TESTING_ENGINE_INIT (&hash2);
CuAssertIntEquals (test, 0, status);
status = RSA_TESTING_ENGINE_INIT (&rsa);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_init (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_init (&recovery);
CuAssertIntEquals (test, 0, status);
status = host_irq_handler_init (&handler, &host.base, &hash.base, &rsa.base, &recovery.base);
CuAssertIntEquals (test, 0, status);
status = mock_expect (&host.mock, host.base.power_on_reset, &host, HOST_PROCESSOR_POR_FAILED,
MOCK_ARG (&hash2), MOCK_ARG (&rsa));
status |= mock_expect (&host.mock, host.base.power_on_reset, &host, HOST_PROCESSOR_POR_FAILED,
MOCK_ARG (&hash2), MOCK_ARG (&rsa));
status |= mock_expect (&host.mock, host.base.flash_rollback, &host,
HOST_PROCESSOR_ROLLBACK_FAILED, MOCK_ARG (&hash2), MOCK_ARG (&rsa), MOCK_ARG (true),
MOCK_ARG (true));
status |= mock_expect (&host.mock, host.base.flash_rollback, &host,
HOST_PROCESSOR_ROLLBACK_FAILED, MOCK_ARG (&hash2), MOCK_ARG (&rsa), MOCK_ARG (true),
MOCK_ARG (true));
status |= mock_expect (&host.mock, host.base.apply_recovery_image, &host, 0, MOCK_ARG (true));
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false, &hash2.base);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_validate_and_release (&recovery);
CuAssertIntEquals (test, 0, status);
host_irq_handler_release (&handler);
HASH_TESTING_ENGINE_RELEASE (&hash);
HASH_TESTING_ENGINE_RELEASE (&hash2);
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_apply_recovery_image_error (CuTest *test)
{
HASH_TESTING_ENGINE hash;
@ -1432,7 +1601,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image_error (CuTest *t
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1492,7 +1661,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image_retry_error (CuT
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, HOST_PROCESSOR_RECOVERY_IMG_FAILED, status);
status = host_processor_mock_validate_and_release (&host);
@ -1550,7 +1719,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image_unsupported (CuT
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, HOST_PROCESSOR_RECOVERY_UNSUPPORTED, status);
status = host_processor_mock_validate_and_release (&host);
@ -1608,7 +1777,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image_no_image (CuTest
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, false);
status = handler.power_on (&handler, false, NULL);
CuAssertIntEquals (test, HOST_PROCESSOR_NO_RECOVERY_IMAGE, status);
status = host_processor_mock_validate_and_release (&host);
@ -1669,7 +1838,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image_unsupported_allo
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, true);
status = handler.power_on (&handler, true, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1730,7 +1899,7 @@ static void host_irq_handler_test_power_on_apply_recovery_image_no_image_allow_u
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, true);
status = handler.power_on (&handler, true, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1792,7 +1961,7 @@ static void host_irq_handler_test_power_on_bypass_mode (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, true);
status = handler.power_on (&handler, true, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1856,7 +2025,7 @@ static void host_irq_handler_test_power_on_bypass_mode_error (CuTest *test)
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, true);
status = handler.power_on (&handler, true, NULL);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_validate_and_release (&host);
@ -1921,7 +2090,7 @@ static void host_irq_handler_test_power_on_bypass_mode_retry_error (CuTest *test
CuAssertIntEquals (test, 0, status);
status = handler.power_on (&handler, true);
status = handler.power_on (&handler, true, NULL);
CuAssertIntEquals (test, HOST_PROCESSOR_BYPASS_FAILED, status);
status = host_processor_mock_validate_and_release (&host);
@ -1936,6 +2105,47 @@ static void host_irq_handler_test_power_on_bypass_mode_retry_error (CuTest *test
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_power_on_null (CuTest *test)
{
HASH_TESTING_ENGINE hash;
RSA_TESTING_ENGINE rsa;
struct host_processor_mock host;
struct bmc_recovery_mock recovery;
struct host_irq_handler handler;
int status;
TEST_START;
status = HASH_TESTING_ENGINE_INIT (&hash);
CuAssertIntEquals (test, 0, status);
status = RSA_TESTING_ENGINE_INIT (&rsa);
CuAssertIntEquals (test, 0, status);
status = host_processor_mock_init (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_init (&recovery);
CuAssertIntEquals (test, 0, status);
status = host_irq_handler_init (&handler, &host.base, &hash.base, &rsa.base, &recovery.base);
CuAssertIntEquals (test, 0, status);
status = handler.power_on (NULL, false, NULL);
CuAssertIntEquals (test, HOST_IRQ_HANDLER_INVALID_ARGUMENT, status);
status = host_processor_mock_validate_and_release (&host);
CuAssertIntEquals (test, 0, status);
status = bmc_recovery_mock_validate_and_release (&recovery);
CuAssertIntEquals (test, 0, status);
host_irq_handler_release (&handler);
HASH_TESTING_ENGINE_RELEASE (&hash);
RSA_TESTING_ENGINE_RELEASE (&rsa);
}
static void host_irq_handler_test_set_host (CuTest *test)
{
HASH_TESTING_ENGINE hash;
@ -2069,11 +2279,13 @@ CuSuite* get_host_irq_handler_suite ()
SUITE_ADD_TEST (suite, host_irq_handler_test_assert_cs1_null);
SUITE_ADD_TEST (suite, host_irq_handler_test_assert_cs1_recovery_error);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_alternate_hash);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_validation_fail);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_blank_fail);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_unknown_version);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_error);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback_alternate_hash);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback_validation_fail);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback_blank_fail);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback_unknown_version);
@ -2081,6 +2293,7 @@ CuSuite* get_host_irq_handler_suite ()
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback_no_rollback);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_flash_rollback_rollback_dirty);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_apply_recovery_image);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_apply_recovery_image_alternate_hash);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_apply_recovery_image_error);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_apply_recovery_image_retry_error);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_apply_recovery_image_unsupported);
@ -2092,6 +2305,7 @@ CuSuite* get_host_irq_handler_suite ()
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_bypass_mode);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_bypass_mode_error);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_bypass_mode_retry_error);
SUITE_ADD_TEST (suite, host_irq_handler_test_power_on_null);
SUITE_ADD_TEST (suite, host_irq_handler_test_set_host);
SUITE_ADD_TEST (suite, host_irq_handler_test_set_host_null);

Просмотреть файл

@ -7,7 +7,8 @@
#include "host_irq_handler_mock.h"
static int host_irq_handler_mock_power_on (struct host_irq_handler *handler, bool allow_unsecure)
static int host_irq_handler_mock_power_on (struct host_irq_handler *handler, bool allow_unsecure,
struct hash_engine *hash)
{
struct host_irq_handler_mock *mock = (struct host_irq_handler_mock*) handler;
@ -16,7 +17,7 @@ static int host_irq_handler_mock_power_on (struct host_irq_handler *handler, boo
}
MOCK_RETURN (&mock->mock, host_irq_handler_mock_power_on, handler,
MOCK_ARG_CALL (allow_unsecure));
MOCK_ARG_CALL (allow_unsecure), MOCK_ARG_CALL (hash));
}
static int host_irq_handler_mock_enter_reset (struct host_irq_handler *handler)
@ -65,6 +66,10 @@ static int host_irq_handler_mock_assert_cs1 (struct host_irq_handler *handler)
static int host_irq_handler_mock_func_arg_count (void *func)
{
if (func == host_irq_handler_mock_power_on) {
return 2;
}
return 0;
}
@ -92,6 +97,16 @@ static const char* host_irq_handler_mock_func_name_map (void *func)
static const char* host_irq_handler_mock_arg_name_map (void *func, int arg)
{
if (func == host_irq_handler_mock_power_on) {
switch (arg) {
case 0:
return "allow_unsecure";
case 1:
return "hash";
}
}
return "unknown";
}

0
tools/testing/tcg_log_test.py Normal file → Executable file
Просмотреть файл