blob: d95ae8e8fa3b656af3df6c3eb2935ce283be9d10 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_hmac.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/hmac_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_main.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
OTTF_DEFINE_TEST_CONFIG();
static const dif_hmac_transaction_t kHmacTransactionConfig = {
.digest_endianness = kDifHmacEndiannessLittle,
.message_endianness = kDifHmacEndiannessLittle,
};
static const char kData[142] =
"Every one suspects himself of at least one of "
"the cardinal virtues, and this is mine: I am "
"one of the few honest people that I have ever "
"known";
static uint32_t kHmacKey[8] = {
0xec4e6c89, 0x082efa98, 0x299f31d0, 0xa4093822,
0x03707344, 0x13198a2e, 0x85a308d3, 0x243f6a88,
};
static const dif_hmac_digest_t kExpectedShaDigest = {
.digest =
{
0xd6c6c94e,
0xf7cff519,
0x45c76d42,
0x9d37a8b8,
0xe2762fe9,
0x71ff68cb,
0x68e236af,
0x3dc296dc,
},
};
static const dif_hmac_digest_t kExpectedHmacDigest = {
.digest =
{
0xebce4019,
0x284d39f1,
0x5eae12b0,
0x0c48fb23,
0xfadb9531,
0xafbbf3c2,
0x90d3833f,
0x397b98e4,
},
};
/**
* Initialize the HMAC engine. Return `true` if the configuration is valid.
*/
static void test_setup(mmio_region_t base_addr, dif_hmac_t *hmac) {
CHECK_DIF_OK(dif_hmac_init(base_addr, hmac));
}
/**
* Start HMAC in the correct mode. If `key` == NULL use SHA256 mode, otherwise
* use the provided key in HMAC mode.
*/
static void test_start(const dif_hmac_t *hmac, const uint8_t *key) {
// Let a null key indicate we are operating in SHA256-only mode.
if (key == NULL) {
CHECK_DIF_OK(dif_hmac_mode_sha256_start(hmac, kHmacTransactionConfig));
} else {
CHECK_DIF_OK(dif_hmac_mode_hmac_start(hmac, key, kHmacTransactionConfig));
}
}
/**
* Kick off the HMAC (or SHA256) run.
*/
static void run_hmac(const dif_hmac_t *hmac) {
CHECK_DIF_OK(dif_hmac_process(hmac));
}
static void run_test(const dif_hmac_t *hmac, const char *data, size_t len,
const uint8_t *key,
const dif_hmac_digest_t *expected_digest) {
test_start(hmac, key);
hmac_testutils_push_message(hmac, data, len);
hmac_testutils_fifo_empty_polled(hmac);
hmac_testutils_check_message_length(hmac, len * 8);
run_hmac(hmac);
hmac_testutils_finish_and_check_polled(hmac, expected_digest);
}
bool test_main(void) {
LOG_INFO("Running HMAC DIF test...");
dif_hmac_t hmac;
test_setup(mmio_region_from_addr(TOP_EARLGREY_HMAC_BASE_ADDR), &hmac);
LOG_INFO("Running test SHA256 pass 1...");
run_test(&hmac, kData, sizeof(kData), NULL, &kExpectedShaDigest);
LOG_INFO("Running test SHA256 pass 2...");
run_test(&hmac, kData, sizeof(kData), NULL, &kExpectedShaDigest);
LOG_INFO("Running test HMAC pass 1...");
run_test(&hmac, kData, sizeof(kData), (uint8_t *)(&kHmacKey[0]),
&kExpectedHmacDigest);
LOG_INFO("Running test HMAC pass 2...");
run_test(&hmac, kData, sizeof(kData), (uint8_t *)(&kHmacKey[0]),
&kExpectedHmacDigest);
return true;
}