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