blob: 1e83984c15f62b5993b06302a039647bd67b4b70 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_TESTING_HMAC_TESTUTILS_H_
#define OPENTITAN_SW_DEVICE_LIB_TESTING_HMAC_TESTUTILS_H_
#include <assert.h>
#include <stdint.h>
#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/dif/dif_hmac.h"
/**
* Timeouts to be used for different HMAC operations.
*
* All timeouts are calculated against the `kClockFreqCpuHz`, in order
* to cover a range of targets. Please see:
* https://docs.opentitan.org/hw/ip/hmac/doc/
*
* 10 cycles are added to the length of the corresponding operation as
* described in the documentation. This is to cover any potential
* inconsistencies or minor IP changes.
*
* To avoid cases with sub uS timeout due to very high clock frequency, we
* guarantee 1uS minimal timeout by adding it in the end.
*/
/**
* FIFO empty timeout.
*
* single HMAC block compression takes 80 cycles.
*/
#define HMAC_TESTUTILS_FIFO_EMPTY_USEC \
(udiv64_slow((80 + 10) * 1000000, kClockFreqCpuHz, NULL) + 1)
/**
* HMAC done timeout.
*
* Final hash calculation takes 360 cycles, which consists of one block
* compression and extra HMAC computation.
*/
#define HMAC_TESTUTILS_FINISH_TIMEOUT_USEC \
(udiv64_slow((360 + 10) * 1000000, kClockFreqCpuHz, NULL) + 1)
/**
* Reference key and tag for testing from NIST.
*
* https://csrc.nist.gov/CSRC/media/Projects/
* Cryptographic-Standards-and-Guidelines/documents/examples/HMAC_SHA256.pdf
*
* Key Length: 100
* Tag length: 32
*
* When key is > than the block size, it should be hashed to obtain the block
* sized key. Please refer to:
* https://csrc.nist.gov/csrc/media/publications/fips/198/archive/
* 2002-03-06/documents/fips-198a.pdf
*
* Specifically chapter 3 and 5 (Table 1).
*/
/**
* This should be hashed with SHA-256 to generate the key.
*/
extern const uint8_t kHmacRefLongKey[100];
/**
* Expected SHA digest for kHmacRefLongKey data above.
*/
extern const dif_hmac_digest_t kHmacRefExpectedLongKeyDigest;
/**
* This is used as data for the MAC computation, using
* kHmacRefExpectedLongKeyDigest as the key.
*/
extern const char kHmacRefData[34];
/**
* Expected MAC digest for kHmacRefData data above.
*/
extern const dif_hmac_digest_t kHmacRefExpectedDigest;
/**
* Reads and compares the actual sent message length against expected.
*
* The message length is provided in bits.
*
* @param hmac An HMAC handle.
* @param expected_sent_bits Expected size of hashed data in bits.
*/
void hmac_testutils_check_message_length(const dif_hmac_t *hmac,
uint64_t expected_sent_bits);
/**
* Spins until the HMAC FIFO is empty, or has timed out.
*
* Internally uses `kHmacTestutilsFifoEmptyTimeoutUsec`.
*
* @param hmac An HMAC handle.
*/
void hmac_testutils_fifo_empty_polled(const dif_hmac_t *hmac);
/**
* Spins until the HMAC has finished processing final hash, or timed out.
*
* Internally uses `kHmacTestutilsFinishTimeoutUsec`.
*
* @param hmac An HMAC handle.
* @param digest_out HMAC final digest.
*/
void hmac_testutils_finish_polled(const dif_hmac_t *hmac,
dif_hmac_digest_t *digest_out);
/**
* Spins until HMAC has processed the final hash, and compares the digests.
*
* Convenience function that combines `hmac_testutils_finish_polled` and
* and `CHECK_ARRAYS_EQ`.
*
* @param hmac An HMAC handle.
* @param expected Expected HMAC final digest.
*/
void hmac_testutils_finish_and_check_polled(const dif_hmac_t *hmac,
const dif_hmac_digest_t *expected);
/**
* Loads entire message into the HMAC engine.
*
* Internally uses `hmac_testutils_fifo_empty_polled` after every push to
* avoid the back pressure.
*
* @param hmac An HMAC handle.
* @param data Data to be hashed.
* @param len Size of the data to be hashed.
*/
void hmac_testutils_push_message(const dif_hmac_t *hmac, const char *data,
size_t len);
#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_HMAC_TESTUTILS_H_