Software APIs
kmac_functest.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/crypto/drivers/entropy.h"
6 #include "sw/device/lib/crypto/drivers/kmac.h"
7 #include "sw/device/lib/crypto/impl/integrity.h"
12 #include "sw/device/lib/testing/test_framework/check.h"
14 
15 // The autogen rule that creates this header creates it in a directory named
16 // after the rule, then manipulates the include path in the
17 // cc_compilation_context to include that directory, so the compiler will find
18 // the version of this file matching the Bazel rule under test.
19 #include "kmac_testvectors.h"
20 
21 #define MODULE_ID MAKE_MODULE_ID('t', 's', 't')
22 
23 // Global pointer to the current test vector.
24 static kmac_test_vector_t *current_test_vector = NULL;
25 
26 /**
27  * Get the mode for SHAKE based on the security strength.
28  *
29  * @param security_str Security strength (in bits).
30  * @param[out] mode SHAKE mode enum value.
31  */
32 status_t get_shake_mode(size_t security_strength, otcrypto_hash_mode_t *mode) {
33  switch (security_strength) {
34  case 128:
35  *mode = kOtcryptoHashXofModeShake128;
36  break;
37  case 256:
38  *mode = kOtcryptoHashXofModeShake256;
39  break;
40  default:
41  LOG_INFO("Invalid security strength for SHAKE: %d bits",
42  security_strength);
43  return INVALID_ARGUMENT();
44  }
45  return OK_STATUS();
46 }
47 
48 /**
49  * Get the mode for cSHAKE based on the security strength.
50  *
51  * @param security_str Security strength (in bits).
52  * @param[out] mode cSHAKE mode enum value.
53  */
54 status_t get_cshake_mode(size_t security_strength, otcrypto_hash_mode_t *mode) {
55  switch (security_strength) {
56  case 128:
57  *mode = kOtcryptoHashXofModeCshake128;
58  break;
59  case 256:
60  *mode = kOtcryptoHashXofModeCshake256;
61  break;
62  default:
63  LOG_INFO("Invalid security strength for cSHAKE: %d bits",
64  security_strength);
65  return INVALID_ARGUMENT();
66  }
67  return OK_STATUS();
68 }
69 
70 /**
71  * Get the mode for SHA3 based on the security strength.
72  *
73  * @param security_str Security strength (in bits).
74  * @param[out] mode Hash mode enum value.
75  */
76 status_t get_sha3_mode(size_t security_strength, otcrypto_hash_mode_t *mode) {
77  switch (security_strength) {
78  case 224:
79  *mode = kOtcryptoHashModeSha3_224;
80  break;
81  case 256:
82  *mode = kOtcryptoHashModeSha3_256;
83  break;
84  case 384:
85  *mode = kOtcryptoHashModeSha3_384;
86  break;
87  case 512:
88  *mode = kOtcryptoHashModeSha3_512;
89  break;
90  default:
91  LOG_INFO("Invalid size for SHA3: %d bits", security_strength);
92  return INVALID_ARGUMENT();
93  }
94  return OK_STATUS();
95 }
96 
97 /**
98  * Get the mode for KMAC based on the security strength.
99  *
100  * @param security_str Security strength (in bits).
101  * @param[out] mode KMAC mode enum value.
102  */
103 status_t get_kmac_mode(size_t security_strength, otcrypto_kmac_mode_t *mode) {
104  switch (security_strength) {
105  case 128:
106  *mode = kOtcryptoKmacModeKmac128;
107  break;
108  case 256:
109  *mode = kOtcryptoKmacModeKmac256;
110  break;
111  default:
112  LOG_INFO("Invalid size for KMAC: %d bits", security_strength);
113  return INVALID_ARGUMENT();
114  }
115  return OK_STATUS();
116 }
117 
118 /**
119  * Run the test pointed to by `current_test_vector`.
120  */
121 static status_t run_test_vector(void) {
122  size_t digest_num_words = current_test_vector->digest.len / sizeof(uint32_t);
123  if (current_test_vector->digest.len % sizeof(uint32_t) != 0) {
124  digest_num_words++;
125  }
126  uint32_t digest[digest_num_words];
127  otcrypto_hash_digest_t digest_buf = {
128  .data = digest,
129  .len = digest_num_words,
130  };
131 
132  switch (current_test_vector->test_operation) {
133  case kKmacTestOperationShake: {
134  TRY(get_shake_mode(current_test_vector->security_strength,
135  &digest_buf.mode));
136  TRY(otcrypto_xof_shake(current_test_vector->input_msg, digest_buf));
137  break;
138  }
139  case kKmacTestOperationCshake: {
140  TRY(get_cshake_mode(current_test_vector->security_strength,
141  &digest_buf.mode));
142  TRY(otcrypto_xof_cshake(current_test_vector->input_msg,
143  current_test_vector->func_name,
144  current_test_vector->cust_str, digest_buf));
145  break;
146  }
147  case kKmacTestOperationSha3: {
148  TRY(get_sha3_mode(current_test_vector->security_strength,
149  &digest_buf.mode));
150  TRY(otcrypto_hash(current_test_vector->input_msg, digest_buf));
151  break;
152  }
153  case kKmacTestOperationKmac: {
154  current_test_vector->key.checksum =
155  integrity_blinded_checksum(&current_test_vector->key);
157  TRY(get_kmac_mode(current_test_vector->security_strength, &mode));
158  otcrypto_word32_buf_t tag_buf = {
159  .data = digest_buf.data,
160  .len = digest_buf.len,
161  };
162  TRY(otcrypto_kmac(&current_test_vector->key,
163  current_test_vector->input_msg, mode,
164  current_test_vector->cust_str,
165  current_test_vector->digest.len, tag_buf));
166  break;
167  }
168  default: {
169  LOG_INFO("Unrecognized `operation` field: 0x%04x",
170  current_test_vector->test_operation);
171  return INVALID_ARGUMENT();
172  }
173  }
174 
175  TRY_CHECK_ARRAYS_EQ((unsigned char *)digest_buf.data,
176  current_test_vector->digest.data,
177  current_test_vector->digest.len);
178  return OTCRYPTO_OK;
179 }
180 
181 OTTF_DEFINE_TEST_CONFIG();
182 bool test_main(void) {
183  LOG_INFO("Testing cryptolib KMAC driver.");
184 
185  // Initialize the core with default parameters
186  CHECK_STATUS_OK(entropy_complex_init());
187  CHECK_STATUS_OK(kmac_hwip_default_configure());
188 
189  status_t test_result = OK_STATUS();
190  for (size_t i = 0; i < ARRAYSIZE(kKmacTestVectors); i++) {
191  current_test_vector = &kKmacTestVectors[i];
192  LOG_INFO("Running test %d of %d, test vector identifier: %s", i + 1,
193  ARRAYSIZE(kKmacTestVectors),
194  current_test_vector->vector_identifier);
195  EXECUTE_TEST(test_result, run_test_vector);
196  }
197  return status_ok(test_result);
198 }