blob: 83b5b151d8f136aa6f353dc7adc216f6b2349d83 [file] [log] [blame]
Yecheng Zhao637b7732021-08-23 22:45:40 -07001// 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
Yecheng Zhaoc2b93792021-09-21 18:36:59 -070015#include <array>
16
Yecheng Zhao637b7732021-08-23 22:45:40 -070017#include "gtest/gtest.h"
18#include "pw_kvs/fake_flash_memory.h"
19#include "pw_kvs/test_key_value_store.h"
Yecheng Zhaoc2b93792021-09-21 18:36:59 -070020#include "pw_software_update/bundled_update_backend.h"
Yecheng Zhaoef6917c2021-10-27 14:11:24 -070021#include "pw_software_update/update_bundle_accessor.h"
22#include "pw_stream/memory_stream.h"
Yecheng Zhao604695e2021-09-17 09:55:49 -070023#include "test_bundles.h"
24
25#define ASSERT_OK(status) ASSERT_EQ(OkStatus(), status)
Yecheng Zhao28072eb2021-10-29 15:37:06 -070026#define ASSERT_NOT_OK(status) ASSERT_NE(OkStatus(), status)
Yecheng Zhao637b7732021-08-23 22:45:40 -070027
28namespace pw::software_update {
29namespace {
30
31constexpr size_t kBufferSize = 256;
32static constexpr size_t kFlashAlignment = 16;
33constexpr size_t kSectorSize = 2048;
34constexpr size_t kSectorCount = 2;
Yecheng Zhaoc2b93792021-09-21 18:36:59 -070035constexpr size_t kMetadataBufferSize =
36 blob_store::BlobStore::BlobWriter::RequiredMetadataBufferSize(0);
37
38class TestBundledUpdateBackend final : public BundledUpdateBackend {
39 public:
Yecheng Zhaoed735e12021-11-09 15:04:24 -080040 TestBundledUpdateBackend()
Yecheng Zhao50262fe2021-12-02 19:10:52 -080041 : current_manifest_reader_({}), trusted_root_memory_reader_({}) {}
Yecheng Zhaoef6917c2021-10-27 14:11:24 -070042
David Rogersc6d70ab2021-11-17 16:44:20 -080043 Status ApplyReboot() override { return Status::Unimplemented(); }
David Rogersb19d5862021-11-18 19:59:53 -080044 Status PostRebootFinalize() override { return OkStatus(); }
Yecheng Zhaoc2b93792021-09-21 18:36:59 -070045
Yecheng Zhaod0997572021-11-12 12:11:23 -080046 Status VerifyTargetFile(
Zihan Chen94552242021-12-13 17:54:27 -080047 [[maybe_unused]] ManifestAccessor manifest,
Yecheng Zhaod0997572021-11-12 12:11:23 -080048 [[maybe_unused]] std::string_view target_file_name) override {
49 backend_verified_files_++;
50 return verify_target_file_result_;
51 };
52
Yecheng Zhaoef6917c2021-10-27 14:11:24 -070053 Status ApplyTargetFile(std::string_view, stream::Reader&, size_t) override {
Yecheng Zhaoc2b93792021-09-21 18:36:59 -070054 return OkStatus();
55 }
Yecheng Zhaoa53cf132021-09-22 10:07:09 -070056
Yecheng Zhaoef6917c2021-10-27 14:11:24 -070057 Result<uint32_t> EnableBundleTransferHandler(std::string_view) override {
58 return 0;
59 }
Yecheng Zhaoa53cf132021-09-22 10:07:09 -070060
61 void DisableBundleTransferHandler() override {}
Yecheng Zhao28072eb2021-10-29 15:37:06 -070062
63 void SetTrustedRoot(ConstByteSpan trusted_root) {
Yecheng Zhao50262fe2021-12-02 19:10:52 -080064 trusted_root_memory_reader_ = stream::MemoryReader(trusted_root);
65 trusted_root_reader_ = stream::IntervalReader(
66 trusted_root_memory_reader_,
67 0,
68 trusted_root_memory_reader_.ConservativeReadLimit());
Yecheng Zhao28072eb2021-10-29 15:37:06 -070069 }
70
Yecheng Zhaoed735e12021-11-09 15:04:24 -080071 void SetCurrentManifest(ConstByteSpan current_manifest) {
72 current_manifest_reader_ = stream::MemoryReader(current_manifest);
73 }
74
Yecheng Zhao28072eb2021-10-29 15:37:06 -070075 virtual Result<stream::SeekableReader*> GetRootMetadataReader() override {
76 return &trusted_root_reader_;
77 };
78
Yecheng Zhaoed735e12021-11-09 15:04:24 -080079 virtual Result<stream::SeekableReader*> GetCurrentManifestReader() {
80 return &current_manifest_reader_;
81 }
82
Yecheng Zhao28072eb2021-10-29 15:37:06 -070083 virtual Status SafelyPersistRootMetadata(
Yecheng Zhao50262fe2021-12-02 19:10:52 -080084 [[maybe_unused]] stream::IntervalReader root_metadata) override {
Yecheng Zhao28072eb2021-10-29 15:37:06 -070085 new_root_persisted_ = true;
Yecheng Zhao50262fe2021-12-02 19:10:52 -080086 trusted_root_reader_ = root_metadata;
Yecheng Zhao28072eb2021-10-29 15:37:06 -070087 return OkStatus();
88 };
89
90 bool IsNewRootPersisted() const { return new_root_persisted_; }
91
Yecheng Zhaod0997572021-11-12 12:11:23 -080092 size_t NumFilesVerified() const { return backend_verified_files_; }
93
94 void SetVerifyTargetFileResult(Status status) {
95 verify_target_file_result_ = status;
96 }
97
Yecheng Zhao28072eb2021-10-29 15:37:06 -070098 private:
Yecheng Zhao50262fe2021-12-02 19:10:52 -080099 stream::IntervalReader trusted_root_reader_;
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800100 stream::MemoryReader current_manifest_reader_;
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700101 bool new_root_persisted_ = false;
Yecheng Zhaod0997572021-11-12 12:11:23 -0800102 size_t backend_verified_files_ = 0;
103 Status verify_target_file_result_ = OkStatus();
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800104
105 // A memory reader for buffer passed by SetTrustedRoot(). This will be used
106 // to back `trusted_root_reader_`
107 stream::MemoryReader trusted_root_memory_reader_;
Yecheng Zhaoc2b93792021-09-21 18:36:59 -0700108};
Yecheng Zhao637b7732021-08-23 22:45:40 -0700109
110class UpdateBundleTest : public testing::Test {
111 public:
112 UpdateBundleTest()
113 : blob_flash_(kFlashAlignment),
114 blob_partition_(&blob_flash_),
Zihan Chenf463acd2021-09-01 14:32:28 -0700115 bundle_blob_("TestBundle",
Yecheng Zhao637b7732021-08-23 22:45:40 -0700116 blob_partition_,
117 nullptr,
118 kvs::TestKvs(),
119 kBufferSize) {}
120
Zihan Chenf463acd2021-09-01 14:32:28 -0700121 blob_store::BlobStoreBuffer<kBufferSize>& bundle_blob() {
122 return bundle_blob_;
Yecheng Zhao637b7732021-08-23 22:45:40 -0700123 }
124
Yecheng Zhaoef6917c2021-10-27 14:11:24 -0700125 TestBundledUpdateBackend& backend() { return backend_; }
Yecheng Zhao637b7732021-08-23 22:45:40 -0700126
Yecheng Zhao604695e2021-09-17 09:55:49 -0700127 void StageTestBundle(ConstByteSpan bundle_data) {
128 ASSERT_OK(bundle_blob_.Init());
Yecheng Zhaoc2b93792021-09-21 18:36:59 -0700129 blob_store::BlobStore::BlobWriter blob_writer(bundle_blob(),
130 metadata_buffer_);
Yecheng Zhao604695e2021-09-17 09:55:49 -0700131 ASSERT_OK(blob_writer.Open());
132 ASSERT_OK(blob_writer.Write(bundle_data));
133 ASSERT_OK(blob_writer.Close());
134 }
135
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800136 // A helper to verify that all bundle operations are disallowed because
137 // the bundle is not open or verified.
138 void VerifyAllBundleOperationsDisallowed(
139 UpdateBundleAccessor& update_bundle) {
140 // We need to check specificially that failure is due to rejecting
141 // unverified/unopen bundle, not anything else.
142 ASSERT_EQ(update_bundle.GetDecoder().status(),
143 Status::FailedPrecondition());
144 ASSERT_EQ(update_bundle.GetTargetPayload("any").status(),
145 Status::FailedPrecondition());
146 ASSERT_EQ(update_bundle.IsTargetPayloadIncluded("any").status(),
147 Status::FailedPrecondition());
148
149 std::byte manifest_buffer[sizeof(kTestBundleManifest)];
150 stream::MemoryWriter manifest_writer(manifest_buffer);
151 ASSERT_EQ(update_bundle.PersistManifest(manifest_writer),
152 Status::FailedPrecondition());
153 }
154
155 // A helper to verify that UpdateBundleAccessor::OpenAndVerify() fails and
156 // that all bundle operations are disallowed as a result. Also check whether
157 // root metadata should be expected to be persisted.
158 void CheckOpenAndVerifyFail(UpdateBundleAccessor& update_bundle,
159 bool expect_new_root_persisted) {
160 ASSERT_FALSE(backend().IsNewRootPersisted());
Zihan Chen94552242021-12-13 17:54:27 -0800161 ASSERT_NOT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800162 ASSERT_EQ(backend().IsNewRootPersisted(), expect_new_root_persisted);
163 VerifyAllBundleOperationsDisallowed(update_bundle);
164
165 ASSERT_OK(update_bundle.Close());
166 VerifyAllBundleOperationsDisallowed(update_bundle);
167 }
168
Yecheng Zhao637b7732021-08-23 22:45:40 -0700169 private:
170 kvs::FakeFlashMemoryBuffer<kSectorSize, kSectorCount> blob_flash_;
171 kvs::FlashPartition blob_partition_;
Zihan Chenf463acd2021-09-01 14:32:28 -0700172 blob_store::BlobStoreBuffer<kBufferSize> bundle_blob_;
Yecheng Zhaoc2b93792021-09-21 18:36:59 -0700173 std::array<std::byte, kMetadataBufferSize> metadata_buffer_;
174 TestBundledUpdateBackend backend_;
Yecheng Zhao637b7732021-08-23 22:45:40 -0700175};
176
177} // namespace
178
Yecheng Zhao604695e2021-09-17 09:55:49 -0700179TEST_F(UpdateBundleTest, GetTargetPayload) {
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700180 backend().SetTrustedRoot(kDevSignedRoot);
181 StageTestBundle(kTestDevBundle);
Yecheng Zhaoef6917c2021-10-27 14:11:24 -0700182 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao604695e2021-09-17 09:55:49 -0700183
Zihan Chen94552242021-12-13 17:54:27 -0800184 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao604695e2021-09-17 09:55:49 -0700185
186 {
187 stream::IntervalReader res = update_bundle.GetTargetPayload("file1");
188 ASSERT_OK(res.status());
189
190 const char kExpectedContent[] = "file 1 content";
191 char read_buffer[sizeof(kExpectedContent) + 1] = {0};
192 ASSERT_TRUE(res.Read(read_buffer, sizeof(kExpectedContent)).ok());
193 ASSERT_STREQ(read_buffer, kExpectedContent);
194 }
195
196 {
197 stream::IntervalReader res = update_bundle.GetTargetPayload("file2");
198 ASSERT_OK(res.status());
199
200 const char kExpectedContent[] = "file 2 content";
201 char read_buffer[sizeof(kExpectedContent) + 1] = {0};
202 ASSERT_TRUE(res.Read(read_buffer, sizeof(kExpectedContent)).ok());
203 ASSERT_STREQ(read_buffer, kExpectedContent);
204 }
205
206 {
207 stream::IntervalReader res = update_bundle.GetTargetPayload("non-exist");
208 ASSERT_EQ(res.status(), Status::NotFound());
209 }
210}
211
212TEST_F(UpdateBundleTest, IsTargetPayloadIncluded) {
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700213 backend().SetTrustedRoot(kDevSignedRoot);
214 StageTestBundle(kTestDevBundle);
Yecheng Zhaoef6917c2021-10-27 14:11:24 -0700215 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao604695e2021-09-17 09:55:49 -0700216
Zihan Chen94552242021-12-13 17:54:27 -0800217 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao604695e2021-09-17 09:55:49 -0700218
219 Result<bool> res = update_bundle.IsTargetPayloadIncluded("file1");
220 ASSERT_OK(res.status());
221 ASSERT_TRUE(res.value());
222
223 res = update_bundle.IsTargetPayloadIncluded("file2");
224 ASSERT_OK(res.status());
225 ASSERT_TRUE(res.value());
226
227 res = update_bundle.IsTargetPayloadIncluded("non-exist");
228 ASSERT_OK(res.status());
229 ASSERT_FALSE(res.value());
230}
231
Yecheng Zhao3f758de2021-11-05 11:13:22 -0700232TEST_F(UpdateBundleTest, PersistManifest) {
233 backend().SetTrustedRoot(kDevSignedRoot);
234 StageTestBundle(kTestDevBundle);
235 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
236
Zihan Chen94552242021-12-13 17:54:27 -0800237 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao3f758de2021-11-05 11:13:22 -0700238
239 std::byte manifest_buffer[sizeof(kTestBundleManifest)];
240 stream::MemoryWriter manifest_writer(manifest_buffer);
241 ASSERT_OK(update_bundle.PersistManifest(manifest_writer));
242
243 ASSERT_EQ(
244 memcmp(manifest_buffer, kTestBundleManifest, sizeof(kTestBundleManifest)),
245 0);
246}
247
248TEST_F(UpdateBundleTest, PersistManifestFailIfNotVerified) {
249 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800250 StageTestBundle(kTestBadProdSignature);
Yecheng Zhao3f758de2021-11-05 11:13:22 -0700251 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
252
Zihan Chen94552242021-12-13 17:54:27 -0800253 ASSERT_NOT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao3f758de2021-11-05 11:13:22 -0700254
255 std::byte manifest_buffer[sizeof(kTestBundleManifest)];
256 stream::MemoryWriter manifest_writer(manifest_buffer);
257 ASSERT_NOT_OK(update_bundle.PersistManifest(manifest_writer));
258}
259
260TEST_F(UpdateBundleTest, BundleVerificationDisabled) {
261 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800262 StageTestBundle(kTestBadProdSignature);
Yecheng Zhao3f758de2021-11-05 11:13:22 -0700263 UpdateBundleAccessor update_bundle(bundle_blob(), backend(), true);
264
265 // Since bundle verification is disabled. The bad bundle should not report
266 // error.
Zihan Chen94552242021-12-13 17:54:27 -0800267 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao3f758de2021-11-05 11:13:22 -0700268
269 // Manifest persisting should be allowed as well.
270 std::byte manifest_buffer[sizeof(kTestBundleManifest)];
271 stream::MemoryWriter manifest_writer(manifest_buffer);
272 ASSERT_OK(update_bundle.PersistManifest(manifest_writer));
273
274 ASSERT_EQ(
275 memcmp(manifest_buffer, kTestBundleManifest, sizeof(kTestBundleManifest)),
276 0);
277}
278
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800279TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithAllVerification) {
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700280 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800281 backend().SetCurrentManifest(kTestBundleManifest);
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700282 StageTestBundle(kTestProdBundle);
283 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
284
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700285 ASSERT_FALSE(backend().IsNewRootPersisted());
Zihan Chen94552242021-12-13 17:54:27 -0800286 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700287 ASSERT_TRUE(backend().IsNewRootPersisted());
Yecheng Zhaod0997572021-11-12 12:11:23 -0800288
289 // No file is personalized out in kTestProdBundle. Backend verification
290 // should not be invoked.
291 ASSERT_EQ(backend().NumFilesVerified(), static_cast<size_t>(0));
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800292
293 ASSERT_OK(update_bundle.Close());
294 VerifyAllBundleOperationsDisallowed(update_bundle);
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700295}
296
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800297TEST_F(UpdateBundleTest,
298 OpenAndVerifyWithoutIncomingRootSucceedsWithAllVerification) {
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700299 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800300 backend().SetCurrentManifest(kTestBundleManifest);
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800301 // kTestDevBundle does not contain an incoming root. See
302 // pw_software_update/py/pw_software_update/generate_test_bundle.py for
303 // detail of generation.
304 StageTestBundle(kTestDevBundle);
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700305 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
306
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700307 ASSERT_FALSE(backend().IsNewRootPersisted());
Zihan Chen94552242021-12-13 17:54:27 -0800308 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700309 ASSERT_FALSE(backend().IsNewRootPersisted());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800310
311 // No file is personalized out in kTestDevBundle. Backend verification
312 // should not be invoked.
313 ASSERT_EQ(backend().NumFilesVerified(), static_cast<size_t>(0));
314
315 ASSERT_OK(update_bundle.Close());
316 VerifyAllBundleOperationsDisallowed(update_bundle);
317}
318
319TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedRootKeyAndSignature) {
320 backend().SetTrustedRoot(kDevSignedRoot);
321 backend().SetCurrentManifest(kTestBundleManifest);
322 // kTestMismatchedRootKeyAndSignature has a dev root metadata that is
323 // prod signed. The root metadata will not be able to verify itself.
324 // See pw_software_update/py/pw_software_update/generate_test_bundle.py for
325 // detail of generation.
326 StageTestBundle(kTestMismatchedRootKeyAndSignature);
327 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
328 CheckOpenAndVerifyFail(update_bundle, false);
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700329}
330
331TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBadProdSignature) {
332 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800333 backend().SetCurrentManifest(kTestBundleManifest);
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700334 StageTestBundle(kTestBadProdSignature);
335 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800336 CheckOpenAndVerifyFail(update_bundle, false);
Yecheng Zhao28072eb2021-10-29 15:37:06 -0700337}
338
Yecheng Zhao38fee792021-11-04 15:49:16 -0700339TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBadTargetsSignature) {
340 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800341 backend().SetCurrentManifest(kTestBundleManifest);
Yecheng Zhao38fee792021-11-04 15:49:16 -0700342 StageTestBundle(kTestBadTargetsSignature);
343 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800344 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhao38fee792021-11-04 15:49:16 -0700345}
346
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800347TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBadTargetsRollBack) {
348 backend().SetTrustedRoot(kDevSignedRoot);
349 backend().SetCurrentManifest(kTestBundleManifest);
350 StageTestBundle(kTestTargetsRollback);
351 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800352 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800353}
354
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800355TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithoutExistingManifest) {
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800356 backend().SetTrustedRoot(kDevSignedRoot);
357 StageTestBundle(kTestProdBundle);
358 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
359
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800360 ASSERT_FALSE(backend().IsNewRootPersisted());
Zihan Chen94552242021-12-13 17:54:27 -0800361 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800362 ASSERT_TRUE(backend().IsNewRootPersisted());
Yecheng Zhaoed735e12021-11-09 15:04:24 -0800363}
364
Yecheng Zhao16f00aa2021-11-09 15:55:21 -0800365TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnRootRollback) {
366 backend().SetTrustedRoot(kDevSignedRoot);
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800367 backend().SetCurrentManifest(kTestBundleManifest);
Yecheng Zhao16f00aa2021-11-09 15:55:21 -0800368 StageTestBundle(kTestRootRollback);
369 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800370 CheckOpenAndVerifyFail(update_bundle, false);
Yecheng Zhao16f00aa2021-11-09 15:55:21 -0800371}
372
Yecheng Zhaod0997572021-11-12 12:11:23 -0800373TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetHashFile0) {
374 backend().SetTrustedRoot(kDevSignedRoot);
375 backend().SetCurrentManifest(kTestBundleManifest);
376 // `kTestBundleMismatchedTargetHashFile0` is auto generated by
377 // pw_software_update/py/pw_software_update/generate_test_bundle.py.
378 // The hash value for file 0 in the targets metadata is made incorrect.
379 StageTestBundle(kTestBundleMismatchedTargetHashFile0);
380 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800381 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800382}
383
384TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetHashFile1) {
385 backend().SetTrustedRoot(kDevSignedRoot);
386 backend().SetCurrentManifest(kTestBundleManifest);
387 // `kTestBundleMismatchedTargetHashFile1` is auto generated by
388 // pw_software_update/py/pw_software_update/generate_test_bundle.py
389 // The hash value for file 1 in the targets metadata is made incorrect.
390 StageTestBundle(kTestBundleMismatchedTargetHashFile1);
391 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800392 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800393}
394
395TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMissingTargetHashFile0) {
396 backend().SetTrustedRoot(kDevSignedRoot);
397 backend().SetCurrentManifest(kTestBundleManifest);
398 // `kTestBundleMismatchedTargetHashFile0` is auto generated by
399 // pw_software_update/py/pw_software_update/generate_test_bundle.py.
400 // The hash value for file 0 is removed.
401 StageTestBundle(kTestBundleMissingTargetHashFile0);
402 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800403 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800404}
405
406TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMissingTargetHashFile1) {
407 backend().SetTrustedRoot(kDevSignedRoot);
408 backend().SetCurrentManifest(kTestBundleManifest);
409 // `kTestBundleMismatchedTargetHashFile1` is auto generated by
410 // pw_software_update/py/pw_software_update/generate_test_bundle.py
411 // The hash value for file 1 is removed.
412 StageTestBundle(kTestBundleMissingTargetHashFile1);
413 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800414 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800415}
416
417TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetLengthFile0) {
418 backend().SetTrustedRoot(kDevSignedRoot);
419 backend().SetCurrentManifest(kTestBundleManifest);
420 // `kTestBundleMismatchedTargetLengthFile0` is auto generated by
421 // pw_software_update/py/pw_software_update/generate_test_bundle.py.
422 // The length value for file 0 in the targets metadata is made incorrect (1).
423 StageTestBundle(kTestBundleMismatchedTargetLengthFile0);
424 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800425 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800426}
427
428TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnMismatchedTargetLengthFile1) {
429 backend().SetTrustedRoot(kDevSignedRoot);
430 backend().SetCurrentManifest(kTestBundleManifest);
431 // `kTestBundleMismatchedTargetLengthFile1` is auto generated by
432 // pw_software_update/py/pw_software_update/generate_test_bundle.py.
433 // The length value for file 0 in the targets metadata is made incorrect (1).
434 StageTestBundle(kTestBundleMismatchedTargetLengthFile1);
435 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800436 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800437}
438
439TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithPersonalizedOutFile0) {
440 backend().SetTrustedRoot(kDevSignedRoot);
441 backend().SetCurrentManifest(kTestBundleManifest);
442 // `kTestBundlePersonalizedOutFile0` is auto generated by
443 // pw_software_update/py/pw_software_update/generate_test_bundle.py
444 // The payload for file 0 is removed from the bundle to emulate being
445 // personalized out.
446 StageTestBundle(kTestBundlePersonalizedOutFile0);
447 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
448
Zihan Chen94552242021-12-13 17:54:27 -0800449 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhaod0997572021-11-12 12:11:23 -0800450 // Backend specific file check shall be performed only on files personalized
451 // out.
452 ASSERT_EQ(backend().NumFilesVerified(), static_cast<size_t>(1));
453}
454
455TEST_F(UpdateBundleTest, OpenAndVerifySucceedsWithPersonalizedOutFile1) {
456 backend().SetTrustedRoot(kDevSignedRoot);
457 backend().SetCurrentManifest(kTestBundleManifest);
458 // `kTestBundlePersonalizedOutFile1` is auto generated by
459 // pw_software_update/py/pw_software_update/generate_test_bundle.py
460 // The payload for file 1 is removed from the bundle to emulate being
461 // personalized out.
462 StageTestBundle(kTestBundlePersonalizedOutFile1);
463 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
464
Zihan Chen94552242021-12-13 17:54:27 -0800465 ASSERT_OK(update_bundle.OpenAndVerify());
Yecheng Zhaod0997572021-11-12 12:11:23 -0800466 // Backend specific file check shall be performed only on files personalized
467 // out.
468 ASSERT_EQ(backend().NumFilesVerified(), static_cast<size_t>(1));
469}
470
471TEST_F(UpdateBundleTest, OpenAndVerifyFailsOnBackendVerification) {
472 backend().SetTrustedRoot(kDevSignedRoot);
473 backend().SetCurrentManifest(kTestBundleManifest);
474 StageTestBundle(kTestBundlePersonalizedOutFile1);
475 UpdateBundleAccessor update_bundle(bundle_blob(), backend());
476 backend().SetVerifyTargetFileResult(Status::Internal());
Yecheng Zhao50262fe2021-12-02 19:10:52 -0800477 CheckOpenAndVerifyFail(update_bundle, true);
Yecheng Zhaod0997572021-11-12 12:11:23 -0800478}
Yecheng Zhaoafa51372021-12-15 11:58:48 -0800479
Yecheng Zhao637b7732021-08-23 22:45:40 -0700480} // namespace pw::software_update