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