Software APIs
kmac_mode_kmac_test.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 "dt/dt_kmac.h" // Generated
11 #include "sw/device/lib/testing/test_framework/check.h"
13 
14 OTTF_DEFINE_TEST_CONFIG();
15 
16 #define DIGEST_LEN_KMAC_MAX 100
17 
18 /**
19  * KMAC test description.
20  */
21 typedef struct kmac_test {
23  dif_kmac_key_t key;
24 
25  const char *message;
26  size_t message_len;
27 
28  const char *customization_string;
29  size_t customization_string_len;
30 
31  const uint32_t digest[DIGEST_LEN_KMAC_MAX];
32  size_t digest_len;
33  bool digest_len_is_fixed;
34 } kmac_test_t;
35 
36 /**
37  * KMAC tests.
38  *
39  * KMAC examples taken from:
40  * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMAC_samples.pdf
41  *
42  * KMACXOF examples taken from:
43  * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/KMACXOF_samples.pdf
44  */
45 const kmac_test_t kmac_tests[] = {
46  // KMAC
47  {
48  .mode = kDifKmacModeKmacLen128,
49  .key =
51  .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C,
52  0x53525150, 0x57565554, 0x5B5A5958, 0x5F5E5D5C},
53  .share1 = {0},
54  .length = kDifKmacKeyLen256,
55  },
56  .message = "\x00\x01\x02\x03",
57  .message_len = 4,
58  .customization_string = "",
59  .customization_string_len = 0,
60  .digest = {0x0D0B78E5, 0xD3F7A63E, 0x70C529A4, 0x003AA46A, 0xD4D7DBFA,
61  0x9E832896, 0x3F248731, 0x4EE16E45},
62  .digest_len = 8,
63  .digest_len_is_fixed = true,
64  },
65  {
66  .mode = kDifKmacModeKmacLen256,
67  .key =
69  .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C,
70  0x53525150, 0x57565554, 0x5B5A5958, 0x5F5E5D5C},
71  .share1 = {0},
72  .length = kDifKmacKeyLen256,
73  },
74  .message =
75  "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
76  "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
77  "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
78  "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
79  "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
80  "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
81  "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
82  "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
83  "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
84  "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
85  "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
86  "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
87  "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
88  .message_len = 200,
89  .customization_string = "My Tagged Application",
90  .customization_string_len = 21,
91  .digest = {0xF71886B5, 0xD5E1921F, 0x558C1B6C, 0x18CDD7DD, 0xCAB4978B,
92  0x1E83994D, 0x839A69B2, 0xD9E4A27D, 0xFDACFB70, 0xAE3300E5,
93  0xA2F185A5, 0xC3108570, 0x0888072D, 0x2818BD01, 0x6847FE98,
94  0x6589FC76},
95  .digest_len = 16,
96  .digest_len_is_fixed = true,
97  },
98  {
99  .mode = kDifKmacModeKmacLen128,
100  .key =
101  (dif_kmac_key_t){
102  .share0 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
103  15},
104  .share1 = {0},
105  .length = kDifKmacKeyLen512,
106  },
107  .message = "OpenTitan",
108  .message_len = 9,
109  .customization_string =
110  "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
111  "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
112  .customization_string_len = 32,
113  .digest = {0x0A77209A, 0x81797CFC, 0x6C6A61AA, 0x87E02697, 0xFC583498,
114  0x924C7FD8, 0xD7E11A80, 0xCEBFD97E, 0x5D01E715, 0xE197129F,
115  0xCED75441, 0x3A08D021, 0xBBACB3CA, 0x353539F9, 0xCD225ACE,
116  0x07C377A5, 0xDEB816E7, 0x6102E338, 0xBA1BA63C, 0x9FD50F0E,
117  0x2B2F632E, 0xABC632E1, 0xF44E5360, 0x01618ABD, 0xCEA93A18,
118  0xA25E1479, 0xACE0387A, 0x8CC8E65A, 0xC5323FBD, 0xCE278A2F,
119  0x6E5C6CD4, 0xDEF0B252, 0xC9569830, 0xDCD1E15A, 0x01592E1D,
120  0x6D41FBEC, 0x7625B67E, 0x2E6FDC71, 0x753253F6, 0xCBE2EE7B,
121  0x94B3F8AB, 0x5F7B9F4B, 0x9C32B704, 0xB75D2CD2, 0x2B9BF8D5,
122  0xF0C43941, 0x070A972F, 0x29039D89, 0x985B43BE, 0x3739526F,
123  0xEB9DE9FE, 0xE885D4EB, 0x147B854A, 0xF39840A4, 0x927FCEEF,
124  0xAA41A128, 0xBF85C5C4, 0x492D7E2B, 0xC39FC808, 0x260A3D02,
125  0x0EAB74F2, 0xFE7B8A99, 0xF77C71F7, 0x49D69382, 0x7B8405D4,
126  0x3D55F0F9, 0x551EAD0B, 0x53D648D0, 0x1820BAEB, 0x8D94C965,
127  0x079BC208, 0xD4D2742F, 0x8496D429, 0x464B6D3A, 0x34899027,
128  0x940B6F55, 0x154F43FB, 0x8C39F574, 0x89E07C5F, 0xE10F713B,
129  0x8B638E35, 0x16F0BFCE, 0x21CB26F8, 0x0A25F977, 0xAD944F1B,
130  0x6B8A6DB7, 0x0ABD1C91, 0x18E2C5AF, 0xE9AF73F5, 0x79CD8C86,
131  0x6830AD6F, 0x9EA2CC45, 0xA70D1807, 0x38993A63, 0xC2BF657E,
132  0x7CE11825, 0x98774D38, 0x9DB867E7, 0xB5F8CBFB, 0x86B242D5},
133  .digest_len = 100,
134  .digest_len_is_fixed = true,
135  },
136  // KMACXOF
137  {
138  .mode = kDifKmacModeKmacLen128,
139  .key =
140  (dif_kmac_key_t){
141  .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C,
142  0x53525150, 0x57565554, 0x5B5A5958, 0x5F5E5D5C},
143  .share1 = {0},
144  .length = kDifKmacKeyLen256,
145  },
146  .message = "\x00\x01\x02\x03",
147  .message_len = 4,
148  .customization_string = "",
149  .customization_string_len = 0,
150  .digest = {0x0B7483CD, 0xC8CC92BD, 0x142B03CF, 0x46F4A081, 0xDDA97C0E,
151  0x0C8AB012, 0x8B173140, 0x35ECD6AC},
152  .digest_len = 8,
153  .digest_len_is_fixed = false,
154  },
155  {
156  .mode = kDifKmacModeKmacLen256,
157  .key =
158  (dif_kmac_key_t){
159  .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C,
160  0x53525150, 0x57565554, 0x5B5A5958, 0x5F5E5D5C},
161  .share1 = {0},
162  .length = kDifKmacKeyLen256,
163  },
164  .message =
165  "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
166  "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
167  "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
168  "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
169  "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
170  "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
171  "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
172  "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
173  "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
174  "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
175  "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
176  "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
177  "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7",
178  .message_len = 200,
179  .customization_string = "My Tagged Application",
180  .customization_string_len = 21,
181  .digest = {0x1C73BED5, 0x73D74E95, 0x59BB4628, 0xE3A8E3DB, 0x7AE7830F,
182  0x5944FF4B, 0xB4C2F1F2, 0xCEB8EBEC, 0xC601BA67, 0x57B88A2E,
183  0x9B492D8D, 0x6727BBD1, 0x90117868, 0x6A300A02, 0x1D28DE97,
184  0x5D3030CC},
185  .digest_len = 16,
186  .digest_len_is_fixed = false,
187  },
188 };
189 
190 bool test_main(void) {
191  LOG_INFO("Running KMAC DIF test...");
192 
193  // Intialize KMAC hardware.
194  dif_kmac_t kmac;
195  dt_kmac_t kKmacDt = (dt_kmac_t)0;
196  static_assert(kDtKmacCount >= 1,
197  "This test requires at least one KMAC instance");
198  dif_kmac_operation_state_t kmac_operation_state;
199  CHECK_DIF_OK(dif_kmac_init_from_dt(kKmacDt, &kmac));
200 
201  // Configure KMAC hardware using software entropy.
203  .entropy_mode = kDifKmacEntropyModeSoftware,
204  .entropy_seed = {0xb153e3fe, 0x09596819, 0x3e85a6e8, 0xb6dcdaba,
205  0x50dc409c, 0x11e1ebd1},
206  .entropy_fast_process = kDifToggleEnabled,
207  };
208  CHECK_DIF_OK(dif_kmac_configure(&kmac, config));
209 
210  // Run fixed length KMAC test cases using single blocking absorb/squeeze
211  // operations.
212  for (int i = 0; i < ARRAYSIZE(kmac_tests); ++i) {
213  kmac_test_t test = kmac_tests[i];
214 
217  test.customization_string, test.customization_string_len, &s));
218 
219  // Use NULL for empty strings to exercise that code path.
221  test.customization_string_len == 0 ? NULL : &s;
222 
223  size_t l = test.digest_len_is_fixed ? test.digest_len : 0;
224  CHECK_DIF_OK(dif_kmac_mode_kmac_start(&kmac, &kmac_operation_state,
225  test.mode, l, &test.key, sp));
226  CHECK_DIF_OK(dif_kmac_absorb(&kmac, &kmac_operation_state, test.message,
227  test.message_len, NULL));
228  uint32_t out[DIGEST_LEN_KMAC_MAX];
229  CHECK(DIGEST_LEN_KMAC_MAX >= test.digest_len);
230  CHECK_DIF_OK(dif_kmac_squeeze(&kmac, &kmac_operation_state, out,
231  test.digest_len, /*processed=*/NULL,
232  /*capacity=*/NULL));
233  CHECK_DIF_OK(dif_kmac_end(&kmac, &kmac_operation_state));
234 
235  for (int j = 0; j < test.digest_len; ++j) {
236  CHECK(out[j] == test.digest[j],
237  "test %d: mismatch at %d got=0x%x want=0x%x", i, j, out[j],
238  test.digest[j]);
239  }
240  }
241 
242  return true;
243 }