Software APIs
kmac_testutils.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 "sw/device/lib/testing/kmac_testutils.h"
6
8#include "sw/device/lib/testing/test_framework/check.h"
9
10status_t kmac_testutils_config(dif_kmac_t *kmac, bool sideload) {
11 dif_kmac_config_t config = {
12 // Use software-provided "entropy" to avoid waiting for EDN.
13 .entropy_mode = kDifKmacEntropyModeSoftware,
14 // This option minimizes masking to improve speed.
15 .entropy_fast_process = true,
16 // No need to have real entropy for tests.
17 .entropy_seed = {0},
18 .entropy_hash_threshold = 0,
19 // Ignored because the entropy source is software.
20 .entropy_wait_timer = 0,
21 // Leave message as the little-endian default.
22 .entropy_prescaler = 0,
23 .message_big_endian = false,
24 // Leave output as the little-endian default.
25 .output_big_endian = false,
26 // Use a sideloaded key if the caller requested to.
27 .sideload = sideload,
28 // Avoid masking the message to improve speed.
29 .msg_mask = false,
30 };
31
32 TRY(dif_kmac_configure(kmac, config));
33 return OK_STATUS();
34}
35
36status_t kmac_testutils_kmac(const dif_kmac_t *kmac,
37 const dif_kmac_mode_kmac_t mode,
38 const dif_kmac_key_t *key,
39 const char *custom_string,
40 const size_t custom_string_len,
41 const char *message, const size_t message_len,
42 const size_t output_len, uint32_t *output,
43 uint32_t *capacity) {
44 // Initialize customization string.
45 dif_kmac_customization_string_t kmac_custom_string;
46 TRY(dif_kmac_customization_string_init(custom_string, custom_string_len,
47 &kmac_custom_string));
48
49 // Start the KMAC operation and check that KMAC doesn't report an error.
50 dif_kmac_operation_state_t operation_state;
51 TRY(dif_kmac_mode_kmac_start(kmac, &operation_state, mode, output_len, key,
52 &kmac_custom_string));
53 TRY(kmac_testutils_check_error(kmac));
54
55 // Pass the entire message to KMAC ("absorb" stage) and check that KMAC
56 // doesn't report an error.
57 TRY(dif_kmac_absorb(kmac, &operation_state, message, message_len, NULL));
58 TRY(kmac_testutils_check_error(kmac));
59
60 // Get the output ("squeeze" stage) and check that KMAC doesn't report an
61 // error.
62 TRY(dif_kmac_squeeze(kmac, &operation_state, output, output_len, NULL,
63 capacity));
64 TRY(kmac_testutils_check_error(kmac));
65
66 // End the operation and check that KMAC doesn't report an error.
67 TRY(dif_kmac_end(kmac, &operation_state));
68 TRY(kmac_testutils_check_error(kmac));
69
70 return OK_STATUS();
71}
72
73status_t kmac_testutils_check_error(const dif_kmac_t *kmac) {
74 bool error;
75 TRY(dif_kmac_has_error_occurred(kmac, &error));
76
77 // If no error has occurred, return early with OK.
78 if (!error) {
79 return OK_STATUS();
80 }
81
82 // Obtain more information on the error.
84 uint32_t info;
85 TRY(dif_kmac_get_error(kmac, &err, &info));
86
87 // Clear the error IRQ.
88 TRY(dif_kmac_clear_err_irq(kmac));
89
90 // Inform HW that we have handled the error.
91 TRY(dif_kmac_err_processed(kmac));
92
93 // Return with a status based on the error code.
94 switch (err) {
96 return FAILED_PRECONDITION();
97 default:
98 return INTERNAL();
99 }
100}