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