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  */
39 static 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  */
53 static 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  */
82 extern const uint8_t kHmacRefLongKey[100];
83 
84 /**
85  * Expected SHA digest for kHmacRefLongKey data above.
86  */
87 extern 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  */
93 extern const char kHmacRefData[34];
94 
95 /**
96  * Expected MAC digest for kHmacRefData data above.
97  */
98 extern 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  */
109 status_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  */
120 status_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  */
131 status_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  */
144 status_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  */
158 status_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_