Software APIs
hmac_smoketest.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "dt/dt_hmac.h"
10 #include "sw/device/lib/testing/hmac_testutils.h"
11 #include "sw/device/lib/testing/test_framework/check.h"
13 
14 static_assert(kDtHmacCount >= 1,
15  "This test requires at least one HMAC instance");
16 
17 static dt_hmac_t kTestHmac = (dt_hmac_t)0;
18 
19 OTTF_DEFINE_TEST_CONFIG();
20 
21 static const dif_hmac_transaction_t kHmacTransactionConfig = {
23  .message_endianness = kDifHmacEndiannessLittle,
24 };
25 
26 static const char kData[142] =
27  "Every one suspects himself of at least one of "
28  "the cardinal virtues, and this is mine: I am "
29  "one of the few honest people that I have ever "
30  "known";
31 
32 static uint32_t kHmacKey[8] = {
33  0xec4e6c89, 0x082efa98, 0x299f31d0, 0xa4093822,
34  0x03707344, 0x13198a2e, 0x85a308d3, 0x243f6a88,
35 };
36 
37 static const dif_hmac_digest_t kExpectedShaDigest = {
38  .digest =
39  {
40  0xd6c6c94e,
41  0xf7cff519,
42  0x45c76d42,
43  0x9d37a8b8,
44  0xe2762fe9,
45  0x71ff68cb,
46  0x68e236af,
47  0x3dc296dc,
48  },
49 };
50 
51 static const dif_hmac_digest_t kExpectedHmacDigest = {
52  .digest =
53  {
54  0xebce4019,
55  0x284d39f1,
56  0x5eae12b0,
57  0x0c48fb23,
58  0xfadb9531,
59  0xafbbf3c2,
60  0x90d3833f,
61  0x397b98e4,
62  },
63 };
64 
65 /**
66  * Initialize the HMAC engine. Return `true` if the configuration is valid.
67  */
68 static void test_setup(mmio_region_t base_addr, dif_hmac_t *hmac) {
69  CHECK_DIF_OK(dif_hmac_init(base_addr, hmac));
70 }
71 
72 /**
73  * Start HMAC in the correct mode. If `key` == NULL use SHA256 mode, otherwise
74  * use the provided key in HMAC mode.
75  */
76 static void test_start(const dif_hmac_t *hmac, const uint8_t *key) {
77  // Let a null key indicate we are operating in SHA256-only mode.
78  if (key == NULL) {
79  CHECK_DIF_OK(dif_hmac_mode_sha256_start(hmac, kHmacTransactionConfig));
80  } else {
81  CHECK_DIF_OK(dif_hmac_mode_hmac_start(hmac, key, kHmacTransactionConfig));
82  }
83 }
84 
85 /**
86  * Kick off the HMAC (or SHA256) run.
87  */
88 static void run_hmac(const dif_hmac_t *hmac) {
89  CHECK_DIF_OK(dif_hmac_process(hmac));
90 }
91 
92 static void run_test(const dif_hmac_t *hmac, const char *data, size_t len,
93  const uint8_t *key,
94  const dif_hmac_digest_t *expected_digest) {
95  test_start(hmac, key);
96  CHECK_STATUS_OK(hmac_testutils_push_message(hmac, data, len));
97  CHECK_STATUS_OK(hmac_testutils_fifo_empty_polled(hmac));
98  CHECK_STATUS_OK(hmac_testutils_check_message_length(hmac, len * 8));
99  run_hmac(hmac);
100  CHECK_STATUS_OK(
101  hmac_testutils_finish_and_check_polled(hmac, expected_digest));
102 }
103 
104 bool test_main(void) {
105  LOG_INFO("Running HMAC DIF test...");
106 
107  dif_hmac_t hmac;
108  CHECK_DIF_OK(dif_hmac_init_from_dt(kTestHmac, &hmac));
109 
110  LOG_INFO("Running test SHA256 pass 1...");
111  run_test(&hmac, kData, sizeof(kData), NULL, &kExpectedShaDigest);
112 
113  LOG_INFO("Running test SHA256 pass 2...");
114  run_test(&hmac, kData, sizeof(kData), NULL, &kExpectedShaDigest);
115 
116  LOG_INFO("Running test HMAC pass 1...");
117  run_test(&hmac, kData, sizeof(kData), (uint8_t *)(&kHmacKey[0]),
118  &kExpectedHmacDigest);
119 
120  LOG_INFO("Running test HMAC pass 2...");
121  run_test(&hmac, kData, sizeof(kData), (uint8_t *)(&kHmacKey[0]),
122  &kExpectedHmacDigest);
123 
124  return true;
125 }