Software APIs
dif_hmac_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 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
12 #include "sw/device/lib/base/mock_mmio.h"
14 
15 #include "hmac_regs.h" // Generated
16 
17 namespace dif_hmac_unittest {
18 
21 using testing::Test;
22 
23 // Base class for the rest fixtures in this file.
24 class HmacTest : public testing::Test, public mock_mmio::MmioTest {
25  protected:
26  dif_hmac_t hmac_;
27  dif_hmac_transaction_t transaction_ = {
29  .digest_endianness = kDifHmacEndiannessLittle,
30  .digest_size = kDifSHA256,
31  .key_length = kDifHMACKey256,
32  };
33 
34  struct ConfigRegister {
35  bool hmac_enable = false;
36  bool sha_enable = true;
37  bool msg_big_endian = false;
38  bool digest_big_endian = false;
39  uint32_t key_length = HMAC_CFG_KEY_LENGTH_VALUE_KEY_256;
40  uint32_t digest_size = HMAC_CFG_DIGEST_SIZE_VALUE_SHA2_256;
41  } config_reg_;
42 
43  HmacTest() { EXPECT_DIF_OK(dif_hmac_init(dev().region(), &hmac_)); }
44 
45  void ExpectConfig(void) {
46  EXPECT_WRITE32(
47  HMAC_CFG_REG_OFFSET,
48  {
49  {HMAC_CFG_HMAC_EN_BIT, config_reg_.hmac_enable},
50  {HMAC_CFG_SHA_EN_BIT, config_reg_.sha_enable},
51  {HMAC_CFG_ENDIAN_SWAP_BIT, config_reg_.msg_big_endian},
52  {HMAC_CFG_DIGEST_SWAP_BIT, config_reg_.digest_big_endian},
53  {HMAC_CFG_DIGEST_SIZE_OFFSET, config_reg_.digest_size},
54  {HMAC_CFG_KEY_LENGTH_OFFSET, config_reg_.key_length},
55  });
56  }
57 
58  void ExpectKey(const uint8_t *key, size_t size) {
59  for (size_t i = 0; i < size; i += sizeof(uint32_t)) {
60  uint32_t word = 0;
61  memcpy(&word, &key[i], sizeof(uint32_t));
62  EXPECT_WRITE32(HMAC_KEY_7_REG_OFFSET - i, word);
63  }
64  }
65 };
66 
67 class HmacMacTest : public HmacTest {
68  protected:
69  static constexpr std::array<uint8_t, 32> kKey = {
70  0x68, 0x56, 0x6D, 0x59, 0x71, 0x33, 0x74, 0x36, 0x77, 0x39, 0x7A,
71  0x24, 0x43, 0x26, 0x46, 0x29, 0x4A, 0x40, 0x4E, 0x63, 0x51, 0x66,
72  0x54, 0x6A, 0x57, 0x6E, 0x5A, 0x72, 0x34, 0x75, 0x37, 0x78};
73  HmacMacTest() { config_reg_.hmac_enable = true; }
74 
75  void SuccessPath() {
76  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
77  ExpectKey(kKey.data(), kKey.size());
78  ExpectConfig();
79  EXPECT_READ32(HMAC_CMD_REG_OFFSET, 0);
80  EXPECT_WRITE32(HMAC_CMD_REG_OFFSET, {{HMAC_CMD_HASH_START_BIT, true}});
81 
82  EXPECT_DIF_OK(dif_hmac_mode_hmac_start(&hmac_, kKey.data(), transaction_));
83  }
84 };
85 constexpr std::array<uint8_t, 32> HmacMacTest::kKey;
86 
87 TEST_F(HmacMacTest, StartSuccess) { SuccessPath(); }
88 
89 TEST_F(HmacMacTest, StartMsgBigEndianSuccess) {
90  config_reg_.msg_big_endian = true;
92 
93  SuccessPath();
94 }
95 
96 TEST_F(HmacMacTest, StartDigestLittleEndianSuccess) {
97  config_reg_.digest_big_endian = false;
99 
100  SuccessPath();
101 }
102 
103 TEST_F(HmacMacTest, StartBadArg) {
105  dif_hmac_mode_hmac_start(nullptr, kKey.data(), transaction_));
106 }
107 
108 TEST_F(HmacMacTest, StartError) {
109  transaction_.message_endianness = static_cast<dif_hmac_endianness_t>(2);
110 
111  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
112  EXPECT_EQ(dif_hmac_mode_hmac_start(&hmac_, kKey.data(), transaction_),
113  kDifError);
114 
115  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
116  transaction_.digest_endianness = static_cast<dif_hmac_endianness_t>(2);
117  EXPECT_EQ(dif_hmac_mode_hmac_start(&hmac_, kKey.data(), transaction_),
118  kDifError);
119 }
120 
121 class HmacSha256Test : public HmacTest {
122  protected:
123  HmacSha256Test() { config_reg_.sha_enable = true; }
124 };
125 
126 TEST_F(HmacSha256Test, StartSuccess) {
127  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
128  ExpectConfig();
129  EXPECT_READ32(HMAC_CMD_REG_OFFSET, 0);
130  EXPECT_WRITE32(HMAC_CMD_REG_OFFSET, {{HMAC_CMD_HASH_START_BIT, true}});
131 
132  EXPECT_DIF_OK(dif_hmac_mode_sha256_start(&hmac_, transaction_));
133 }
134 
135 TEST_F(HmacSha256Test, StartMsgBigEndianSuccess) {
136  config_reg_.msg_big_endian = true;
138 
139  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
140  ExpectConfig();
141  EXPECT_READ32(HMAC_CMD_REG_OFFSET, 0);
142  EXPECT_WRITE32(HMAC_CMD_REG_OFFSET, {{HMAC_CMD_HASH_START_BIT, true}});
143 
144  EXPECT_DIF_OK(dif_hmac_mode_sha256_start(&hmac_, transaction_));
145 }
146 
147 TEST_F(HmacSha256Test, StartDigestLittleEndianSuccess) {
148  config_reg_.digest_big_endian = false;
150 
151  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
152  ExpectConfig();
153  EXPECT_READ32(HMAC_CMD_REG_OFFSET, 0);
154  EXPECT_WRITE32(HMAC_CMD_REG_OFFSET, {{HMAC_CMD_HASH_START_BIT, true}});
155 
156  EXPECT_DIF_OK(dif_hmac_mode_sha256_start(&hmac_, transaction_));
157 }
158 
159 TEST_F(HmacSha256Test, StartBadArg) {
160  EXPECT_DIF_BADARG(dif_hmac_mode_sha256_start(nullptr, transaction_));
161 }
162 
163 TEST_F(HmacSha256Test, StartError) {
164  transaction_.message_endianness = static_cast<dif_hmac_endianness_t>(2);
165 
166  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
167  EXPECT_EQ(dif_hmac_mode_sha256_start(&hmac_, transaction_), kDifError);
168 
169  EXPECT_READ32(HMAC_CFG_REG_OFFSET, 0);
170  transaction_.digest_endianness = static_cast<dif_hmac_endianness_t>(2);
171  EXPECT_EQ(dif_hmac_mode_sha256_start(&hmac_, transaction_), kDifError);
172 }
173 
174 class HmacProcessTest : public HmacTest {
175  protected:
176  HmacProcessTest() {}
177 };
178 
179 TEST_F(HmacProcessTest, StartSuccess) {
180  EXPECT_READ32(HMAC_CMD_REG_OFFSET, 0);
181  EXPECT_WRITE32(HMAC_CMD_REG_OFFSET, {{HMAC_CMD_HASH_PROCESS_BIT, true}});
183 }
184 
185 TEST_F(HmacProcessTest, ProcessBadArg) {
187 }
188 
190  protected:
192 };
193 
194 TEST_F(HmacGetMessageLengthTest, RunSuccess) {
195  EXPECT_READ32(HMAC_MSG_LENGTH_LOWER_REG_OFFSET, 0xfd257515);
196  EXPECT_READ32(HMAC_MSG_LENGTH_UPPER_REG_OFFSET, 0xaf3975bc);
197  uint64_t len = 0;
199  EXPECT_EQ(len, 0xaf3975bcfd257515);
200 }
201 
202 TEST_F(HmacGetMessageLengthTest, BadArgHmac) {
203  uint64_t len = 0;
205 }
206 
207 TEST_F(HmacGetMessageLengthTest, BadArgLen) {
209 }
210 
211 } // namespace dif_hmac_unittest