Software APIs
dif_kmac_unittest.cc
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 
7 #include <array>
8 #include <cstring>
9 #include <limits>
10 #include <ostream>
11 #include <string>
12 
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
16 #include "sw/device/lib/base/mock_mmio.h"
18 
19 #include "kmac_regs.h" // Generated
20 
21 // We define global namespace == and << to make `dif_i2c_timing_params_t` work
22 // nicely with EXPECT_EQ.
24  return a.squeezing == b.squeezing && a.append_d == b.append_d &&
25  a.offset == b.offset && a.r == b.r && a.d == b.d;
26 }
27 
28 std::ostream &operator<<(std::ostream &os,
29  const dif_kmac_operation_state_t &params) {
30  return os << "{\n"
31  << " .squeezing = " << params.squeezing << ",\n"
32  << " .append_d = " << params.append_d << ",\n"
33  << " .offset = " << params.offset << ",\n"
34  << " .r = " << params.r << ",\n"
35  << " .d = " << params.d << ",\n"
36  << "}";
37 }
38 
39 namespace dif_kmac_unittest {
40 
41 using ::testing::ElementsAre;
42 using testing::ElementsAreArray;
43 
44 TEST(CustomizationStringTest, Encode) {
46 
48  EXPECT_THAT(std::string(&cs.buffer[0], 2), ElementsAre(1, 0));
49 
51  EXPECT_THAT(std::string(&cs.buffer[0], 2), ElementsAre(1, 0));
52 
54  EXPECT_THAT(std::string(&cs.buffer[0], 2), ElementsAre(1, 16));
55  EXPECT_THAT(std::string(&cs.buffer[2], 2), ElementsAre(0, 0));
56 
58  EXPECT_THAT(std::string(&cs.buffer[0], 2), ElementsAre(1, 40));
59  EXPECT_EQ(std::string(&cs.buffer[2], 5), "SHA-3");
60 
61  std::string max(kDifKmacMaxCustomizationStringLen, 0x12);
63  dif_kmac_customization_string_init(max.data(), max.size(), &cs));
64  static_assert(kDifKmacMaxCustomizationStringLen == 32,
65  "encoding needs to be updated");
66  EXPECT_THAT(std::string(&cs.buffer[0], 3), ElementsAre(2, 1, 0));
67  EXPECT_EQ(std::string(&cs.buffer[3], max.size()), max);
68 }
69 
70 TEST(CustomizationStringTest, BadArg) {
72 
76  "", kDifKmacMaxCustomizationStringLen + 1, &cs));
78 }
79 
80 TEST(FunctionNameTest, Encode) {
82 
84  EXPECT_THAT(std::string(&fn.buffer[0], 2), ElementsAre(1, 0));
85 
87  EXPECT_THAT(std::string(&fn.buffer[0], 2), ElementsAre(1, 0));
88 
89  EXPECT_DIF_OK(dif_kmac_function_name_init("\x00\x00", 2, &fn));
90  EXPECT_THAT(std::string(&fn.buffer[0], 2), ElementsAre(1, 16));
91  EXPECT_THAT(std::string(&fn.buffer[2], 2), ElementsAre(0, 0));
92 
94  EXPECT_THAT(std::string(&fn.buffer[0], 2), ElementsAre(1, 32));
95  EXPECT_EQ(std::string(&fn.buffer[2], 4), "KMAC");
96 
97  std::string max(kDifKmacMaxFunctionNameLen, 0x34);
98  EXPECT_DIF_OK(dif_kmac_function_name_init(max.data(), max.size(), &fn));
99  static_assert(kDifKmacMaxFunctionNameLen == 4,
100  "encoding needs to be updated");
101  EXPECT_THAT(std::string(&fn.buffer[0], 2), ElementsAre(1, 32));
102  EXPECT_EQ(std::string(&fn.buffer[2], max.size()), max);
103 }
104 
105 TEST(FunctionNameTest, BadArg) {
107 
113 }
114 
115 using mock_mmio::MmioTest;
117 using testing::Test;
118 
119 // Base class for the rest fixtures in this file.
120 class KmacTest : public testing::Test, public mock_mmio::MmioTest {
121  protected:
122  dif_kmac_t kmac_;
123  dif_kmac_operation_state_t op_state_ = {
124  .squeezing = false,
125  .append_d = false,
126  .offset = 0,
127  .r = 0,
128  .d = 0,
129  };
130 
131  static constexpr std::array<uint8_t, 17> kMsg = {
132  0xa7, 0x48, 0x47, 0x93, 0x0a, 0x03, 0xab, 0xee, 0xa4,
133  0x73, 0xe1, 0xf3, 0xdc, 0x30, 0xb8, 0x88, 0x15};
134 
135  struct ConfigRegister {
136  bool enable = false;
137  uint8_t key_strength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
138  uint8_t mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE;
139  bool msg_big_endian = false;
140  bool state_big_endian = false;
141  bool sideload = false;
142  uint8_t entropy_mode = KMAC_CFG_SHADOWED_ENTROPY_MODE_VALUE_IDLE_MODE;
143  bool entropy_fast_process = false;
144  bool msg_mask = false;
145  bool entropy_ready = false;
146  bool enable_unsupported_mode_strength = false;
147  uint16_t entropy_hash_threshold = 0;
148  uint16_t entropy_wait_timer = 0;
149  uint16_t entropy_prescaler = 0;
150  } config_reg_;
151 
152  KmacTest() { EXPECT_DIF_OK(dif_kmac_init(dev().region(), &kmac_)); }
153 
154  /**
155  * Set mmio write expectation for 8 bits data size.
156  *
157  * @param message Buffer with the data.
158  * @param size Len of the buffer.
159  */
160  void ExpectMessageByte(const uint8_t *message, const size_t size) {
161  for (size_t i = 0; i < size; ++i) {
162  EXPECT_WRITE8(KMAC_MSG_FIFO_REG_OFFSET, message[i]);
163  }
164  }
165 
166  /**
167  * Set mmio write expectation for 32 bits data size considering an alignment
168  * of 32 bits.
169  *
170  * @param message Buffer with the data.
171  * @param size Len of the buffer.
172  */
173  void ExpectMessageInt32(const uint8_t *message, const size_t size) {
174  // Check if the buffer is unaligned.
175  size_t remaining = size;
176  size_t unalignment = ((uintptr_t)message) % sizeof(uint32_t);
177  if (unalignment) {
178  // write unaligned data in bytes.
179  unalignment = sizeof(uint32_t) - unalignment;
180  ExpectMessageByte(message, unalignment);
181  message += unalignment;
182  remaining -= unalignment;
183  }
184 
185  // Write aligned part of the buffer.
186  while (remaining >= sizeof(uint32_t)) {
187  uint32_t word = 0;
188  memcpy(&word, message, sizeof(uint32_t));
189  EXPECT_WRITE32(KMAC_MSG_FIFO_REG_OFFSET, word);
190  remaining -= sizeof(uint32_t);
191  message += sizeof(uint32_t);
192  }
193  // Check if there still unaligned data in the buffer tail.
194  if (remaining) {
195  // write unaligned data in bytes.
196  ExpectMessageByte(message, remaining);
197  }
198  }
199 
200  void ExpectConfig(void) {
201  EXPECT_WRITE32_SHADOWED(
202  KMAC_CFG_SHADOWED_REG_OFFSET,
203  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, config_reg_.enable},
204  {KMAC_CFG_SHADOWED_KSTRENGTH_OFFSET, config_reg_.key_strength},
205  {KMAC_CFG_SHADOWED_MODE_OFFSET, config_reg_.mode},
206  {KMAC_CFG_SHADOWED_MSG_ENDIANNESS_BIT, config_reg_.msg_big_endian},
207  {KMAC_CFG_SHADOWED_STATE_ENDIANNESS_BIT, config_reg_.state_big_endian},
208  {KMAC_CFG_SHADOWED_SIDELOAD_BIT, config_reg_.sideload},
209  {KMAC_CFG_SHADOWED_ENTROPY_MODE_OFFSET, config_reg_.entropy_mode},
210  {KMAC_CFG_SHADOWED_ENTROPY_FAST_PROCESS_BIT,
211  config_reg_.entropy_fast_process},
212  {KMAC_CFG_SHADOWED_MSG_MASK_BIT, config_reg_.msg_mask},
213  {KMAC_CFG_SHADOWED_ENTROPY_READY_BIT, config_reg_.entropy_ready},
214  {KMAC_CFG_SHADOWED_EN_UNSUPPORTED_MODESTRENGTH_BIT,
215  config_reg_.enable_unsupported_mode_strength}});
216  }
217 
218  void ExpectKey(const dif_kmac_key_t &key) {
219  std::map<dif_kmac_key_length_t, uint32_t> key_size_map = {
220  {kDifKmacKeyLen128, KMAC_KEY_LEN_LEN_VALUE_KEY128},
221  {kDifKmacKeyLen192, KMAC_KEY_LEN_LEN_VALUE_KEY192},
222  {kDifKmacKeyLen256, KMAC_KEY_LEN_LEN_VALUE_KEY256},
223  {kDifKmacKeyLen384, KMAC_KEY_LEN_LEN_VALUE_KEY384},
224  {kDifKmacKeyLen512, KMAC_KEY_LEN_LEN_VALUE_KEY512},
225  };
226 
227  EXPECT_WRITE32(KMAC_KEY_LEN_REG_OFFSET, key_size_map[key.length]);
228  for (uint32_t i = 0; i < ARRAYSIZE(key.share0); ++i) {
229  ptrdiff_t offset = KMAC_KEY_SHARE0_0_REG_OFFSET + (i * sizeof(uint32_t));
230  EXPECT_WRITE32(offset, key.share0[i]);
231  offset = KMAC_KEY_SHARE1_0_REG_OFFSET + (i * sizeof(uint32_t));
232  EXPECT_WRITE32(offset, key.share1[i]);
233  }
234  }
235 
236  void ExpectPrefix(const uint32_t *prefix_regs, uint32_t size) {
237  for (uint32_t i = 0; i < size; ++i) {
238  ptrdiff_t offset = KMAC_PREFIX_0_REG_OFFSET + i * sizeof(uint32_t);
239  EXPECT_WRITE32(offset, prefix_regs[i]);
240  }
241  }
242 
243  void ExpectEntropySeed(const uint32_t *seed) {
244  for (uint32_t i = 0; i < kDifKmacEntropySeedWords; ++i) {
245  EXPECT_WRITE32(KMAC_ENTROPY_SEED_REG_OFFSET, seed[i]);
246  }
247  }
248 
249  uint32_t GetRateBits(uint32_t security_level) {
250  // Formula for the rate in bits is:
251  //
252  // r = 1600 - c
253  //
254  // Where c is the capacity (the security level in bits multiplied by two).
255  return 1600 - 2 * security_level;
256  }
257 
258  uint32_t GetRateWords(uint32_t security_level) {
259  return GetRateBits(security_level) / 32;
260  }
261 };
262 
263 class Kmac256Test : public KmacTest {
264  protected:
265  dif_kmac_key_t key_ = {
266  .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C, 0x53525150,
267  0x57565554, 0x5B5A5958, 0x5F5E5D5C},
268  .share1 = {0},
269  .length = kDifKmacKeyLen256,
270  };
272  dif_kmac_customization_string_t custom_string_;
273 
274  Kmac256Test() {
275  const std::string string = "My Tagged Application";
277  string.c_str(), string.size(), &custom_string_));
278  config_reg_.enable = true;
279  config_reg_.mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE;
280  }
281 
282  void ExpectPrefix(const dif_kmac_customization_string_t &s) {
283  // Initialize prefix registers with function name ("KMAC") and empty
284  // customization string. The empty customization string will be overwritten
285  // if a non-empty string is provided.
286  std::string prefix_str("\001 KMAC\001");
287 
288  // Encoded customization string (s) must be at least 3 bytes long if it is
289  // not the empty string.
290  if (s.length >= 3) {
291  // First two bytes overwrite the pre-encoded empty customization string.
292  prefix_str[prefix_str.size() - 1] |= s.buffer[0] & 0xFF;
293  prefix_str.push_back(s.buffer[1] & 0xFF);
294  prefix_str.insert(prefix_str.end(), &s.buffer[2], &s.buffer[s.length]);
295  }
296 
297  std::vector<uint32_t> prefix_regs(11, 0);
298  memcpy(prefix_regs.data(), prefix_str.data(), prefix_str.size());
299  KmacTest::ExpectPrefix(prefix_regs.data(), prefix_regs.size());
300  }
301 };
302 
303 TEST_F(Kmac256Test, StartSuccess) {
304  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
305  ExpectKey(key_);
306  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET, 0);
307  ExpectConfig();
308  ExpectPrefix(custom_string_);
309  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
310  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
311  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
312 
313  EXPECT_DIF_OK(dif_kmac_mode_kmac_start(&kmac_, &op_state_, mode_, 0, &key_,
314  &custom_string_));
315  EXPECT_EQ(op_state_.squeezing, false);
316  EXPECT_EQ(op_state_.append_d, true);
317  EXPECT_EQ(op_state_.offset, 0);
318  EXPECT_EQ(op_state_.r, GetRateWords(256));
319  EXPECT_EQ(op_state_.d, 0);
320 }
321 
322 TEST_F(Kmac256Test, StartBadArg) {
323  EXPECT_DIF_BADARG(dif_kmac_mode_kmac_start(nullptr, &op_state_, mode_, 0,
324  &key_, &custom_string_));
325 
326  EXPECT_DIF_BADARG(dif_kmac_mode_kmac_start(&kmac_, nullptr, mode_, 0, &key_,
327  &custom_string_));
328 
329  EXPECT_DIF_BADARG(dif_kmac_mode_kmac_start(&kmac_, &op_state_, mode_,
331  &key_, &custom_string_));
332 
333  EXPECT_DIF_BADARG(dif_kmac_mode_kmac_start(&kmac_, &op_state_,
334  (dif_kmac_mode_kmac_t)0xff, 0,
335  &key_, &custom_string_));
336 
337  EXPECT_DIF_BADARG(dif_kmac_mode_kmac_start(&kmac_, &op_state_, mode_, 0,
338  nullptr, &custom_string_));
339 
340  key_.length = static_cast<dif_kmac_key_length_t>(0xFF);
341  EXPECT_DIF_BADARG(dif_kmac_mode_kmac_start(&kmac_, &op_state_, mode_, 0,
342  &key_, &custom_string_));
343 }
344 
345 TEST_F(Kmac256Test, StartError) {
346  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, false}});
347  EXPECT_EQ(dif_kmac_mode_kmac_start(&kmac_, &op_state_, mode_, 0, &key_,
348  &custom_string_),
349  kDifError);
350 }
351 
352 class Sha3_224Test : public KmacTest {
353  protected:
355 
356  Sha3_224Test() {
357  config_reg_.mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHA3;
358  config_reg_.key_strength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L224;
359  }
360 };
361 
362 TEST_F(Sha3_224Test, StartSuccess) {
363  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
364  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET,
365  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, false}});
366  ExpectConfig();
367  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
368  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
369  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
370 
371  EXPECT_DIF_OK(dif_kmac_mode_sha3_start(&kmac_, &op_state_, mode_));
372 }
373 
374 TEST_F(Sha3_224Test, StartBadArg) {
375  EXPECT_DIF_BADARG(dif_kmac_mode_sha3_start(nullptr, &op_state_, mode_));
376 
377  EXPECT_DIF_BADARG(dif_kmac_mode_sha3_start(&kmac_, nullptr, mode_));
378 
380  dif_kmac_mode_sha3_start(&kmac_, &op_state_, (dif_kmac_mode_sha3_t)0xff));
381 }
382 
383 TEST_F(Sha3_224Test, StartError) {
384  {
385  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, false}});
386  EXPECT_EQ(dif_kmac_mode_sha3_start(&kmac_, &op_state_, mode_), kDifError);
387  }
388 }
389 
390 class Shake128Test : public KmacTest {
391  protected:
393 
394  Shake128Test() {
395  config_reg_.mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE;
396  config_reg_.key_strength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L128;
397  }
398 };
399 
400 TEST_F(Shake128Test, StartSuccess) {
401  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
402  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET,
403  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, false}});
404  ExpectConfig();
405  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
406  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
407  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
408 
409  EXPECT_DIF_OK(dif_kmac_mode_shake_start(&kmac_, &op_state_, mode_));
410 }
411 
412 TEST_F(Shake128Test, StartBadArg) {
413  EXPECT_DIF_BADARG(dif_kmac_mode_shake_start(nullptr, &op_state_, mode_));
414 
415  EXPECT_DIF_BADARG(dif_kmac_mode_shake_start(&kmac_, nullptr, mode_));
416 
417  EXPECT_DIF_BADARG(dif_kmac_mode_shake_start(&kmac_, &op_state_,
418  (dif_kmac_mode_shake_t)0xff));
419 }
420 
421 TEST_F(Shake128Test, StartError) {
422  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, false}});
423  EXPECT_EQ(dif_kmac_mode_shake_start(&kmac_, &op_state_, mode_), kDifError);
424 }
425 
426 class Cshake256Test : public KmacTest {
427  protected:
430  dif_kmac_function_name_t func_name_;
431 
432  Cshake256Test() {
433  const std::string string = "My Application";
435  string.c_str(), string.size(), &custom_str_));
436 
437  const std::string kFunctionName = "Foo";
439  kFunctionName.c_str(), kFunctionName.size(), &func_name_));
440 
441  config_reg_.mode = KMAC_CFG_SHADOWED_MODE_VALUE_CSHAKE;
442  config_reg_.key_strength = KMAC_CFG_SHADOWED_KSTRENGTH_VALUE_L256;
443  }
444 
445  void ExpectPrefix(const dif_kmac_customization_string_t &s) {
446  // Calculate PREFIX register values.
447  std::vector<uint8_t> prefixData;
448  if (func_name_.length == 0) {
449  // Append left encoded empty string.
450  prefixData.push_back(1);
451  prefixData.push_back(0);
452  } else {
453  prefixData.insert(prefixData.end(), func_name_.buffer,
454  func_name_.buffer + func_name_.length);
455  }
456 
457  if (s.length == 0) {
458  // Append left encoded empty string.
459  prefixData.push_back(1);
460  prefixData.push_back(0);
461  } else {
462  prefixData.insert(prefixData.end(), s.buffer, s.buffer + s.length);
463  }
464 
465  std::vector<uint32_t> prefixRegs(11, 0);
466  memcpy(prefixRegs.data(), prefixData.data(), prefixData.size());
467  KmacTest::ExpectPrefix(prefixRegs.data(), prefixRegs.size());
468  }
469 
470  void CheckOperationState(dif_kmac_operation_state_t &operation_state) {
471  EXPECT_EQ(op_state_.squeezing, false);
472  EXPECT_EQ(op_state_.append_d, false);
473  EXPECT_EQ(op_state_.offset, 0);
474  EXPECT_EQ(op_state_.d, 0);
475  EXPECT_EQ(op_state_.r, GetRateWords(256));
476  }
477 };
478 
479 TEST_F(Cshake256Test, StartAllArgsSuccess) {
480  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
481  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET,
482  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, false}});
483  ExpectConfig();
484  ExpectPrefix(custom_str_);
485  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
486  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
487  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
488 
489  EXPECT_DIF_OK(dif_kmac_mode_cshake_start(&kmac_, &op_state_, mode_,
490  &func_name_, &custom_str_));
491  CheckOperationState(op_state_);
492 }
493 
494 TEST_F(Cshake256Test, StartNoFuncNameSuccess) {
495  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
496  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET,
497  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, false}});
498  ExpectConfig();
499  func_name_.length = 0;
500  ExpectPrefix(custom_str_);
501  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
502  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
503  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
504 
505  EXPECT_DIF_OK(dif_kmac_mode_cshake_start(&kmac_, &op_state_, mode_, nullptr,
506  &custom_str_));
507  CheckOperationState(op_state_);
508 }
509 
510 TEST_F(Cshake256Test, StartNoCustomStrSuccess) {
511  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
512  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET,
513  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, false}});
514  ExpectConfig();
515  custom_str_.length = 0;
516  ExpectPrefix(custom_str_);
517  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
518  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
519  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
520 
521  EXPECT_DIF_OK(dif_kmac_mode_cshake_start(&kmac_, &op_state_, mode_,
522  &func_name_, nullptr));
523  CheckOperationState(op_state_);
524 }
525 
526 /**
527  * In case the Function name and the Custom string are both empty the
528  * `dif_kmac_mode_cshake_start` will fallback to `dif_kmac_mode_shake_start`.
529  */
530 TEST_F(Cshake256Test, StartFallbackToShakeSuccess) {
531  config_reg_.mode = KMAC_CFG_SHADOWED_MODE_VALUE_SHAKE;
532 
533  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
534  EXPECT_READ32(KMAC_CFG_SHADOWED_REG_OFFSET,
535  {{KMAC_CFG_SHADOWED_KMAC_EN_BIT, false}});
536  ExpectConfig();
537  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
538  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_START}});
539  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true}});
541  dif_kmac_mode_cshake_start(&kmac_, &op_state_, mode_, nullptr, nullptr));
542 }
543 
544 TEST_F(Cshake256Test, StartBadArg) {
545  EXPECT_DIF_BADARG(dif_kmac_mode_cshake_start(nullptr, &op_state_, mode_,
546  &func_name_, &custom_str_));
547 
548  EXPECT_DIF_BADARG(dif_kmac_mode_cshake_start(&kmac_, nullptr, mode_,
549  &func_name_, &custom_str_));
550 
553  &func_name_, &custom_str_));
554 
556  &kmac_, &op_state_, (dif_kmac_mode_cshake_t)0xff, nullptr, nullptr));
557 }
558 
559 TEST_F(Cshake256Test, StartError) {
560  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, false}});
561  EXPECT_EQ(dif_kmac_mode_cshake_start(&kmac_, &op_state_, mode_, &func_name_,
562  &custom_str_),
563  kDifError);
564 }
565 
566 constexpr std::array<uint8_t, 17> KmacTest::kMsg;
567 
569  protected:
570  AbsorbalignmentMessage() { op_state_.r = GetRateWords(256); }
571 };
572 
573 TEST_F(AbsorbalignmentMessage, Success) {
574  // Test assumption: message fits in the FIFO.
575  static_assert(kMsg.size() <= KMAC_PARAM_NUM_ENTRIES_MSG_FIFO *
576  KMAC_PARAM_NUM_BYTES_MSG_FIFO_ENTRY,
577  "Message must fit in the KMAC message FIFO.");
578 
579  uint8_t buffer[kMsg.size() + sizeof(uint32_t)];
580 
581  for (size_t i = 0; i < sizeof(uint32_t); i++) {
582  uint8_t *pMsg = &buffer[i];
583  std::copy(kMsg.begin(), kMsg.end(), pMsg);
584 
585  // First status read: checks for absorb bit.
586  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, 1 << KMAC_STATUS_SHA3_ABSORB_BIT);
587 
588  // Second status read: checks FIFO depth. Always return 0 (i.e. 0 entries
589  // occupied, FIFO is completely free).
590  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, 1 << KMAC_STATUS_SHA3_ABSORB_BIT);
591  ExpectMessageInt32(pMsg, kMsg.size());
592 
594  dif_kmac_absorb(&kmac_, &op_state_, pMsg, kMsg.size(), nullptr));
595  }
596 }
597 
598 class ConfigLock : public KmacTest {};
599 
600 TEST_F(ConfigLock, Locked) {
601  EXPECT_READ32(KMAC_CFG_REGWEN_REG_OFFSET, 0);
602 
603  bool lock = false;
604  EXPECT_EQ(dif_kmac_config_is_locked(&kmac_, &lock), kDifOk);
605  EXPECT_TRUE(lock);
606 }
607 
608 TEST_F(ConfigLock, Unlocked) {
609  EXPECT_READ32(KMAC_CFG_REGWEN_REG_OFFSET, 1);
610 
611  bool lock = true;
612  EXPECT_EQ(dif_kmac_config_is_locked(&kmac_, &lock), kDifOk);
613  EXPECT_FALSE(lock);
614 }
615 
616 TEST_F(ConfigLock, BadArg) {
617  bool locked;
618  EXPECT_DIF_BADARG(dif_kmac_config_is_locked(nullptr, &locked));
620 }
621 
622 class KmacEndTest : public KmacTest {
623  protected:
624  KmacEndTest() { op_state_.squeezing = true; }
625 };
626 
627 TEST_F(KmacEndTest, Success) {
628  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_SQUEEZE_BIT, true}});
629  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
630  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_DONE}});
631 
632  EXPECT_DIF_OK(dif_kmac_end(&kmac_, &op_state_));
633 
634  EXPECT_EQ(op_state_.squeezing, false);
635  EXPECT_EQ(op_state_.append_d, false);
636  EXPECT_EQ(op_state_.offset, 0);
637  EXPECT_EQ(op_state_.r, 0);
638  EXPECT_EQ(op_state_.d, 0);
639 }
640 
641 TEST_F(KmacEndTest, BadArg) {
642  EXPECT_DIF_BADARG(dif_kmac_end(nullptr, &op_state_));
643 
644  EXPECT_DIF_BADARG(dif_kmac_end(&kmac_, nullptr));
645 }
646 
647 TEST_F(KmacEndTest, Error) {
648  op_state_.squeezing = false;
649  EXPECT_EQ(dif_kmac_end(&kmac_, &op_state_), kDifError);
650 }
651 
652 class KmacConfigureTest : public KmacTest {
653  protected:
654  dif_kmac_config_t kmac_config_ = {
655  .entropy_mode = kDifKmacEntropyModeIdle,
656  .entropy_fast_process = false,
657  .entropy_seed = {0xb153e3fe, 0x09596819, 0x3e85a6e8, 0xb6dcdaba,
658  0x50dc409c, 0x11e1ebd1},
659  .entropy_hash_threshold = 0x03ff,
660  .entropy_wait_timer = 0xffff,
661  .entropy_prescaler = 0x03ff,
662  .message_big_endian = false,
663  .output_big_endian = false,
664  .sideload = false,
665  .msg_mask = true,
666  };
668  config_reg_.entropy_hash_threshold = kmac_config_.entropy_hash_threshold,
669  config_reg_.entropy_wait_timer = kmac_config_.entropy_wait_timer,
670  config_reg_.entropy_prescaler = kmac_config_.entropy_prescaler,
671  config_reg_.msg_big_endian = kmac_config_.message_big_endian;
672  config_reg_.state_big_endian = kmac_config_.output_big_endian;
673  config_reg_.entropy_mode = kmac_config_.entropy_mode;
674  config_reg_.entropy_fast_process = kmac_config_.entropy_fast_process;
675  config_reg_.sideload = kmac_config_.sideload;
676  config_reg_.key_strength = 0;
677  config_reg_.mode = 0;
678  config_reg_.msg_mask = kmac_config_.msg_mask;
679  }
680 };
681 
682 TEST_F(KmacConfigureTest, Success) {
683  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true}});
684  EXPECT_WRITE32(
685  KMAC_ENTROPY_PERIOD_REG_OFFSET,
686  {{KMAC_ENTROPY_PERIOD_PRESCALER_OFFSET, kmac_config_.entropy_prescaler},
687  {KMAC_ENTROPY_PERIOD_WAIT_TIMER_OFFSET,
688  kmac_config_.entropy_wait_timer}});
689  EXPECT_WRITE32_SHADOWED(
690  KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_REG_OFFSET,
691  {{KMAC_ENTROPY_REFRESH_THRESHOLD_SHADOWED_THRESHOLD_OFFSET,
692  kmac_config_.entropy_hash_threshold}});
693  ExpectConfig();
694  ExpectEntropySeed(kmac_config_.entropy_seed);
695  EXPECT_DIF_OK(dif_kmac_configure(&kmac_, kmac_config_));
696 }
697 
698 TEST_F(KmacConfigureTest, BadArg) {
699  EXPECT_DIF_BADARG(dif_kmac_configure(NULL, kmac_config_));
700  kmac_config_.entropy_mode = (dif_kmac_entropy_mode_t)0xff;
701  EXPECT_DIF_BADARG(dif_kmac_configure(&kmac_, kmac_config_));
702 }
703 
704 TEST_F(KmacConfigureTest, Locked) {
705  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, false}});
706  EXPECT_EQ(dif_kmac_configure(&kmac_, kmac_config_), kDifLocked);
707 }
708 
709 class KmacStatusTest : public KmacTest {
710  protected:
711  dif_kmac_status_t status_;
712 };
713 
714 TEST_F(KmacStatusTest, IdleFifoEmptySuccess) {
715  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_IDLE_BIT, true},
716  {KMAC_STATUS_FIFO_EMPTY_BIT, true}});
717  EXPECT_DIF_OK(dif_kmac_get_status(&kmac_, &status_));
718 
719  EXPECT_EQ(status_.sha3_state, kDifKmacSha3StateIdle);
720  EXPECT_EQ(status_.fifo_depth, 0);
721  EXPECT_EQ(status_.fifo_state, kDifKmacFifoStateEmpty);
722  EXPECT_EQ(status_.faults, kDifKmacAlertNone);
723 }
724 
725 TEST_F(KmacStatusTest, AbsorbingFifoPartialSuccess) {
726  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_ABSORB_BIT, true},
727  {KMAC_STATUS_FIFO_DEPTH_OFFSET,
728  KMAC_PARAM_NUM_ENTRIES_MSG_FIFO}});
729  EXPECT_DIF_OK(dif_kmac_get_status(&kmac_, &status_));
730 
731  EXPECT_EQ(status_.sha3_state, kDifKmacSha3StateAbsorbing);
732  EXPECT_EQ(status_.fifo_depth, KMAC_PARAM_NUM_ENTRIES_MSG_FIFO);
733  EXPECT_EQ(status_.fifo_state, kDifKmacFifoStatePartial);
734  EXPECT_EQ(status_.faults, kDifKmacAlertNone);
735 }
736 
737 TEST_F(KmacStatusTest, SqueezingFifoFullSuccess) {
738  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_SQUEEZE_BIT, true},
739  {KMAC_STATUS_FIFO_DEPTH_OFFSET, 15},
740  {KMAC_STATUS_FIFO_FULL_BIT, true}});
741  EXPECT_DIF_OK(dif_kmac_get_status(&kmac_, &status_));
742 
743  EXPECT_EQ(status_.sha3_state, kDifKmacSha3StateSqueezing);
744  EXPECT_EQ(status_.fifo_depth, 15);
745  EXPECT_EQ(status_.fifo_state, kDifKmacFifoStateFull);
746  EXPECT_EQ(status_.faults, kDifKmacAlertNone);
747 }
748 
749 TEST_F(KmacStatusTest, AbsorbingFifoFullFatalFault) {
750  EXPECT_READ32(KMAC_STATUS_REG_OFFSET,
751  {{KMAC_STATUS_SHA3_ABSORB_BIT, true},
752  {KMAC_STATUS_FIFO_DEPTH_OFFSET, 5},
753  {KMAC_STATUS_FIFO_FULL_BIT, true},
754  {KMAC_STATUS_ALERT_FATAL_FAULT_BIT, true}});
755  EXPECT_DIF_OK(dif_kmac_get_status(&kmac_, &status_));
756 
757  EXPECT_EQ(status_.sha3_state, kDifKmacSha3StateAbsorbing);
758  EXPECT_EQ(status_.fifo_depth, 5);
759  EXPECT_EQ(status_.fifo_state, kDifKmacFifoStateFull);
760  EXPECT_EQ(status_.faults, kDifKmacAlertFatalFault);
761 }
762 
763 TEST_F(KmacStatusTest, AbsorbingFifoFullUpdateError) {
764  EXPECT_READ32(KMAC_STATUS_REG_OFFSET,
765  {{KMAC_STATUS_SHA3_ABSORB_BIT, true},
766  {KMAC_STATUS_FIFO_DEPTH_OFFSET, 2},
767  {KMAC_STATUS_FIFO_FULL_BIT, true},
768  {KMAC_STATUS_ALERT_RECOV_CTRL_UPDATE_ERR_BIT, true}});
769  EXPECT_DIF_OK(dif_kmac_get_status(&kmac_, &status_));
770 
771  EXPECT_EQ(status_.sha3_state, kDifKmacSha3StateAbsorbing);
772  EXPECT_EQ(status_.fifo_depth, 2);
773  EXPECT_EQ(status_.fifo_state, kDifKmacFifoStateFull);
774  EXPECT_EQ(status_.faults, kDifKmacAlertRecovCtrlUpdate);
775 }
776 
777 TEST_F(KmacStatusTest, BadArg) {
778  EXPECT_DIF_BADARG(dif_kmac_get_status(nullptr, &status_));
779  EXPECT_DIF_BADARG(dif_kmac_get_status(&kmac_, nullptr));
780 }
781 
782 class KmacGetErrorTest : public KmacTest {
783  protected:
784  static constexpr std::array<dif_kmac_error_t, 14> kErrors = {
791  kDifErrorUnexpectedModeStrength,
792  kDifErrorIncorrectFunctionName,
793  kDifErrorSoftwareCommandSequence,
794  kDifErrorSoftwareHashingWithoutEntropyReady,
795  kDifErrorFatalError,
796  kDifErrorPackerIntegrity,
797  kDifErrorMsgFifoIntegrity,
798  };
799  dif_kmac_error_t error_;
800  uint32_t info_;
801  KmacGetErrorTest() { op_state_.squeezing = true; }
802 };
803 constexpr std::array<dif_kmac_error_t, 14> KmacGetErrorTest::kErrors;
804 
805 TEST_F(KmacGetErrorTest, Success) {
806  for (auto err : kErrors) {
807  uint32_t reg = err << 24 | 0x500bad;
808  EXPECT_READ32(KMAC_ERR_CODE_REG_OFFSET, reg);
809  EXPECT_DIF_OK(dif_kmac_get_error(&kmac_, &error_, &info_));
810  EXPECT_EQ(error_, err);
811  EXPECT_EQ(info_, 0x500bad);
812  }
813 }
814 
815 TEST_F(KmacGetErrorTest, BadArg) {
816  EXPECT_DIF_BADARG(dif_kmac_get_error(nullptr, &error_, &info_));
817 
818  EXPECT_DIF_BADARG(dif_kmac_get_error(&kmac_, nullptr, &info_));
819 
820  EXPECT_DIF_BADARG(dif_kmac_get_error(&kmac_, &error_, nullptr));
821 }
822 
824  protected:
825  uint32_t hash_ctr_;
826 };
827 
828 TEST_F(KmacGetHashCounterTest, Success) {
829  EXPECT_READ32(KMAC_ENTROPY_REFRESH_HASH_CNT_REG_OFFSET,
830  {{KMAC_PARAM_HASH_CNT_W, 0}});
831  EXPECT_DIF_OK(dif_kmac_get_hash_counter(&kmac_, &hash_ctr_));
832 }
833 
834 TEST_F(KmacGetHashCounterTest, BadArg) {
835  EXPECT_DIF_BADARG(dif_kmac_get_hash_counter(nullptr, &hash_ctr_));
836 
838 }
839 
840 class KmacSqueezeTest : public KmacTest {
841  protected:
842  dif_kmac_operation_state_t expected_op_state_ = {
843  .squeezing = true,
844  .append_d = false,
845  .offset = 30,
846  .r = 34,
847  .d = 30,
848  };
849 
850  uint32_t out_buffer_[8];
851  size_t processed_;
852  static constexpr std::array<std::array<uint32_t, 64>, 2> kOutShares = {
853  {{0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A,
854  0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A,
855  0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A,
856  0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A,
857  0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A,
858  0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A,
859  0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A,
860  0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A,
861  0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A,
862  0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A,
863  0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A},
864  {0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A,
865  0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A,
866  0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A,
867  0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A,
868  0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A,
869  0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A,
870  0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A,
871  0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A,
872  0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0x5AA5A55A, 0x5AA5A55A,
873  0x5AA5A55A, 0x5AA5A55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A, 0xA55AA55A,
874  0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A, 0x5AA5A55A}}};
875 
876  KmacSqueezeTest() {
877  op_state_.r = GetRateWords(256);
878  op_state_.squeezing = false;
879  op_state_.append_d = false;
880  }
881 
882  void ExpectAppendSize() {
883  uint32_t d = op_state_.d * sizeof(uint32_t) * 8;
884  uint8_t len = 1 + (d > 0xFF) + (d > 0xFFFF) + (d > 0xFFFFFF);
885  uint8_t shift = len * 8;
886  do {
887  shift -= 8;
888  EXPECT_WRITE8(KMAC_MSG_FIFO_REG_OFFSET, (d >> shift) & 0xFF);
889  } while (shift);
890  EXPECT_WRITE8(KMAC_MSG_FIFO_REG_OFFSET, len & 0xFF);
891  }
892 
893  void ExpectReadOutput(const uint32_t *share1, const uint32_t *share2,
894  size_t len) {
895  uint32_t offset = KMAC_STATE_REG_OFFSET;
896  for (size_t i = 0; i < len; ++i) {
897  // Read both shares from state register and combine using XOR.
898  EXPECT_READ32(offset, share1[i]);
899  EXPECT_READ32(offset + 0x100, share2[i]);
900  offset += sizeof(uint32_t);
901  }
902  }
903 };
904 constexpr std::array<std::array<uint32_t, 64>, 2> KmacSqueezeTest::kOutShares;
905 
906 TEST_F(KmacSqueezeTest, GenerateExtraStatesSuccess) {
907  uint32_t out_buffer[64];
908  op_state_.d = ARRAYSIZE(out_buffer);
909 
910  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
911  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_PROCESS}});
912  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_SQUEEZE_BIT, true}});
913  ExpectReadOutput(kOutShares[0].data(), kOutShares[1].data(), 34);
914  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
915  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_RUN}});
916  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_SQUEEZE_BIT, true}});
917  ExpectReadOutput(&kOutShares[0].data()[34], &kOutShares[1].data()[34],
918  kOutShares[0].size() - 34);
919 
920  EXPECT_DIF_OK(dif_kmac_squeeze(&kmac_, &op_state_, out_buffer,
921  ARRAYSIZE(out_buffer), nullptr, nullptr));
922 
923  EXPECT_EQ(op_state_, expected_op_state_);
924 
925  std::array<uint32_t, ARRAYSIZE(out_buffer)> out;
926  for (size_t i = 0; i < out.size(); i++) {
927  out[i] = kOutShares[0][i] ^ kOutShares[1][i];
928  }
929  EXPECT_THAT(out_buffer, ElementsAreArray(out));
930 }
931 
932 TEST_F(KmacSqueezeTest, FillOutBufferSuccess) {
933  op_state_.d = ARRAYSIZE(out_buffer_);
934  expected_op_state_.d = ARRAYSIZE(out_buffer_);
935  expected_op_state_.offset = 8;
936 
937  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
938  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_PROCESS}});
939  EXPECT_READ32(KMAC_STATUS_REG_OFFSET, {{KMAC_STATUS_SHA3_SQUEEZE_BIT, true}});
940  ExpectReadOutput(kOutShares[0].data(), kOutShares[1].data(),
941  ARRAYSIZE(out_buffer_));
942 
943  EXPECT_DIF_OK(dif_kmac_squeeze(&kmac_, &op_state_, out_buffer_,
944  ARRAYSIZE(out_buffer_), nullptr, nullptr));
945 
946  EXPECT_EQ(op_state_, expected_op_state_);
947 
948  std::array<uint32_t, ARRAYSIZE(out_buffer_)> out;
949  for (size_t i = 0; i < out.size(); i++) {
950  out[i] = kOutShares[0][i] ^ kOutShares[1][i];
951  }
952  EXPECT_THAT(out_buffer_, ElementsAreArray(out));
953 }
954 
955 TEST_F(KmacSqueezeTest, AppendSizeSuccess) {
956  op_state_.append_d = true;
957  op_state_.d = ARRAYSIZE(out_buffer_);
958  expected_op_state_.append_d = true;
959  expected_op_state_.d = ARRAYSIZE(out_buffer_);
960  expected_op_state_.r = GetRateWords(256);
961  expected_op_state_.offset = 0;
962 
963  ExpectAppendSize();
964  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
965  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_PROCESS}});
967  dif_kmac_squeeze(&kmac_, &op_state_, nullptr, 0, nullptr, nullptr));
968 
969  EXPECT_EQ(op_state_, expected_op_state_);
970 }
971 
972 TEST_F(KmacSqueezeTest, JustProcessSuccess) {
973  expected_op_state_.d = 0;
974  expected_op_state_.r = GetRateWords(256);
975  expected_op_state_.offset = 0;
976  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
977  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_PROCESS}});
978 
980  dif_kmac_squeeze(&kmac_, &op_state_, nullptr, 0, nullptr, nullptr));
981  EXPECT_EQ(op_state_, expected_op_state_);
982  EXPECT_EQ(op_state_.d, 0);
983 }
984 
985 TEST_F(KmacSqueezeTest, BadArg) {
986  EXPECT_DIF_BADARG(dif_kmac_squeeze(NULL, &op_state_, out_buffer_,
987  ARRAYSIZE(out_buffer_), nullptr, nullptr));
988  EXPECT_DIF_BADARG(dif_kmac_squeeze(&kmac_, nullptr, out_buffer_,
989  ARRAYSIZE(out_buffer_), nullptr, nullptr));
990  EXPECT_DIF_BADARG(dif_kmac_squeeze(&kmac_, &op_state_, nullptr,
991  ARRAYSIZE(out_buffer_), nullptr, nullptr));
992 }
993 
994 TEST_F(KmacSqueezeTest, StarteMachineError) {
995  op_state_.d = ARRAYSIZE(out_buffer_) / 2;
996  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
997  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_PROCESS}});
998 
999  EXPECT_EQ(dif_kmac_squeeze(&kmac_, &op_state_, out_buffer_,
1000  ARRAYSIZE(out_buffer_), nullptr, nullptr),
1001  kDifError);
1002 }
1003 
1004 TEST_F(KmacSqueezeTest, RequestLessDataThanFixedLenError) {
1005  op_state_.d = ARRAYSIZE(out_buffer_);
1006 
1007  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET,
1008  {{KMAC_CMD_CMD_OFFSET, KMAC_CMD_CMD_VALUE_PROCESS}});
1009  EXPECT_READ32(KMAC_STATUS_REG_OFFSET,
1010  {{KMAC_STATUS_SHA3_SQUEEZE_BIT, false}});
1011  EXPECT_READ32(KMAC_INTR_STATE_REG_OFFSET,
1012  {{KMAC_INTR_STATE_KMAC_ERR_BIT, true}});
1013 
1014  EXPECT_EQ(dif_kmac_squeeze(&kmac_, &op_state_, out_buffer_,
1015  ARRAYSIZE(out_buffer_), nullptr, nullptr),
1016  kDifError);
1017 }
1018 
1019 class KmacResetTest : public KmacTest {};
1020 
1021 TEST_F(KmacResetTest, Success) {
1022  EXPECT_WRITE32(KMAC_CMD_REG_OFFSET, {{KMAC_CMD_ERR_PROCESSED_BIT, true}});
1023  EXPECT_DIF_OK(dif_kmac_reset(&kmac_, &op_state_));
1024  EXPECT_EQ(op_state_.squeezing, false);
1025  EXPECT_EQ(op_state_.append_d, false);
1026  EXPECT_EQ(op_state_.offset, 0);
1027  EXPECT_EQ(op_state_.r, 0);
1028  EXPECT_EQ(op_state_.d, 0);
1029 }
1030 
1031 TEST_F(KmacResetTest, BadArg) {
1032  EXPECT_DIF_BADARG(dif_kmac_reset(nullptr, &op_state_));
1033 
1034  EXPECT_DIF_BADARG(dif_kmac_reset(&kmac_, nullptr));
1035 }
1036 
1037 } // namespace dif_kmac_unittest