Software APIs
kdf_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"
13 #include "sw/device/lib/testing/test_framework/check.h"
15 
16 // The autogen rule that creates this header creates it in a directory named
17 // after the rule, then manipulates the include path in the
18 // cc_compilation_context to include that directory, so the compiler will find
19 // the version of this file matching the Bazel rule under test.
20 #include "kdf_testvectors.h"
21 
22 // Global pointer to the current test vector.
23 static kdf_kmac_test_vector_t *current_test_vector = NULL;
24 
25 /**
26  * Run the test pointed to by `current_test_vector`.
27  */
28 static status_t run_test_vector(void) {
29  // Below, `km` prefix refers to output_key_material, and
30  // `kdk` prefix refers to key derivation key
31  size_t km_num_words = current_test_vector->expected_output.len;
32  uint32_t km_buffer[2 * km_num_words];
33 
34  otcrypto_blinded_key_t output_key_material = {
35  .config =
36  {
37  // The following key_mode is a dummy placeholder. It does not
38  // necessarily match the `key_length`.
39  .key_mode = kOtcryptoKeyModeKdfKmac128,
40  .key_length = km_num_words * sizeof(uint32_t),
41  .hw_backed = kHardenedBoolFalse,
42  .security_level = kOtcryptoKeySecurityLevelLow,
43  .exportable = kHardenedBoolTrue,
44  },
45  .keyblob = km_buffer,
46  .keyblob_length = sizeof(km_buffer),
47  };
48 
49  // Populate `checksum` and `config.security_level` fields.
50  current_test_vector->key_derivation_key.checksum =
51  integrity_blinded_checksum(&current_test_vector->key_derivation_key);
52 
53  TRY(otcrypto_kmac_kdf(current_test_vector->key_derivation_key,
54  current_test_vector->label,
55  current_test_vector->context, &output_key_material));
56 
57  HARDENED_CHECK_EQ(integrity_blinded_key_check(&output_key_material),
59 
60  // Export the derived blinded key.
61  uint32_t km_share0[km_num_words];
62  uint32_t km_share1[km_num_words];
64  output_key_material,
65  (otcrypto_word32_buf_t){.data = km_share0, .len = ARRAYSIZE(km_share0)},
66  (otcrypto_word32_buf_t){.data = km_share1, .len = ARRAYSIZE(km_share1)}));
67 
68  // Unmask the derived key and compare to the expected value.
69  uint32_t actual_output[km_num_words];
70  for (size_t i = 0; i < ARRAYSIZE(actual_output); i++) {
71  actual_output[i] = km_share0[i] ^ km_share1[i];
72  }
73  TRY_CHECK_ARRAYS_EQ(actual_output, current_test_vector->expected_output.data,
74  km_num_words);
75  return OTCRYPTO_OK;
76 }
77 
78 OTTF_DEFINE_TEST_CONFIG();
79 bool test_main(void) {
80  LOG_INFO("Testing cryptolib KMAC-KDF driver.");
81 
82  // Initialize the core with default parameters
83  CHECK_STATUS_OK(entropy_complex_init());
84  CHECK_STATUS_OK(kmac_hwip_default_configure());
85 
86  status_t test_result = OK_STATUS();
87  for (size_t i = 0; i < ARRAYSIZE(kKdfTestVectors); i++) {
88  current_test_vector = &kKdfTestVectors[i];
89  LOG_INFO("Running test %d of %d, test vector identifier: %s", i + 1,
90  ARRAYSIZE(kKdfTestVectors),
91  current_test_vector->vector_identifier);
92  EXECUTE_TEST(test_result, run_test_vector);
93  }
94  return status_ok(test_result);
95 }