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