Software APIs
hmac_sha384_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/impl/integrity.h"
7 #include "sw/device/lib/crypto/impl/keyblob.h"
11 #include "sw/device/lib/testing/test_framework/check.h"
13 
14 enum {
15  /**
16  * HMAC-SHA384 tag length (384 bits) in words.
17  */
18  kTagLenWords = 384 / 32,
19 };
20 
21 // Randomly generated 384-bit test key (big endian) =
22 // 0x7751ae57bc0ba74f9d5cba1a458d9543342c70fe102f5e2fb339c2500f5610f132276a7cb87d39cde522efea6ba18dd1
23 static const uint32_t kBasicTestKey[] = {
24  0x57ae5177, 0x4fa70bbc, 0x1aba5c9d, 0x43958d45, 0xfe702c34, 0x2f5e2f10,
25  0x50c239b3, 0xf110560f, 0x7c6a2732, 0xcd397db8, 0xeaef22e5, 0xd18da16b};
26 
27 // Test key longer than the message block size, 1088 bits (big endian) =
28 // 0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243
29 static const uint32_t kLongTestKey[] = {
30  0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0x13121110, 0x17161514,
31  0x1b1a1918, 0x1f1e1d1c, 0x23222120, 0x27262524, 0x2b2a2928, 0x2f2e2d2c,
32  0x33323130, 0x37363534, 0x3b3a3938, 0x3f3e3d3c, 0x43424140, 0x03020100,
33  0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0x13121110, 0x17161514, 0x1b1a1918,
34  0x1f1e1d1c, 0x23222120, 0x27262524, 0x2b2a2928, 0x2f2e2d2c, 0x33323130,
35  0x37363534, 0x3b3a3938, 0x3f3e3d3c, 0x43424140,
36 };
37 
38 // Random value for masking, as large as the longest test key. This value
39 // should not affect the result.
40 static const uint32_t kTestMask[ARRAYSIZE(kLongTestKey)] = {
41  0x8cb847c3, 0xc6d34f36, 0x72edbf7b, 0x9bc0317f, 0x8f003c7f, 0x1d7ba049,
42  0xfd463b63, 0xbb720c44, 0x784c215e, 0xeb101d65, 0x35beb911, 0xab481345,
43  0xa7ebc3e3, 0x04b2a1b9, 0x764a9630, 0x78b8f9c5, 0x3f2a1d8e, 0x8cb847c3,
44  0xc6d34f36, 0x72edbf7b, 0x9bc0317f, 0x8f003c7f, 0x1d7ba049, 0xfd463b63,
45  0xbb720c44, 0x784c215e, 0xeb101d65, 0x35beb911, 0xab481345, 0xa7ebc3e3,
46  0x04b2a1b9, 0x764a9630, 0x78b8f9c5, 0x3f2a1d8e,
47 };
48 
49 /**
50  * Call the `otcrypto_mac` API and check the resulting tag.
51  *
52  * @param key Key material.
53  * @param key_num_words Key length in bytes.
54  * @param msg Input message.
55  * @param exp_tag Expected tag.
56  * @return Result (OK or error).
57  */
58 static status_t run_test(const uint32_t *key, size_t key_len,
60  const uint32_t *exp_tag) {
61  // Construct blinded key.
62  otcrypto_key_config_t config = {
63  .version = kOtcryptoLibVersion1,
64  .key_mode = kOtcryptoKeyModeHmacSha384,
65  .key_length = key_len,
66  .hw_backed = kHardenedBoolFalse,
67  .exportable = kHardenedBoolFalse,
68  .security_level = kOtcryptoKeySecurityLevelLow,
69  };
70 
71  uint32_t keyblob[keyblob_num_words(config)];
72  TRY(keyblob_from_key_and_mask(key, kTestMask, config, keyblob));
73  otcrypto_blinded_key_t blinded_key = {
74  .config = config,
75  .keyblob = keyblob,
76  .keyblob_length = sizeof(keyblob),
77  .checksum = 0,
78  };
79  blinded_key.checksum = integrity_blinded_checksum(&blinded_key);
80 
81  uint32_t act_tag[kTagLenWords];
82  otcrypto_word32_buf_t tag_buf = {
83  .data = act_tag,
84  .len = ARRAYSIZE(act_tag),
85  };
86 
87  TRY(otcrypto_hmac(&blinded_key, msg, tag_buf));
88  TRY_CHECK_ARRAYS_EQ(act_tag, exp_tag, kTagLenWords);
89  return OK_STATUS();
90 }
91 
92 /**
93  * Simple test with a short message.
94  *
95  * HMAC-SHA384(kBasicTestKey, 'Test message.')
96  * =
97  * 0x2fba69e09ba15197aff88d3768aaee009cb6895763c31dcdf1d0146d4e4462d01a3c68ed42e6cee1e67b4ba48bdd1805
98  */
99 static status_t simple_test(void) {
100  const char plaintext[] = "Test message.";
101  otcrypto_const_byte_buf_t msg_buf = {
102  .data = (unsigned char *)plaintext,
103  .len = sizeof(plaintext) - 1,
104  };
105  const uint32_t exp_tag[] = {
106  0xe069ba2f, 0x9751a19b, 0x378df8af, 0x00eeaa68, 0x5789b69c, 0xcd1dc363,
107  0x6d14d0f1, 0xd062444e, 0xed683c1a, 0xe1cee642, 0xa44b7be6, 0x0518dd8b,
108  };
109  return run_test(kBasicTestKey, sizeof(kBasicTestKey), msg_buf, exp_tag);
110 }
111 
112 /**
113  * Test with an empty message.
114  *
115  * HMAC-SHA384(kBasicTestKey, '')
116  * =
117  * 0xb69271e94f5f5da40337cdb2f2d3412b6d568b7b51a86f7109f8454f3c34276cf44a5b98997ce3ab8f59170b6e1f71f9
118  */
119 static status_t empty_test(void) {
120  const uint32_t exp_tag[] = {
121  0xe97192b6, 0xa45d5f4f, 0xb2cd3703, 0x2b41d3f2, 0x7b8b566d, 0x716fa851,
122  0x4f45f809, 0x6c27343c, 0x985b4af4, 0xabe37c99, 0x0b17598f, 0xf9711f6e,
123  };
124  otcrypto_const_byte_buf_t msg_buf = {
125  .data = NULL,
126  .len = 0,
127  };
128  return run_test(kBasicTestKey, sizeof(kBasicTestKey), msg_buf, exp_tag);
129 }
130 
131 /**
132  * Test using a long key.
133  *
134  * HMAC-SHA384(kLongTestKey, 'Test message.')
135  * =
136  * 0xaacc6a2d9aadee928c78467c02a881b00afc8a6b004d09cf05b8a492651a5f5cf8d4bc988598b2bd3154f07239b48dc0
137  */
138 static status_t long_key_test(void) {
139  const char plaintext[] = "Test message.";
140  otcrypto_const_byte_buf_t msg_buf = {
141  .data = (unsigned char *)plaintext,
142  .len = sizeof(plaintext) - 1,
143  };
144  const uint32_t exp_tag[] = {
145  0x2d6accaa, 0x92eead9a, 0x7c46788c, 0xb081a802, 0x6b8afc0a, 0xcf094d00,
146  0x92a4b805, 0x5c5f1a65, 0x98bcd4f8, 0xbdb29885, 0x72f05431, 0xc08db439,
147  };
148  return run_test(kLongTestKey, sizeof(kLongTestKey), msg_buf, exp_tag);
149 }
150 
151 OTTF_DEFINE_TEST_CONFIG();
152 
153 // Holds the test result.
154 static volatile status_t test_result;
155 
156 bool test_main(void) {
157  test_result = OK_STATUS();
158  CHECK_STATUS_OK(entropy_complex_init());
159  EXECUTE_TEST(test_result, empty_test);
160  EXECUTE_TEST(test_result, simple_test);
161  EXECUTE_TEST(test_result, long_key_test);
162  return status_ok(test_result);
163 }