Software APIs
owner_block_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 
5 #include "sw/device/silicon_creator/lib/ownership/owner_block.h"
6 
7 #include <stdint.h>
8 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
12 #include "sw/device/lib/testing/binary_blob.h"
13 #include "sw/device/silicon_creator/lib/boot_data.h"
14 #include "sw/device/silicon_creator/lib/drivers/mock_flash_ctrl.h"
15 #include "sw/device/silicon_creator/lib/error.h"
16 #include "sw/device/silicon_creator/lib/ownership/datatypes.h"
17 #include "sw/device/silicon_creator/testing/rom_test.h"
18 
19 namespace {
20 #include "sw/device/silicon_creator/lib/ownership/testdata/basic_owner_testdata.h"
21 
22 using rom_test::FlashCfg;
23 using rom_test::FlashPerms;
24 using rom_test::MockFlashCtrl;
25 using ::testing::_;
26 using ::testing::Return;
27 using ::testutil::BinaryBlob;
28 
30  protected:
31  MockFlashCtrl flash_ctrl_;
32  flash_ctrl_cfg_t default_config = {
33  .scrambling = kMultiBitBool4False,
34  .ecc = kMultiBitBool4False,
35  .he = kMultiBitBool4False,
36  };
37 
38  void SetUp() override {
39  ON_CALL(flash_ctrl_, DataDefaultCfgGet)
40  .WillByDefault(Return(default_config));
41  }
42 };
43 
44 // clang-format off
45 // Create and "encrypt" the `access` word of a flash region config.
46 #define FLASH_ACCESS(index, read, program, erase, pwp, lock) ( \
47  ( \
48  bitfield_field32_write(0, FLASH_CONFIG_READ, read ? kMultiBitBool4True : kMultiBitBool4False) | \
49  bitfield_field32_write(0, FLASH_CONFIG_PROGRAM, program ? kMultiBitBool4True : kMultiBitBool4False) | \
50  bitfield_field32_write(0, FLASH_CONFIG_ERASE, erase ? kMultiBitBool4True : kMultiBitBool4False) | \
51  bitfield_field32_write(0, FLASH_CONFIG_PROTECT_WHEN_PRIMARY, pwp ? kMultiBitBool4True : kMultiBitBool4False) | \
52  bitfield_field32_write(0, FLASH_CONFIG_LOCK, lock ? kMultiBitBool4True : kMultiBitBool4False) \
53  ) ^ (0x11111111 * index) \
54  )
55 
56 // Create and "encrypt" the `properties` word of a flash region config.
57 #define FLASH_PROP(index, scramble, ecc, he) ( \
58  ( \
59  bitfield_field32_write(0, FLASH_CONFIG_SCRAMBLE, scramble ? kMultiBitBool4True : kMultiBitBool4False) | \
60  bitfield_field32_write(0, FLASH_CONFIG_ECC, ecc ? kMultiBitBool4True : kMultiBitBool4False) | \
61  bitfield_field32_write(0, FLASH_CONFIG_HIGH_ENDURANCE, he ? kMultiBitBool4True : kMultiBitBool4False) \
62  ) ^ (0x11111111 * index) \
63  )
64 // clang-format on
65 
66 const owner_flash_config_t simple_flash_config = {
67  .header =
68  {
69  .tag = kTlvTagFlashConfig,
70  .length =
71  sizeof(owner_flash_config_t) + 6 * sizeof(owner_flash_region_t),
72  },
73  .config =
74  {
75  {
76  // SideA ROM_EXT.
77  .start = 0,
78  .size = 32,
79  .access = FLASH_ACCESS(
80  /*index=*/0,
81  /*read=*/true,
82  /*program=*/true,
83  /*erase=*/true,
84  /*pwp=*/true,
85  /*lock=*/false),
86  .properties = FLASH_PROP(
87  /*index=*/0,
88  /*scramble=*/false,
89  /*ecc=*/false,
90  /*he=*/false),
91 
92  },
93  {
94  // SideA FIRMWARE.
95  .start = 32,
96  .size = 192,
97  .access = FLASH_ACCESS(
98  /*index=*/1,
99  /*read=*/true,
100  /*program=*/true,
101  /*erase=*/true,
102  /*pwp=*/true,
103  /*lock=*/false),
104  .properties = FLASH_PROP(
105  /*index=*/1,
106  /*scramble=*/true,
107  /*ecc=*/true,
108  /*he=*/false),
109 
110  },
111  {
112  // SideA Filesystem.
113  .start = 224,
114  .size = 32,
115  .access = FLASH_ACCESS(
116  /*index=*/2,
117  /*read=*/true,
118  /*program=*/true,
119  /*erase=*/true,
120  /*pwp=*/false,
121  /*lock=*/false),
122  .properties = FLASH_PROP(
123  /*index=*/2,
124  /*scramble=*/false,
125  /*ecc=*/false,
126  /*he=*/true),
127 
128  },
129  {
130  // SideB ROM_EXT.
131  .start = 256 + 0,
132  .size = 32,
133  .access = FLASH_ACCESS(
134  /*index=*/3,
135  /*read=*/true,
136  /*program=*/true,
137  /*erase=*/true,
138  /*pwp=*/true,
139  /*lock=*/false),
140  .properties = FLASH_PROP(
141  /*index=*/3,
142  /*scramble=*/false,
143  /*ecc=*/false,
144  /*he=*/false),
145  },
146  {
147  // SideB FIRMWARE.
148  .start = 256 + 32,
149  .size = 192,
150  .access = FLASH_ACCESS(
151  /*index=*/4,
152  /*read=*/true,
153  /*program=*/true,
154  /*erase=*/true,
155  /*pwp=*/true,
156  /*lock=*/false),
157  .properties = FLASH_PROP(
158  /*index=*/4,
159  /*scramble=*/true,
160  /*ecc=*/true,
161  /*he=*/false),
162  },
163  {
164  // SideB Filesystem.
165  .start = 256 + 224,
166  .size = 32,
167  .access = FLASH_ACCESS(
168  /*index=*/5,
169  /*read=*/true,
170  /*program=*/true,
171  /*erase=*/true,
172  /*pwp=*/false,
173  /*lock=*/false),
174  .properties = FLASH_PROP(
175  /*index=*/5,
176  /*scramble=*/false,
177  /*ecc=*/false,
178  /*he=*/true),
179  },
180  },
181 };
182 
183 const owner_flash_config_t bad_flash_config = {
184  .header =
185  {
186  .tag = kTlvTagFlashConfig,
187  .length =
188  sizeof(owner_flash_config_t) + 8 * sizeof(owner_flash_region_t),
189  },
190 };
191 
192 const owner_flash_info_config_t info_config = {
193  .header =
194  {
195  .tag = kTlvTagInfoConfig,
196  .length =
197  sizeof(owner_flash_config_t) + 2 * sizeof(owner_flash_region_t),
198  },
199  .config =
200  {
201  {
202  // User page
203  .bank = 0,
204  .page = 6,
205  .access = FLASH_ACCESS(
206  /*index=*/0,
207  /*read=*/true,
208  /*program=*/true,
209  /*erase=*/true,
210  /*pwp=*/false,
211  /*lock=*/false),
212  .properties = FLASH_PROP(
213  /*index=*/0,
214  /*scramble=*/false,
215  /*ecc=*/false,
216  /*he=*/true),
217 
218  },
219  {
220  // Disallowed page
221  .bank = 0,
222  .page = 5,
223  .access = FLASH_ACCESS(
224  /*index=*/1,
225  /*read=*/true,
226  /*program=*/true,
227  /*erase=*/true,
228  /*pwp=*/false,
229  /*lock=*/false),
230  .properties = FLASH_PROP(
231  /*index=*/1,
232  /*scramble=*/false,
233  /*ecc=*/false,
234  /*he=*/false),
235  },
236 
237  },
238 };
239 
240 TEST_F(OwnerBlockTest, FlashConfigApplyBad) {
241  rom_error_t error = owner_block_flash_apply(&bad_flash_config, kBootSlotA, 0);
242  EXPECT_EQ(error, kErrorOwnershipFlashConfigLenth);
243 }
244 
245 // Tests that the flash parameters get applied for side A.
246 TEST_F(OwnerBlockTest, FlashConfigApplySideA) {
247  EXPECT_CALL(
248  flash_ctrl_,
249  DataRegionProtect(0, 0, 32,
250  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
251  kMultiBitBool4True),
252  FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
253  kMultiBitBool4False),
255  EXPECT_CALL(
256  flash_ctrl_,
257  DataRegionProtect(
258  1, 32, 192,
259  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
260  kMultiBitBool4True),
261  FlashCfg(kMultiBitBool4True, kMultiBitBool4True, kMultiBitBool4False),
263  EXPECT_CALL(
264  flash_ctrl_,
265  DataRegionProtect(2, 224, 32,
266  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
267  kMultiBitBool4True),
268  FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
269  kMultiBitBool4True),
271 
272  rom_error_t error =
273  owner_block_flash_apply(&simple_flash_config, kBootSlotA, 0);
274  EXPECT_EQ(error, kErrorOk);
275 }
276 
277 // Tests that the flash parameters get applied for side A and the
278 // ProtectWhenPrimary disables erase and program on the ROM_EXT and FIRMWARE
279 // regions.
280 TEST_F(OwnerBlockTest, FlashConfigApplySideAPrimary) {
281  EXPECT_CALL(
282  flash_ctrl_,
283  DataRegionProtect(0, 0, 32,
284  FlashPerms(kMultiBitBool4True, kMultiBitBool4False,
285  kMultiBitBool4False),
286  FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
287  kMultiBitBool4False),
289  EXPECT_CALL(
290  flash_ctrl_,
291  DataRegionProtect(
292  1, 32, 192,
293  FlashPerms(kMultiBitBool4True, kMultiBitBool4False,
294  kMultiBitBool4False),
295  FlashCfg(kMultiBitBool4True, kMultiBitBool4True, kMultiBitBool4False),
297  EXPECT_CALL(
298  flash_ctrl_,
299  DataRegionProtect(2, 224, 32,
300  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
301  kMultiBitBool4True),
302  FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
303  kMultiBitBool4True),
305 
306  rom_error_t error =
307  owner_block_flash_apply(&simple_flash_config, kBootSlotA, kBootSlotA);
308  EXPECT_EQ(error, kErrorOk);
309 }
310 
311 // Tests that the flash parameters get applied for side B.
312 TEST_F(OwnerBlockTest, FlashConfigApplySideB) {
313  EXPECT_CALL(
314  flash_ctrl_,
315  DataRegionProtect(3, 256 + 0, 32,
316  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
317  kMultiBitBool4True),
318  FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
319  kMultiBitBool4False),
321  EXPECT_CALL(
322  flash_ctrl_,
323  DataRegionProtect(
324  4, 256 + 32, 192,
325  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
326  kMultiBitBool4True),
327  FlashCfg(kMultiBitBool4True, kMultiBitBool4True, kMultiBitBool4False),
329  EXPECT_CALL(
330  flash_ctrl_,
331  DataRegionProtect(5, 256 + 224, 32,
332  FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
333  kMultiBitBool4True),
334  FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
335  kMultiBitBool4True),
337 
338  rom_error_t error =
339  owner_block_flash_apply(&simple_flash_config, kBootSlotB, 0);
340  EXPECT_EQ(error, kErrorOk);
341 }
342 
343 TEST_F(OwnerBlockTest, FlashInfoApply) {
344  EXPECT_CALL(flash_ctrl_,
345  InfoCfgSet(_, FlashCfg(kMultiBitBool4False, kMultiBitBool4False,
346  kMultiBitBool4True)));
347  EXPECT_CALL(flash_ctrl_,
348  InfoPermsSet(_, FlashPerms(kMultiBitBool4True, kMultiBitBool4True,
349  kMultiBitBool4True)));
350 
351  rom_error_t error = owner_block_info_apply(&info_config);
352  EXPECT_EQ(error, kErrorOk);
353 }
354 
355 TEST_F(OwnerBlockTest, ParseBlock) {
356  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
357  owner_config_t config;
358  owner_application_keyring_t keyring{};
359 
360  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
361  .WillRepeatedly(Return(default_config));
362  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
363  EXPECT_EQ(error, kErrorOk);
364  EXPECT_EQ(config.sram_exec, kOwnerSramExecModeDisabledLocked);
365  EXPECT_EQ(config.flash->header.tag, kTlvTagFlashConfig);
366  EXPECT_EQ(config.info->header.tag, kTlvTagInfoConfig);
367  EXPECT_EQ(config.rescue->header.tag, kTlvTagRescueConfig);
368  EXPECT_EQ(keyring.length, 1);
369  EXPECT_EQ(keyring.key[0]->header.tag, kTlvTagApplicationKey);
370 }
371 
372 TEST_F(OwnerBlockTest, ParseBlockBadHeaderLength) {
373  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
374  // Rewrite the header length to a bad value
375  block.Seek(offsetof(owner_block_t, header.length)).Write(12345);
376  owner_config_t config;
377  owner_application_keyring_t keyring{};
378  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
379  EXPECT_EQ(error, kErrorOwnershipInvalidTagLength);
380 }
381 
382 TEST_F(OwnerBlockTest, ParseBlockBadHeaderTag) {
383  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
384  // Rewrite the header tag from `OWNR` to `AAAA`.
385  block.Seek(offsetof(owner_block_t, header.tag)).Write(0x41414141);
386  owner_config_t config;
387  owner_application_keyring_t keyring{};
388  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
389  EXPECT_EQ(error, kErrorOwnershipInvalidTag);
390 }
391 
392 TEST_F(OwnerBlockTest, ParseBlockUnknownTag) {
393  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
394  .WillRepeatedly(Return(default_config));
395  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
396  // Write an unknown header of {tag="AAAA", len=0x40} after the RESQ config.
397  tlv_header_t rescue = block.Find(kTlvTagRescueConfig).Read<tlv_header_t>();
398  block.Seek(rescue.length - sizeof(tlv_header_t))
399  .Write(0x41414141)
400  .Write(0x40);
401  owner_config_t config;
402  owner_application_keyring_t keyring{};
403 
404  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
405  EXPECT_EQ(error, kErrorOwnershipInvalidTag);
406 }
407 
408 TEST_F(OwnerBlockTest, ParseBlockBadLength) {
409  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
410  owner_config_t config;
411  owner_application_keyring_t keyring{};
412  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
413  .WillRepeatedly(Return(default_config));
414 
415  // Rewrite the RESQ block length to overflow the TLV region.
416  block.Find(kTlvTagRescueConfig)
417  .Seek(offsetof(tlv_header_t, length))
418  .Write(uint16_t(0x600));
419  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
420  EXPECT_EQ(error, kErrorOwnershipInvalidTagLength);
421 
422  // Rewrite the RESQ block length to be too short.
423  block.Reset()
424  .Find(kTlvTagRescueConfig)
425  .Seek(offsetof(tlv_header_t, length))
426  .Write(uint16_t(0x4));
427  error = owner_block_parse(block.get(), &config, &keyring);
428  EXPECT_EQ(error, kErrorOwnershipInvalidTagLength);
429 
430  // Rewrite the RESQ block length to not be a multiple of 4.
431  block.Reset()
432  .Find(kTlvTagRescueConfig)
433  .Seek(offsetof(tlv_header_t, length))
434  .Write(uint16_t(0x21));
435  error = owner_block_parse(block.get(), &config, &keyring);
436  EXPECT_EQ(error, kErrorOwnershipInvalidTagLength);
437 }
438 
439 TEST_F(OwnerBlockTest, ParseBlockDupFlash) {
440  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
441  .WillRepeatedly(Return(default_config));
442  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
443  // Rewrite the RESQ tag as a FLSH tag to test duplicate detection.
444  block.Find(kTlvTagRescueConfig).Write(kTlvTagFlashConfig);
445  owner_config_t config;
446  owner_application_keyring_t keyring{};
447  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
448  EXPECT_EQ(error, kErrorOwnershipDuplicateItem);
449 }
450 
451 TEST_F(OwnerBlockTest, ParseBlockDupInfo) {
452  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
453  .WillRepeatedly(Return(default_config));
454  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
455  // Rewrite the RESQ tag as an INFO tag to test duplicate detection.
456  block.Find(kTlvTagRescueConfig).Write(kTlvTagInfoConfig);
457  owner_config_t config;
458  owner_application_keyring_t keyring{};
459  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
460  EXPECT_EQ(error, kErrorOwnershipDuplicateItem);
461 }
462 
463 TEST_F(OwnerBlockTest, ParseBlockDupRescue) {
464  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
465  // Rewrite the FLSH tag as a RESQ tag to test duplicate detection.
466  block.Find(kTlvTagFlashConfig).Write(kTlvTagRescueConfig);
467  owner_config_t config;
468  owner_application_keyring_t keyring{};
469  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
470  EXPECT_EQ(error, kErrorOwnershipDuplicateItem);
471 }
472 
473 struct TagError {
474  tlv_tag_t tag;
475  rom_error_t expect;
476 };
477 
479  public testing::WithParamInterface<TagError> {};
480 
481 TEST_P(OwnerBlockPerTagTest, ParseBadVersion) {
482  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
483  .WillRepeatedly(Return(default_config));
484  BinaryBlob<owner_block_t> block(basic_owner, sizeof(basic_owner));
485  TagError param = GetParam();
486 
487  // Rewrite the version to a bad value.
488  block.Find(param.tag)
489  .Seek(offsetof(tlv_header_t, version))
490  .Write((struct_version_t){5, 0});
491  owner_config_t config;
492  owner_application_keyring_t keyring{};
493  rom_error_t error = owner_block_parse(block.get(), &config, &keyring);
494  EXPECT_EQ(error, param.expect);
495 }
496 
497 INSTANTIATE_TEST_SUITE_P(
498  AllCases, OwnerBlockPerTagTest,
499  testing::Values(TagError{kTlvTagOwner, kErrorOwnershipOWNRVersion},
500  TagError{kTlvTagApplicationKey, kErrorOwnershipAPPKVersion},
501  TagError{kTlvTagFlashConfig, kErrorOwnershipFLSHVersion},
502  TagError{kTlvTagInfoConfig, kErrorOwnershipINFOVersion},
503  TagError{kTlvTagRescueConfig, kErrorOwnershipRESQVersion}));
504 
505 // Flash region is the exact size of the ROM_EXT and has a bad ECC setting.
506 const owner_flash_config_t invalid_flash_0 = {
507  .header =
508  {
509  .tag = kTlvTagFlashConfig,
510  .length =
511  sizeof(owner_flash_config_t) + 1 * sizeof(owner_flash_region_t),
512  },
513  .config =
514  {
515  {
516  // SideA ROM_EXT.
517  .start = 0,
518  .size = 32,
519  .access = FLASH_ACCESS(
520  /*index=*/0,
521  /*read=*/true,
522  /*program=*/true,
523  /*erase=*/true,
524  /*pwp=*/true,
525  /*lock=*/false),
526  .properties = FLASH_PROP(
527  /*index=*/0,
528  /*scramble=*/false,
529  /*ecc=*/true,
530  /*he=*/false),
531  },
532  },
533 };
534 
535 // Flash regions is ROM_EXT and APP and has a bad ECC setting.
536 const owner_flash_config_t invalid_flash_1 = {
537  .header =
538  {
539  .tag = kTlvTagFlashConfig,
540  .length =
541  sizeof(owner_flash_config_t) + 1 * sizeof(owner_flash_region_t),
542  },
543  .config =
544  {
545  {
546  // SideA ROM_EXT & APP.
547  .start = 0,
548  .size = 224,
549  .access = FLASH_ACCESS(
550  /*index=*/0,
551  /*read=*/true,
552  /*program=*/true,
553  /*erase=*/true,
554  /*pwp=*/true,
555  /*lock=*/false),
556  .properties = FLASH_PROP(
557  /*index=*/0,
558  /*scramble=*/false,
559  /*ecc=*/true,
560  /*he=*/false),
561  },
562  },
563 };
564 
565 // Flash region straddles ROM_EXT and first has a bad ECC setting.
566 const owner_flash_config_t invalid_flash_2 = {
567  .header =
568  {
569  .tag = kTlvTagFlashConfig,
570  .length =
571  sizeof(owner_flash_config_t) + 2 * sizeof(owner_flash_region_t),
572  },
573  .config =
574  {
575  {
576  // SideA ROM_EXT.
577  .start = 0,
578  .size = 16,
579  .access = FLASH_ACCESS(
580  /*index=*/0,
581  /*read=*/true,
582  /*program=*/true,
583  /*erase=*/true,
584  /*pwp=*/true,
585  /*lock=*/false),
586  .properties = FLASH_PROP(
587  /*index=*/0,
588  /*scramble=*/false,
589  /*ecc=*/true,
590  /*he=*/false),
591  },
592  {
593  // SideA APP
594  .start = 16,
595  .size = 240,
596  .access = FLASH_ACCESS(
597  /*index=*/1,
598  /*read=*/true,
599  /*program=*/true,
600  /*erase=*/true,
601  /*pwp=*/true,
602  /*lock=*/false),
603  .properties = FLASH_PROP(
604  /*index=*/1,
605  /*scramble=*/false,
606  /*ecc=*/false,
607  /*he=*/false),
608  },
609  },
610 };
611 
612 // Flash region straddles ROM_EXT and second has a bad ECC setting.
613 const owner_flash_config_t invalid_flash_3 = {
614  .header =
615  {
616  .tag = kTlvTagFlashConfig,
617  .length =
618  sizeof(owner_flash_config_t) + 2 * sizeof(owner_flash_region_t),
619  },
620  .config =
621  {
622  {
623  // SideA ROM_EXT.
624  .start = 0,
625  .size = 16,
626  .access = FLASH_ACCESS(
627  /*index=*/0,
628  /*read=*/true,
629  /*program=*/true,
630  /*erase=*/true,
631  /*pwp=*/true,
632  /*lock=*/false),
633  .properties = FLASH_PROP(
634  /*index=*/0,
635  /*scramble=*/false,
636  /*ecc=*/true,
637  /*he=*/false),
638  },
639  {
640  // SideA APP
641  .start = 16,
642  .size = 240,
643  .access = FLASH_ACCESS(
644  /*index=*/1,
645  /*read=*/true,
646  /*program=*/true,
647  /*erase=*/true,
648  /*pwp=*/true,
649  /*lock=*/false),
650  .properties = FLASH_PROP(
651  /*index=*/1,
652  /*scramble=*/false,
653  /*ecc=*/false,
654  /*he=*/false),
655  },
656  },
657 };
658 
659 // Flash region is the exact size of the ROM_EXT. SideA is good, SideB is bad.
660 const owner_flash_config_t invalid_flash_4 = {
661  .header =
662  {
663  .tag = kTlvTagFlashConfig,
664  .length =
665  sizeof(owner_flash_config_t) + 2 * sizeof(owner_flash_region_t),
666  },
667  .config =
668  {
669  {
670  // SideA ROM_EXT.
671  .start = 0,
672  .size = 32,
673  .access = FLASH_ACCESS(
674  /*index=*/0,
675  /*read=*/true,
676  /*program=*/true,
677  /*erase=*/true,
678  /*pwp=*/true,
679  /*lock=*/false),
680  .properties = FLASH_PROP(
681  /*index=*/0,
682  /*scramble=*/false,
683  /*ecc=*/false,
684  /*he=*/false),
685  },
686  {
687  // SideB ROM_EXT.
688  .start = 256,
689  .size = 32,
690  .access = FLASH_ACCESS(
691  /*index=*/1,
692  /*read=*/true,
693  /*program=*/true,
694  /*erase=*/true,
695  /*pwp=*/true,
696  /*lock=*/false),
697  .properties = FLASH_PROP(
698  /*index=*/1,
699  /*scramble=*/false,
700  /*ecc=*/true,
701  /*he=*/false),
702  },
703  },
704 
705 };
706 
708  : public OwnerBlockTest,
709  public testing::WithParamInterface<const owner_flash_config_t *> {};
710 
711 // Test bad ROM_EXT region configs with respect to the default config.
712 TEST_P(RomExtFlashConfigTest, BadFlashConfig) {
713  EXPECT_CALL(flash_ctrl_, DataDefaultCfgGet)
714  .WillRepeatedly(Return(default_config));
715  const owner_flash_config_t *param = GetParam();
716  rom_error_t error = owner_block_flash_check(param);
717  EXPECT_EQ(error, kErrorOwnershipFlashConfigRomExt);
718 }
719 
720 INSTANTIATE_TEST_SUITE_P(AllCases, RomExtFlashConfigTest,
721  testing::Values(&invalid_flash_0, &invalid_flash_1,
722  &invalid_flash_2, &invalid_flash_3,
723  &invalid_flash_4));
724 
725 } // namespace