Software APIs
hmac_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/impl/integrity.h"
10 #include "sw/device/lib/testing/test_framework/check.h"
12 
13 // The autogen rule that creates this header creates it in a directory named
14 // after the rule, then manipulates the include path in the
15 // cc_compilation_context to include that directory, so the compiler will find
16 // the version of this file matching the Bazel rule under test.
17 #include "hmac_testvectors.h"
18 
19 // Module ID for status codes.
20 #define MODULE_ID MAKE_MODULE_ID('h', 'm', 'a')
21 
22 // Global pointer to the current test vector.
23 static hmac_test_vector_t *current_test_vector = NULL;
24 
25 /**
26  * Determines `hash_mode` for given SHA-2 test vectors.
27  *
28  * Note that for HMAC operations, mode information is part of the key struct,
29  * hence this function is only used for hash vectors.
30  *
31  * @param test_vec The pointer to the test vector.
32  * @param[out] hash_mode The determined hash_mode of the given test vector.
33  */
34 static status_t get_hash_mode(hmac_test_vector_t *test_vec,
35  otcrypto_hash_mode_t *hash_mode) {
36  switch (test_vec->test_operation) {
37  case kHmacTestOperationSha256:
38  *hash_mode = kOtcryptoHashModeSha256;
39  return OTCRYPTO_OK;
40  case kHmacTestOperationSha384:
41  *hash_mode = kOtcryptoHashModeSha384;
42  return OTCRYPTO_OK;
43  case kHmacTestOperationSha512:
44  *hash_mode = kOtcryptoHashModeSha512;
45  return OTCRYPTO_OK;
46  default:
47  return OTCRYPTO_BAD_ARGS;
48  }
49 }
50 
51 /**
52  * Run the test pointed to by `current_test_vector`.
53  */
54 static status_t run_test_vector(void) {
55  // Populate `checksum` and `config.security_level` fields.
56  current_test_vector->key.checksum =
57  integrity_blinded_checksum(&current_test_vector->key);
58 
59  // The test vectors already have the correct digest sizes hardcoded.
60  size_t digest_len = current_test_vector->digest.len;
61  // Allocate the buffer for the maximum digest size (which comes from SHA-512).
62  uint32_t act_tag[kSha512DigestWords];
63  otcrypto_word32_buf_t tag_buf = {
64  .data = act_tag,
65  .len = digest_len,
66  };
67  otcrypto_hash_digest_t hash_digest = {
68  // .mode is to be determined below in switch-case block.
69  .data = act_tag,
70  .len = digest_len,
71  };
72  switch (current_test_vector->test_operation) {
73  case kHmacTestOperationSha256:
75  case kHmacTestOperationSha384:
77  case kHmacTestOperationSha512:
78  TRY(get_hash_mode(current_test_vector, &hash_digest.mode));
79  TRY(otcrypto_hash(current_test_vector->message, hash_digest));
80  break;
81  case kHmacTestOperationHmacSha256:
83  case kHmacTestOperationHmacSha384:
85  case kHmacTestOperationHmacSha512:
86  TRY(otcrypto_hmac(&current_test_vector->key, current_test_vector->message,
87  tag_buf));
88  break;
89  default:
90  return OTCRYPTO_BAD_ARGS;
91  }
92  TRY_CHECK_ARRAYS_EQ(act_tag, current_test_vector->digest.data, digest_len);
93  return OTCRYPTO_OK;
94 }
95 
96 OTTF_DEFINE_TEST_CONFIG();
97 bool test_main(void) {
98  LOG_INFO("Testing cryptolib HMAC/SHA-2 streaming implementations.");
99  status_t test_result = OK_STATUS();
100  for (size_t i = 0; i < ARRAYSIZE(kHmacTestVectors); i++) {
101  current_test_vector = &kHmacTestVectors[i];
102  LOG_INFO("Running test %d of %d, test vector identifier: %s", i + 1,
103  ARRAYSIZE(kHmacTestVectors),
104  current_test_vector->vector_identifier);
105  EXECUTE_TEST(test_result, run_test_vector);
106  }
107  return status_ok(test_result);
108 }