xref: /aosp_15_r20/external/pigweed/pw_software_update/update_bundle_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include <array>
16 
17 #include "pw_blob_store/blob_store.h"
18 #include "pw_kvs/fake_flash_memory.h"
19 #include "pw_kvs/test_key_value_store.h"
20 #include "pw_software_update/blob_store_openable_reader.h"
21 #include "pw_software_update/bundled_update_backend.h"
22 #include "pw_software_update/update_bundle_accessor.h"
23 #include "pw_stream/memory_stream.h"
24 #include "pw_unit_test/framework.h"
25 #include "test_bundles.h"
26 
27 #define ASSERT_FAIL(status) ASSERT_NE(OkStatus(), status)
28 
29 namespace pw::software_update {
30 namespace {
31 
32 constexpr size_t kBufferSize = 256;
33 static constexpr size_t kFlashAlignment = 16;
34 constexpr size_t kSectorSize = 2048;
35 constexpr size_t kSectorCount = 2;
36 constexpr size_t kMetadataBufferSize =
37     blob_store::BlobStore::BlobWriter::RequiredMetadataBufferSize(0);
38 
39 class TestBundledUpdateBackend final : public BundledUpdateBackend {
40  public:
TestBundledUpdateBackend()41   TestBundledUpdateBackend()
42       : manifest_reader_({}), trusted_root_memory_reader_({}) {}
43 
ApplyReboot()44   Status ApplyReboot() override { return Status::Unimplemented(); }
PostRebootFinalize()45   Status PostRebootFinalize() override { return OkStatus(); }
46 
ApplyTargetFile(std::string_view,stream::SeekableReader &,size_t)47   Status ApplyTargetFile(std::string_view,
48                          stream::SeekableReader&,
49                          size_t) override {
50     return OkStatus();
51   }
52 
EnableBundleTransferHandler(std::string_view)53   Result<uint32_t> EnableBundleTransferHandler(std::string_view) override {
54     return 0;
55   }
56 
DisableBundleTransferHandler()57   void DisableBundleTransferHandler() override {}
58 
SetTrustedRoot(ConstByteSpan trusted_root)59   void SetTrustedRoot(ConstByteSpan trusted_root) {
60     trusted_root_memory_reader_ = stream::MemoryReader(trusted_root);
61     trusted_root_reader_ = stream::IntervalReader(
62         trusted_root_memory_reader_,
63         0,
64         trusted_root_memory_reader_.ConservativeReadLimit());
65   }
66 
SetCurrentManifest(ConstByteSpan current_manifest)67   void SetCurrentManifest(ConstByteSpan current_manifest) {
68     manifest_reader_ = stream::MemoryReader(current_manifest);
69   }
70 
SetManifestWriter(stream::Writer * writer)71   void SetManifestWriter(stream::Writer* writer) { manifest_writer_ = writer; }
72 
GetRootMetadataReader()73   Result<stream::SeekableReader*> GetRootMetadataReader() override {
74     return &trusted_root_reader_;
75   }
76 
BeforeManifestRead()77   Status BeforeManifestRead() override {
78     before_manifest_read_called_ = true;
79     if (manifest_reader_.ConservativeReadLimit() > 0) {
80       return OkStatus();
81     }
82     return Status::NotFound();
83   }
84 
BeforeManifestReadCalled()85   bool BeforeManifestReadCalled() { return before_manifest_read_called_; }
86 
GetManifestReader()87   Result<stream::SeekableReader*> GetManifestReader() override {
88     return &manifest_reader_;
89   }
90 
BeforeManifestWrite()91   Status BeforeManifestWrite() override {
92     before_manifest_write_called_ = true;
93     return (manifest_writer_) ? OkStatus() : Status::NotFound();
94   }
95 
BeforeManifestWriteCalled()96   bool BeforeManifestWriteCalled() { return before_manifest_write_called_; }
97 
AfterManifestWrite()98   Status AfterManifestWrite() override {
99     after_manifest_write_called_ = true;
100     return OkStatus();
101   }
102 
AfterManifestWriteCalled()103   bool AfterManifestWriteCalled() { return after_manifest_write_called_; }
104 
GetManifestWriter()105   Result<stream::Writer*> GetManifestWriter() override {
106     return manifest_writer_;
107   }
108 
SafelyPersistRootMetadata(stream::IntervalReader root_metadata)109   Status SafelyPersistRootMetadata(
110       [[maybe_unused]] stream::IntervalReader root_metadata) override {
111     new_root_persisted_ = true;
112     trusted_root_reader_ = root_metadata;
113     return OkStatus();
114   }
115 
IsNewRootPersisted() const116   bool IsNewRootPersisted() const { return new_root_persisted_; }
117 
118  private:
119   stream::IntervalReader trusted_root_reader_;
120   stream::MemoryReader manifest_reader_;
121   stream::Writer* manifest_writer_ = nullptr;
122   bool before_manifest_read_called_ = false;
123   bool before_manifest_write_called_ = false;
124   bool after_manifest_write_called_ = false;
125   bool new_root_persisted_ = false;
126 
127   // A memory reader for buffer passed by SetTrustedRoot(). This will be used
128   // to back `trusted_root_reader_`
129   stream::MemoryReader trusted_root_memory_reader_;
130 };
131 
132 class UpdateBundleTest : public testing::Test {
133  public:
UpdateBundleTest()134   UpdateBundleTest()
135       : blob_flash_(kFlashAlignment),
136         blob_partition_(&blob_flash_),
137         bundle_blob_("TestBundle",
138                      blob_partition_,
139                      nullptr,
140                      kvs::TestKvs(),
141                      kBufferSize),
142         blob_reader_(bundle_blob_) {}
143 
bundle_blob()144   blob_store::BlobStoreBuffer<kBufferSize>& bundle_blob() {
145     return bundle_blob_;
146   }
147 
blob_reader()148   BlobStoreOpenableReader& blob_reader() { return blob_reader_; }
149 
backend()150   TestBundledUpdateBackend& backend() { return backend_; }
151 
StageTestBundle(ConstByteSpan bundle_data)152   void StageTestBundle(ConstByteSpan bundle_data) {
153     PW_TEST_ASSERT_OK(bundle_blob_.Init());
154     blob_store::BlobStore::BlobWriter blob_writer(bundle_blob(),
155                                                   metadata_buffer_);
156     PW_TEST_ASSERT_OK(blob_writer.Open());
157     PW_TEST_ASSERT_OK(blob_writer.Write(bundle_data));
158     PW_TEST_ASSERT_OK(blob_writer.Close());
159   }
160 
161   // A helper to verify that all bundle operations are disallowed because
162   // the bundle is not open or verified.
VerifyAllBundleOperationsDisallowed(UpdateBundleAccessor & update_bundle)163   void VerifyAllBundleOperationsDisallowed(
164       UpdateBundleAccessor& update_bundle) {
165     // We need to check specificially that failure is due to rejecting
166     // unverified/unopen bundle, not anything else.
167     ASSERT_EQ(update_bundle.GetManifest().status(),
168               Status::FailedPrecondition());
169     ASSERT_EQ(update_bundle.GetTargetPayload("any").status(),
170               Status::FailedPrecondition());
171     ASSERT_EQ(update_bundle.GetTargetPayload(protobuf::String({})).status(),
172               Status::FailedPrecondition());
173     ASSERT_EQ(update_bundle.PersistManifest(), Status::FailedPrecondition());
174     ASSERT_EQ(update_bundle.GetTotalPayloadSize().status(),
175               Status::FailedPrecondition());
176   }
177 
178   // A helper to verify that UpdateBundleAccessor::OpenAndVerify() fails and
179   // that all bundle operations are disallowed as a result. Also check whether
180   // root metadata should be expected to be persisted.
CheckOpenAndVerifyFail(UpdateBundleAccessor & update_bundle,bool expect_new_root_persisted)181   void CheckOpenAndVerifyFail(UpdateBundleAccessor& update_bundle,
182                               bool expect_new_root_persisted) {
183     ASSERT_FALSE(backend().IsNewRootPersisted());
184     ASSERT_FAIL(update_bundle.OpenAndVerify());
185     ASSERT_EQ(backend().IsNewRootPersisted(), expect_new_root_persisted);
186     VerifyAllBundleOperationsDisallowed(update_bundle);
187 
188     PW_TEST_ASSERT_OK(update_bundle.Close());
189     VerifyAllBundleOperationsDisallowed(update_bundle);
190   }
191 
192  private:
193   kvs::FakeFlashMemoryBuffer<kSectorSize, kSectorCount> blob_flash_;
194   kvs::FlashPartition blob_partition_;
195   blob_store::BlobStoreBuffer<kBufferSize> bundle_blob_;
196   BlobStoreOpenableReader blob_reader_;
197   std::array<std::byte, kMetadataBufferSize> metadata_buffer_;
198   TestBundledUpdateBackend backend_;
199 };
200 
201 }  // namespace
202 
TEST_F(UpdateBundleTest,GetTargetPayload)203 TEST_F(UpdateBundleTest, GetTargetPayload) {
204   backend().SetTrustedRoot(kDevSignedRoot);
205   StageTestBundle(kTestDevBundle);
206   UpdateBundleAccessor update_bundle(blob_reader(), backend());
207 
208   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
209 
210   {
211     stream::IntervalReader res = update_bundle.GetTargetPayload("file1");
212     PW_TEST_ASSERT_OK(res.status());
213 
214     const char kExpectedContent[] = "file 1 content";
215     char read_buffer[sizeof(kExpectedContent) + 1] = {0};
216     ASSERT_TRUE(res.Read(read_buffer, sizeof(kExpectedContent)).ok());
217     ASSERT_STREQ(read_buffer, kExpectedContent);
218   }
219 
220   {
221     stream::IntervalReader res = update_bundle.GetTargetPayload("file2");
222     PW_TEST_ASSERT_OK(res.status());
223 
224     const char kExpectedContent[] = "file 2 content";
225     char read_buffer[sizeof(kExpectedContent) + 1] = {0};
226     ASSERT_TRUE(res.Read(read_buffer, sizeof(kExpectedContent)).ok());
227     ASSERT_STREQ(read_buffer, kExpectedContent);
228   }
229 
230   {
231     stream::IntervalReader res = update_bundle.GetTargetPayload("non-exist");
232     ASSERT_EQ(res.status(), Status::NotFound());
233   }
234 }
235 
TEST_F(UpdateBundleTest,PersistManifest)236 TEST_F(UpdateBundleTest, PersistManifest) {
237   backend().SetTrustedRoot(kDevSignedRoot);
238   StageTestBundle(kTestDevBundle);
239   UpdateBundleAccessor update_bundle(blob_reader(), backend());
240 
241   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
242 
243   std::byte manifest_buffer[sizeof(kTestBundleManifest)] = {};
244   stream::MemoryWriter manifest_writer(manifest_buffer);
245   backend().SetManifestWriter(&manifest_writer);
246   ASSERT_FALSE(backend().BeforeManifestWriteCalled());
247   ASSERT_FALSE(backend().AfterManifestWriteCalled());
248   PW_TEST_ASSERT_OK(update_bundle.PersistManifest());
249   ASSERT_TRUE(backend().BeforeManifestWriteCalled());
250   ASSERT_TRUE(backend().AfterManifestWriteCalled());
251 
252   ASSERT_EQ(
253       memcmp(manifest_buffer, kTestBundleManifest, sizeof(kTestBundleManifest)),
254       0);
255 }
256 
TEST_F(UpdateBundleTest,PersistManifestFailIfNotVerified)257 TEST_F(UpdateBundleTest, PersistManifestFailIfNotVerified) {
258   backend().SetTrustedRoot(kDevSignedRoot);
259   StageTestBundle(kTestBadProdSignature);
260   UpdateBundleAccessor update_bundle(blob_reader(), backend());
261 
262   ASSERT_FAIL(update_bundle.OpenAndVerify());
263 
264   std::byte manifest_buffer[sizeof(kTestBundleManifest)];
265   stream::MemoryWriter manifest_writer(manifest_buffer);
266   backend().SetManifestWriter(&manifest_writer);
267   ASSERT_FALSE(backend().BeforeManifestWriteCalled());
268   ASSERT_FALSE(backend().AfterManifestWriteCalled());
269   ASSERT_FAIL(update_bundle.PersistManifest());
270   ASSERT_FALSE(backend().BeforeManifestWriteCalled());
271   ASSERT_FALSE(backend().AfterManifestWriteCalled());
272 }
273 
TEST_F(UpdateBundleTest,SelfVerificationWithIncomingRoot)274 TEST_F(UpdateBundleTest, SelfVerificationWithIncomingRoot) {
275   StageTestBundle(kTestDevBundleWithRoot);
276   UpdateBundleAccessor update_bundle(
277       blob_reader(), backend(), /* self_verification = */ true);
278 
279   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
280   // Self verification must not persist anything.
281   ASSERT_FALSE(backend().IsNewRootPersisted());
282 
283   // Manifest persisting should be allowed as well.
284   std::byte manifest_buffer[sizeof(kTestBundleManifest)];
285   stream::MemoryWriter manifest_writer(manifest_buffer);
286   backend().SetManifestWriter(&manifest_writer);
287   PW_TEST_ASSERT_OK(update_bundle.PersistManifest());
288 
289   ASSERT_EQ(
290       memcmp(manifest_buffer, kTestBundleManifest, sizeof(kTestBundleManifest)),
291       0);
292 }
293 
TEST_F(UpdateBundleTest,SelfVerificationWithoutIncomingRoot)294 TEST_F(UpdateBundleTest, SelfVerificationWithoutIncomingRoot) {
295   StageTestBundle(kTestDevBundle);
296   UpdateBundleAccessor update_bundle(
297       blob_reader(), backend(), /* self_verification = */ true);
298 
299   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
300 }
301 
TEST_F(UpdateBundleTest,SelfVerificationWithMessedUpRoot)302 TEST_F(UpdateBundleTest, SelfVerificationWithMessedUpRoot) {
303   StageTestBundle(kTestDevBundleWithProdRoot);
304   UpdateBundleAccessor update_bundle(
305       blob_reader(), backend(), /* self_verification = */ true);
306 
307   ASSERT_FAIL(update_bundle.OpenAndVerify());
308 }
309 
TEST_F(UpdateBundleTest,SelfVerificationChecksMissingHashes)310 TEST_F(UpdateBundleTest, SelfVerificationChecksMissingHashes) {
311   StageTestBundle(kTestBundleMissingTargetHashFile0);
312   UpdateBundleAccessor update_bundle(
313       blob_reader(), backend(), /* self_verification = */ true);
314 
315   ASSERT_FAIL(update_bundle.OpenAndVerify());
316 }
317 
TEST_F(UpdateBundleTest,SelfVerificationChecksBadHashes)318 TEST_F(UpdateBundleTest, SelfVerificationChecksBadHashes) {
319   StageTestBundle(kTestBundleMismatchedTargetHashFile0);
320   UpdateBundleAccessor update_bundle(
321       blob_reader(), backend(), /* self_verification = */ true);
322 
323   ASSERT_FAIL(update_bundle.OpenAndVerify());
324 }
325 
TEST_F(UpdateBundleTest,SelfVerificationIgnoresUnsignedBundle)326 TEST_F(UpdateBundleTest, SelfVerificationIgnoresUnsignedBundle) {
327   StageTestBundle(kTestUnsignedBundleWithRoot);
328   UpdateBundleAccessor update_bundle(
329       blob_reader(), backend(), /* self_verification = */ true);
330 
331   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
332 }
333 
TEST_F(UpdateBundleTest,OpenAndVerifySucceedsWithAllVerification)334 TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithAllVerification) {
335   backend().SetTrustedRoot(kDevSignedRoot);
336   backend().SetCurrentManifest(kTestBundleManifest);
337   StageTestBundle(kTestProdBundle);
338   UpdateBundleAccessor update_bundle(blob_reader(), backend());
339 
340   ASSERT_FALSE(backend().IsNewRootPersisted());
341   ASSERT_FALSE(backend().BeforeManifestReadCalled());
342   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
343   ASSERT_TRUE(backend().IsNewRootPersisted());
344   ASSERT_TRUE(backend().BeforeManifestReadCalled());
345 
346   PW_TEST_ASSERT_OK(update_bundle.Close());
347   VerifyAllBundleOperationsDisallowed(update_bundle);
348 }
349 
TEST_F(UpdateBundleTest,OpenAndVerifyWithoutIncomingRootSucceedsWithAllVerification)350 TEST_F(UpdateBundleTest,
351        OpenAndVerifyWithoutIncomingRootSucceedsWithAllVerification) {
352   backend().SetTrustedRoot(kDevSignedRoot);
353   backend().SetCurrentManifest(kTestBundleManifest);
354   // kTestDevBundle does not contain an incoming root. See
355   // pw_software_update/py/pw_software_update/generate_test_bundle.py for
356   // detail of generation.
357   StageTestBundle(kTestDevBundle);
358   UpdateBundleAccessor update_bundle(blob_reader(), backend());
359 
360   ASSERT_FALSE(backend().IsNewRootPersisted());
361   ASSERT_FALSE(backend().BeforeManifestReadCalled());
362   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
363   ASSERT_FALSE(backend().IsNewRootPersisted());
364   ASSERT_TRUE(backend().BeforeManifestReadCalled());
365 
366   PW_TEST_ASSERT_OK(update_bundle.Close());
367   VerifyAllBundleOperationsDisallowed(update_bundle);
368 }
369 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMismatchedRootKeyAndSignature)370 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedRootKeyAndSignature) {
371   backend().SetTrustedRoot(kDevSignedRoot);
372   backend().SetCurrentManifest(kTestBundleManifest);
373   // kTestMismatchedRootKeyAndSignature has a dev root metadata that is
374   // prod signed. The root metadata will not be able to verify itself.
375   // See pw_software_update/py/pw_software_update/generate_test_bundle.py for
376   // detail of generation.
377   StageTestBundle(kTestMismatchedRootKeyAndSignature);
378   UpdateBundleAccessor update_bundle(blob_reader(), backend());
379   CheckOpenAndVerifyFail(update_bundle, false);
380 }
381 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnBadProdSignature)382 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBadProdSignature) {
383   backend().SetTrustedRoot(kDevSignedRoot);
384   backend().SetCurrentManifest(kTestBundleManifest);
385   StageTestBundle(kTestBadProdSignature);
386   UpdateBundleAccessor update_bundle(blob_reader(), backend());
387   CheckOpenAndVerifyFail(update_bundle, false);
388 }
389 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnBadTargetsSignature)390 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBadTargetsSignature) {
391   backend().SetTrustedRoot(kDevSignedRoot);
392   backend().SetCurrentManifest(kTestBundleManifest);
393   StageTestBundle(kTestBadTargetsSignature);
394   UpdateBundleAccessor update_bundle(blob_reader(), backend());
395   CheckOpenAndVerifyFail(update_bundle, true);
396 }
397 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnBadTargetsRollBack)398 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBadTargetsRollBack) {
399   backend().SetTrustedRoot(kDevSignedRoot);
400   backend().SetCurrentManifest(kTestBundleManifest);
401   StageTestBundle(kTestTargetsRollback);
402   UpdateBundleAccessor update_bundle(blob_reader(), backend());
403   CheckOpenAndVerifyFail(update_bundle, true);
404 }
405 
TEST_F(UpdateBundleTest,OpenAndVerifySucceedsWithoutExistingManifest)406 TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithoutExistingManifest) {
407   backend().SetTrustedRoot(kDevSignedRoot);
408   StageTestBundle(kTestProdBundle);
409   UpdateBundleAccessor update_bundle(blob_reader(), backend());
410 
411   ASSERT_FALSE(backend().IsNewRootPersisted());
412   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
413   ASSERT_TRUE(backend().IsNewRootPersisted());
414 }
415 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnRootRollback)416 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnRootRollback) {
417   backend().SetTrustedRoot(kDevSignedRoot);
418   backend().SetCurrentManifest(kTestBundleManifest);
419   StageTestBundle(kTestRootRollback);
420   UpdateBundleAccessor update_bundle(blob_reader(), backend());
421   CheckOpenAndVerifyFail(update_bundle, false);
422 }
423 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMismatchedTargetHashFile0)424 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetHashFile0) {
425   backend().SetTrustedRoot(kDevSignedRoot);
426   backend().SetCurrentManifest(kTestBundleManifest);
427   // `kTestBundleMismatchedTargetHashFile0` is auto generated by
428   // pw_software_update/py/pw_software_update/generate_test_bundle.py.
429   // The hash value for file 0 in the targets metadata is made incorrect.
430   StageTestBundle(kTestBundleMismatchedTargetHashFile0);
431   UpdateBundleAccessor update_bundle(blob_reader(), backend());
432   CheckOpenAndVerifyFail(update_bundle, true);
433 }
434 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMismatchedTargetHashFile1)435 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetHashFile1) {
436   backend().SetTrustedRoot(kDevSignedRoot);
437   backend().SetCurrentManifest(kTestBundleManifest);
438   // `kTestBundleMismatchedTargetHashFile1` is auto generated by
439   // pw_software_update/py/pw_software_update/generate_test_bundle.py
440   // The hash value for file 1 in the targets metadata is made incorrect.
441   StageTestBundle(kTestBundleMismatchedTargetHashFile1);
442   UpdateBundleAccessor update_bundle(blob_reader(), backend());
443   CheckOpenAndVerifyFail(update_bundle, true);
444 }
445 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMissingTargetHashFile0)446 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMissingTargetHashFile0) {
447   backend().SetTrustedRoot(kDevSignedRoot);
448   backend().SetCurrentManifest(kTestBundleManifest);
449   // `kTestBundleMismatchedTargetHashFile0` is auto generated by
450   // pw_software_update/py/pw_software_update/generate_test_bundle.py.
451   // The hash value for file 0 is removed.
452   StageTestBundle(kTestBundleMissingTargetHashFile0);
453   UpdateBundleAccessor update_bundle(blob_reader(), backend());
454   CheckOpenAndVerifyFail(update_bundle, true);
455 }
456 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMissingTargetHashFile1)457 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMissingTargetHashFile1) {
458   backend().SetTrustedRoot(kDevSignedRoot);
459   backend().SetCurrentManifest(kTestBundleManifest);
460   // `kTestBundleMismatchedTargetHashFile1` is auto generated by
461   // pw_software_update/py/pw_software_update/generate_test_bundle.py
462   // The hash value for file 1 is removed.
463   StageTestBundle(kTestBundleMissingTargetHashFile1);
464   UpdateBundleAccessor update_bundle(blob_reader(), backend());
465   CheckOpenAndVerifyFail(update_bundle, true);
466 }
467 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMismatchedTargetLengthFile0)468 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetLengthFile0) {
469   backend().SetTrustedRoot(kDevSignedRoot);
470   backend().SetCurrentManifest(kTestBundleManifest);
471   // `kTestBundleMismatchedTargetLengthFile0` is auto generated by
472   // pw_software_update/py/pw_software_update/generate_test_bundle.py.
473   // The length value for file 0 in the targets metadata is made incorrect (1).
474   StageTestBundle(kTestBundleMismatchedTargetLengthFile0);
475   UpdateBundleAccessor update_bundle(blob_reader(), backend());
476   CheckOpenAndVerifyFail(update_bundle, true);
477 }
478 
TEST_F(UpdateBundleTest,OpenAndVerifyFailsOnMismatchedTargetLengthFile1)479 TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetLengthFile1) {
480   backend().SetTrustedRoot(kDevSignedRoot);
481   backend().SetCurrentManifest(kTestBundleManifest);
482   // `kTestBundleMismatchedTargetLengthFile1` is auto generated by
483   // pw_software_update/py/pw_software_update/generate_test_bundle.py.
484   // The length value for file 0 in the targets metadata is made incorrect (1).
485   StageTestBundle(kTestBundleMismatchedTargetLengthFile1);
486   UpdateBundleAccessor update_bundle(blob_reader(), backend());
487   CheckOpenAndVerifyFail(update_bundle, true);
488 }
489 
TEST_F(UpdateBundleTest,OpenAndVerifySucceedsWithPersonalizedOutFile0)490 TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithPersonalizedOutFile0) {
491   backend().SetTrustedRoot(kDevSignedRoot);
492   backend().SetCurrentManifest(kTestBundleManifest);
493   // `kTestBundlePersonalizedOutFile0` is auto generated by
494   // pw_software_update/py/pw_software_update/generate_test_bundle.py
495   // The payload for file 0 is removed from the bundle to emulate being
496   // personalized out.
497   StageTestBundle(kTestBundlePersonalizedOutFile0);
498   UpdateBundleAccessor update_bundle(blob_reader(), backend());
499 
500   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
501 }
502 
TEST_F(UpdateBundleTest,OpenAndVerifySucceedsWithPersonalizedOutFile1)503 TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithPersonalizedOutFile1) {
504   backend().SetTrustedRoot(kDevSignedRoot);
505   backend().SetCurrentManifest(kTestBundleManifest);
506   // `kTestBundlePersonalizedOutFile1` is auto generated by
507   // pw_software_update/py/pw_software_update/generate_test_bundle.py
508   // The payload for file 1 is removed from the bundle to emulate being
509   // personalized out.
510   StageTestBundle(kTestBundlePersonalizedOutFile1);
511   UpdateBundleAccessor update_bundle(blob_reader(), backend());
512 
513   PW_TEST_ASSERT_OK(update_bundle.OpenAndVerify());
514 }
515 
TEST_F(UpdateBundleTest,PersonalizationVerificationFailsWithoutDeviceManifest)516 TEST_F(UpdateBundleTest,
517        PersonalizationVerificationFailsWithoutDeviceManifest) {
518   backend().SetTrustedRoot(kDevSignedRoot);
519   // `kTestBundlePersonalizedOutFile0` is auto generated by
520   // pw_software_update/py/pw_software_update/generate_test_bundle.py
521   // The payload for file 0 is removed from the bundle to emulate being
522   // personalized out.
523   StageTestBundle(kTestBundlePersonalizedOutFile0);
524   UpdateBundleAccessor update_bundle(blob_reader(), backend());
525 
526   ASSERT_FAIL(update_bundle.OpenAndVerify());
527 }
528 
529 }  // namespace pw::software_update
530