Software APIs
aes_kwp_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 
6 #include "sw/device/lib/crypto/drivers/entropy.h"
9 #include "sw/device/lib/testing/test_framework/check.h"
11 
12 // Module ID for status codes.
13 #define MODULE_ID MAKE_MODULE_ID('t', 's', 't')
14 
15 // Key configuration for wrapping key (AES-256).
16 static const otcrypto_key_config_t kWrappingKeyConfig = {
17  .version = kOtcryptoLibVersion1,
18  .key_mode = kOtcryptoKeyModeAesKwp,
19  .key_length = 256 / 8,
20  .hw_backed = kHardenedBoolFalse,
21  .security_level = kOtcryptoKeySecurityLevelLow,
22 };
23 
24 /**
25  * Check that wrapping and unwrapping returns the original key.
26  *
27  * @param key_to_wrap Blinded key to wrap/unwrap.
28  * @param kek_kek AES-KWP key to wrap with.
29  */
30 static status_t run_wrap_unwrap(const otcrypto_blinded_key_t *key_to_wrap,
31  const otcrypto_blinded_key_t *key_kek) {
32  size_t wrapped_num_words;
33  TRY(otcrypto_wrapped_key_len(key_to_wrap->config, &wrapped_num_words));
34 
35  // Wrap the key.
36  uint32_t wrapped_key_data[wrapped_num_words];
37  otcrypto_word32_buf_t wrapped_key = {
38  .data = wrapped_key_data,
39  .len = ARRAYSIZE(wrapped_key_data),
40  };
41  TRY(otcrypto_key_wrap(key_to_wrap, key_kek, wrapped_key));
42 
43  // Unwrap the key.
44  hardened_bool_t success;
45  TRY_CHECK(key_to_wrap->keyblob_length % sizeof(uint32_t) == 0);
46  size_t keyblob_words = key_to_wrap->keyblob_length / sizeof(uint32_t);
47  uint32_t unwrapped_key_keyblob[keyblob_words];
48  otcrypto_blinded_key_t unwrapped_key = {
49  .keyblob_length = keyblob_words * sizeof(uint32_t),
50  .keyblob = unwrapped_key_keyblob,
51  };
54  .data = wrapped_key_data,
55  .len = ARRAYSIZE(wrapped_key_data),
56  },
57  key_kek, &success, &unwrapped_key));
58 
59  // Check the result.
60  TRY_CHECK(success == kHardenedBoolTrue);
61  TRY_CHECK_ARRAYS_EQ(unwrapped_key.keyblob, key_to_wrap->keyblob,
62  keyblob_words);
63  TRY_CHECK(memcmp(&unwrapped_key.config, &key_to_wrap->config,
64  sizeof(otcrypto_key_config_t)) == 0);
65  TRY_CHECK(unwrapped_key.keyblob_length == key_to_wrap->keyblob_length);
66  TRY_CHECK(unwrapped_key.checksum == key_to_wrap->checksum);
67 
68  return OK_STATUS();
69 }
70 
71 /**
72  * Test wrapping/unwrapping a random key.
73  */
74 static status_t wrap_unwrap_random_test(void) {
75  const otcrypto_key_config_t kKmacKeyConfig = {
76  .version = kOtcryptoLibVersion1,
77  .key_mode = kOtcryptoKeyModeKmac128,
78  .key_length = 128 / 8,
79  .hw_backed = kHardenedBoolFalse,
80  .security_level = kOtcryptoKeySecurityLevelLow,
81  };
82 
83  // Generate a random KMAC key.
84  uint32_t keyblob[(kKmacKeyConfig.key_length * 2) / sizeof(uint32_t)];
85  otcrypto_blinded_key_t kmac_key = {
86  .config = kKmacKeyConfig,
87  .keyblob_length = sizeof(keyblob),
88  .keyblob = keyblob,
89  };
90  otcrypto_const_byte_buf_t personalization = {.data = NULL, .len = 0};
91  TRY(otcrypto_symmetric_keygen(personalization, &kmac_key));
92 
93  // Generate a random AES-KWP key.
94  uint32_t kek_keyblob[(kWrappingKeyConfig.key_length * 2) / sizeof(uint32_t)];
96  .config = kWrappingKeyConfig,
97  .keyblob_length = sizeof(kek_keyblob),
98  .keyblob = kek_keyblob,
99  };
100  TRY(otcrypto_symmetric_keygen(personalization, &kek));
101 
102  return run_wrap_unwrap(&kmac_key, &kek);
103 }
104 
105 OTTF_DEFINE_TEST_CONFIG();
106 
107 bool test_main(void) {
108  status_t result = OK_STATUS();
109 
110  CHECK_STATUS_OK(entropy_complex_init());
111  EXECUTE_TEST(result, wrap_unwrap_random_test);
112 
113  return status_ok(result);
114 }