Software APIs
hmac_testutils.h
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#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_HMAC_TESTUTILS_H_
6#define OPENTITAN_SW_DEVICE_LIB_TESTING_HMAC_TESTUTILS_H_
7
8#include <assert.h>
9#include <stdint.h>
10
13#include "sw/device/lib/base/status.h"
15#include "sw/device/lib/testing/test_framework/check.h"
16
17#define MODULE_ID MAKE_MODULE_ID('h', 'm', 'h')
18
19/**
20 * Timeouts to be used for different HMAC operations.
21 *
22 * All timeouts are calculated against the `kClockFreqCpuHz`, in order
23 * to cover a range of targets. Please see:
24 * https://docs.opentitan.org/hw/ip/hmac/doc/
25 *
26 * 10 cycles are added to the length of the corresponding operation as
27 * described in the documentation. This is to cover any potential
28 * inconsistencies or minor IP changes.
29 *
30 * To avoid cases with sub uS timeout due to very high clock frequency, we
31 * guarantee 1uS minimal timeout by adding it in the end.
32 */
33
34/**
35 * FIFO empty timeout.
36 *
37 * single HMAC block compression takes 80 cycles.
38 */
39static inline status_t compute_hmac_testutils_fifo_empty_usec(
40 uint32_t *out_usec) {
41 uint64_t result = udiv64_slow((80 + 10) * 1000000, kClockFreqCpuHz, NULL) + 1;
42 TRY_CHECK(result <= UINT32_MAX, "timeout must fit in uint32_t");
43 *out_usec = (uint32_t)result;
44 return OK_STATUS();
45}
46
47/**
48 * HMAC done timeout.
49 *
50 * Final hash calculation takes 360 cycles, which consists of one block
51 * compression and extra HMAC computation.
52 */
53static inline status_t compute_hmac_testutils_finish_timeout_usec(
54 uint32_t *out_usec) {
55 uint64_t result =
56 udiv64_slow((360 + 10) * 1000000, kClockFreqCpuHz, NULL) + 1;
57 TRY_CHECK(result <= UINT32_MAX, "timeout must fit in uint32_t");
58 *out_usec = (uint32_t)result;
59 return OK_STATUS();
60}
61
62/**
63 * Reference key and tag for testing from NIST.
64 *
65 * https://csrc.nist.gov/CSRC/media/Projects/
66 * Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA256.pdf
67 *
68 * Key Length: 100
69 * Tag length: 32
70 *
71 * When key is > than the block size, it should be hashed to obtain the block
72 * sized key. Please refer to:
73 * https://csrc.nist.gov/csrc/media/publications/fips/198/archive/
74 * 2002-03-06/documents/fips-198a.pdf
75 *
76 * Specifically chapter 3 and 5 (Table 1).
77 */
78
79/**
80 * This should be hashed with SHA-256 to generate the key.
81 */
82extern const uint8_t kHmacRefLongKey[100];
83
84/**
85 * Expected SHA digest for kHmacRefLongKey data above.
86 */
87extern const dif_hmac_digest_t kHmacRefExpectedLongKeyDigest;
88
89/**
90 * This is used as data for the MAC computation, using
91 * kHmacRefExpectedLongKeyDigest as the key.
92 */
93extern const char kHmacRefData[34];
94
95/**
96 * Expected MAC digest for kHmacRefData data above.
97 */
98extern const dif_hmac_digest_t kHmacRefExpectedDigest;
99
100/**
101 * Reads and compares the actual sent message length against expected.
102 *
103 * The message length is provided in bits.
104 *
105 * @param hmac An HMAC handle.
106 * @param expected_sent_bits Expected size of hashed data in bits.
107 */
109status_t hmac_testutils_check_message_length(const dif_hmac_t *hmac,
110 uint64_t expected_sent_bits);
111
112/**
113 * Spins until the HMAC FIFO is empty, or has timed out.
114 *
115 * Internally uses `kHmacTestutilsFifoEmptyTimeoutUsec`.
116 *
117 * @param hmac An HMAC handle.
118 */
120status_t hmac_testutils_fifo_empty_polled(const dif_hmac_t *hmac);
121
122/**
123 * Spins until the HMAC has finished processing final hash, or timed out.
124 *
125 * Internally uses `kHmacTestutilsFinishTimeoutUsec`.
126 *
127 * @param hmac An HMAC handle.
128 * @param digest_out HMAC final digest.
129 */
131status_t hmac_testutils_finish_polled(const dif_hmac_t *hmac,
132 dif_hmac_digest_t *digest_out);
133
134/**
135 * Spins until HMAC has processed the final hash, and compares the digests.
136 *
137 * Convenience function that combines `hmac_testutils_finish_polled` and
138 * and `CHECK_ARRAYS_EQ`.
139 *
140 * @param hmac An HMAC handle.
141 * @param expected Expected HMAC final digest.
142 */
144status_t hmac_testutils_finish_and_check_polled(
145 const dif_hmac_t *hmac, const dif_hmac_digest_t *expected);
146
147/**
148 * Loads entire message into the HMAC engine.
149 *
150 * Internally uses `hmac_testutils_fifo_empty_polled` after every push to
151 * avoid the back pressure.
152 *
153 * @param hmac An HMAC handle.
154 * @param data Data to be hashed.
155 * @param len Size of the data to be hashed.
156 */
158status_t hmac_testutils_push_message(const dif_hmac_t *hmac, const char *data,
159 size_t len);
160
161#undef MODULE_ID
162
163#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_HMAC_TESTUTILS_H_