1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "update_engine/payload_consumer/delta_performer.h"
18
19 #include <inttypes.h>
20 #include <sys/mount.h>
21
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25
26 #include <base/files/file_path.h>
27 #include <base/files/file_util.h>
28 #include <base/stl_util.h>
29 #include <base/strings/string_util.h>
30 #include <base/strings/stringprintf.h>
31 #include <gmock/gmock-matchers.h>
32 #include <google/protobuf/repeated_field.h>
33 #include <gtest/gtest.h>
34 #include <openssl/pem.h>
35
36 #include "update_engine/common/constants.h"
37 #include "update_engine/common/fake_boot_control.h"
38 #include "update_engine/common/fake_hardware.h"
39 #include "update_engine/common/mock_prefs.h"
40 #include "update_engine/common/test_utils.h"
41 #include "update_engine/common/utils.h"
42 #include "update_engine/payload_consumer/mock_download_action.h"
43 #include "update_engine/payload_consumer/payload_constants.h"
44 #include "update_engine/payload_consumer/payload_metadata.h"
45 #include "update_engine/payload_consumer/payload_verifier.h"
46 #include "update_engine/payload_generator/delta_diff_generator.h"
47 #include "update_engine/payload_generator/payload_signer.h"
48 #include "update_engine/update_metadata.pb.h"
49
50 namespace chromeos_update_engine {
51
52 using std::string;
53 using std::vector;
54 using test_utils::GetBuildArtifactsPath;
55 using test_utils::kRandomString;
56 using test_utils::ScopedLoopMounter;
57 using test_utils::System;
58 using testing::_;
59 using testing::Return;
60
61 extern const char* kUnittestPrivateKeyPath;
62 extern const char* kUnittestPublicKeyPath;
63 extern const char* kUnittestPrivateKey2Path;
64 extern const char* kUnittestPublicKey2Path;
65 extern const char* kUnittestPrivateKeyECPath;
66 extern const char* kUnittestPublicKeyECPath;
67
68 static const uint32_t kDefaultKernelSize = 4096; // Something small for a test
69 // clang-format off
70 static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
71 'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
72 // clang-format on
73
74 namespace {
75 struct DeltaState {
76 string a_img;
77 string b_img;
78 string result_img;
79 size_t image_size;
80
81 string delta_path;
82 uint64_t metadata_size;
83 uint32_t metadata_signature_size;
84
85 string old_kernel;
86 brillo::Blob old_kernel_data;
87
88 string new_kernel;
89 brillo::Blob new_kernel_data;
90
91 string result_kernel;
92 brillo::Blob result_kernel_data;
93 size_t kernel_size;
94
95 // The InstallPlan referenced by the DeltaPerformer. This needs to outlive
96 // the DeltaPerformer.
97 InstallPlan install_plan;
98
99 // The in-memory copy of delta file.
100 brillo::Blob delta;
101
102 // Mock and fake instances used by the delta performer.
103 FakeBootControl fake_boot_control_;
104 FakeHardware fake_hardware_;
105 MockDownloadActionDelegate mock_delegate_;
106 };
107
108 enum SignatureTest {
109 kSignatureNone, // No payload signing.
110 kSignatureGenerator, // Sign the payload at generation time.
111 kSignatureGenerated, // Sign the payload after it's generated.
112 kSignatureGeneratedPlaceholder, // Insert placeholder signatures, then real.
113 kSignatureGeneratedPlaceholderMismatch, // Insert a wrong sized placeholder.
114 kSignatureGeneratedShell, // Sign the generated payload through shell cmds.
115 kSignatureGeneratedShellECKey, // Sign with a EC key through shell cmds.
116 kSignatureGeneratedShellBadKey, // Sign with a bad key through shell cmds.
117 kSignatureGeneratedShellRotateCl1, // Rotate key, test client v1
118 kSignatureGeneratedShellRotateCl2, // Rotate key, test client v2
119 };
120
121 enum OperationHashTest {
122 kInvalidOperationData,
123 kValidOperationData,
124 };
125
126 } // namespace
127
128 class DeltaPerformerIntegrationTest : public ::testing::Test {};
129
CompareFilesByBlock(const string & a_file,const string & b_file,size_t image_size)130 static void CompareFilesByBlock(const string& a_file,
131 const string& b_file,
132 size_t image_size) {
133 EXPECT_EQ(0U, image_size % kBlockSize);
134
135 brillo::Blob a_data, b_data;
136 EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
137 EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
138
139 EXPECT_GE(a_data.size(), image_size);
140 EXPECT_GE(b_data.size(), image_size);
141 for (size_t i = 0; i < image_size; i += kBlockSize) {
142 EXPECT_EQ(0U, i % kBlockSize);
143 brillo::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
144 brillo::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
145 EXPECT_TRUE(a_sub == b_sub) << "Block " << (i / kBlockSize) << " differs";
146 }
147 if (::testing::Test::HasNonfatalFailure()) {
148 LOG(INFO) << "Compared filesystems with size " << image_size
149 << ", partition A " << a_file << " size: " << a_data.size()
150 << ", partition B " << b_file << " size: " << b_data.size();
151 }
152 }
153
WriteSparseFile(const string & path,off_t size)154 static bool WriteSparseFile(const string& path, off_t size) {
155 int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
156 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
157 ScopedFdCloser fd_closer(&fd);
158 off_t rc = lseek(fd, size + 1, SEEK_SET);
159 TEST_AND_RETURN_FALSE_ERRNO(rc != static_cast<off_t>(-1));
160 int return_code = ftruncate(fd, size);
161 TEST_AND_RETURN_FALSE_ERRNO(return_code == 0);
162 return true;
163 }
164
WriteByteAtOffset(const string & path,off_t offset)165 static bool WriteByteAtOffset(const string& path, off_t offset) {
166 int fd = open(path.c_str(), O_CREAT | O_WRONLY, 0644);
167 TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
168 ScopedFdCloser fd_closer(&fd);
169 EXPECT_TRUE(utils::PWriteAll(fd, "\0", 1, offset));
170 return true;
171 }
172
InsertSignaturePlaceholder(size_t signature_size,const string & payload_path,uint64_t * out_metadata_size)173 static bool InsertSignaturePlaceholder(size_t signature_size,
174 const string& payload_path,
175 uint64_t* out_metadata_size) {
176 vector<brillo::Blob> signatures;
177 signatures.push_back(brillo::Blob(signature_size, 0));
178
179 return PayloadSigner::AddSignatureToPayload(payload_path,
180 {signature_size},
181 signatures,
182 {},
183 payload_path,
184 out_metadata_size);
185 }
186
SignGeneratedPayload(const string & payload_path,uint64_t * out_metadata_size)187 static void SignGeneratedPayload(const string& payload_path,
188 uint64_t* out_metadata_size) {
189 string private_key_path = GetBuildArtifactsPath(kUnittestPrivateKeyPath);
190 size_t signature_size;
191 ASSERT_TRUE(PayloadSigner::GetMaximumSignatureSize(private_key_path,
192 &signature_size));
193 brillo::Blob metadata_hash, payload_hash;
194 ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
195 payload_path, {signature_size}, &payload_hash, &metadata_hash));
196 brillo::Blob metadata_signature, payload_signature;
197 ASSERT_TRUE(PayloadSigner::SignHash(
198 payload_hash, private_key_path, &payload_signature));
199 ASSERT_TRUE(PayloadSigner::SignHash(
200 metadata_hash, private_key_path, &metadata_signature));
201 ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(payload_path,
202 {signature_size},
203 {payload_signature},
204 {metadata_signature},
205 payload_path,
206 out_metadata_size));
207 EXPECT_TRUE(PayloadSigner::VerifySignedPayload(
208 payload_path, GetBuildArtifactsPath(kUnittestPublicKeyPath)));
209 }
210
SignGeneratedShellPayloadWithKeys(const string & payload_path,const vector<string> & private_key_paths,const string & public_key_path,bool verification_success)211 static void SignGeneratedShellPayloadWithKeys(
212 const string& payload_path,
213 const vector<string>& private_key_paths,
214 const string& public_key_path,
215 bool verification_success) {
216 vector<string> signature_size_strings;
217 for (const auto& key_path : private_key_paths) {
218 size_t signature_size;
219 ASSERT_TRUE(
220 PayloadSigner::GetMaximumSignatureSize(key_path, &signature_size));
221 signature_size_strings.push_back(base::StringPrintf("%zu", signature_size));
222 }
223 string signature_size_string = base::JoinString(signature_size_strings, ":");
224
225 test_utils::ScopedTempFile hash_file("hash.XXXXXX"),
226 metadata_hash_file("hash.XXXXXX");
227 string delta_generator_path = GetBuildArtifactsPath("delta_generator");
228 ASSERT_EQ(0,
229 System(base::StringPrintf(
230 "%s -in_file=%s -signature_size=%s -out_hash_file=%s "
231 "-out_metadata_hash_file=%s",
232 delta_generator_path.c_str(),
233 payload_path.c_str(),
234 signature_size_string.c_str(),
235 hash_file.path().c_str(),
236 metadata_hash_file.path().c_str())));
237
238 // Sign the hash with all private keys.
239 vector<test_utils::ScopedTempFile> sig_files, metadata_sig_files;
240 vector<string> sig_file_paths, metadata_sig_file_paths;
241 for (const auto& key_path : private_key_paths) {
242 brillo::Blob hash, signature;
243 ASSERT_TRUE(utils::ReadFile(hash_file.path(), &hash));
244 ASSERT_TRUE(PayloadSigner::SignHash(hash, key_path, &signature));
245
246 test_utils::ScopedTempFile sig_file("signature.XXXXXX");
247 ASSERT_TRUE(test_utils::WriteFileVector(sig_file.path(), signature));
248 sig_file_paths.push_back(sig_file.path());
249 sig_files.push_back(std::move(sig_file));
250
251 brillo::Blob metadata_hash, metadata_signature;
252 ASSERT_TRUE(utils::ReadFile(metadata_hash_file.path(), &metadata_hash));
253 ASSERT_TRUE(
254 PayloadSigner::SignHash(metadata_hash, key_path, &metadata_signature));
255
256 test_utils::ScopedTempFile metadata_sig_file("signature.XXXXXX");
257 ASSERT_TRUE(test_utils::WriteFileVector(metadata_sig_file.path(),
258 metadata_signature));
259
260 metadata_sig_file_paths.push_back(metadata_sig_file.path());
261 metadata_sig_files.push_back(std::move(metadata_sig_file));
262 }
263 string sig_files_string = base::JoinString(sig_file_paths, ":");
264 string metadata_sig_files_string =
265 base::JoinString(metadata_sig_file_paths, ":");
266
267 // Add the signature to the payload.
268 ASSERT_EQ(0,
269 System(base::StringPrintf("%s --signature_size=%s -in_file=%s "
270 "-payload_signature_file=%s "
271 "-metadata_signature_file=%s "
272 "-out_file=%s",
273 delta_generator_path.c_str(),
274 signature_size_string.c_str(),
275 payload_path.c_str(),
276 sig_files_string.c_str(),
277 metadata_sig_files_string.c_str(),
278 payload_path.c_str())));
279
280 int verify_result = System(base::StringPrintf("%s -in_file=%s -public_key=%s",
281 delta_generator_path.c_str(),
282 payload_path.c_str(),
283 public_key_path.c_str()));
284
285 if (verification_success) {
286 ASSERT_EQ(0, verify_result);
287 } else {
288 ASSERT_NE(0, verify_result);
289 }
290 }
291
SignGeneratedShellPayload(SignatureTest signature_test,const string & payload_path)292 static void SignGeneratedShellPayload(SignatureTest signature_test,
293 const string& payload_path) {
294 vector<SignatureTest> supported_test = {
295 kSignatureGeneratedShell,
296 kSignatureGeneratedShellBadKey,
297 kSignatureGeneratedShellECKey,
298 kSignatureGeneratedShellRotateCl1,
299 kSignatureGeneratedShellRotateCl2,
300 };
301 ASSERT_TRUE(std::find(supported_test.begin(),
302 supported_test.end(),
303 signature_test) != supported_test.end());
304
305 string private_key_path;
306 if (signature_test == kSignatureGeneratedShellBadKey) {
307 ASSERT_TRUE(utils::MakeTempFile("key.XXXXXX", &private_key_path, nullptr));
308 } else if (signature_test == kSignatureGeneratedShellECKey) {
309 private_key_path = GetBuildArtifactsPath(kUnittestPrivateKeyECPath);
310 } else {
311 private_key_path = GetBuildArtifactsPath(kUnittestPrivateKeyPath);
312 }
313 ScopedPathUnlinker key_unlinker(private_key_path);
314 key_unlinker.set_should_remove(signature_test ==
315 kSignatureGeneratedShellBadKey);
316
317 // Generates a new private key that will not match the public key.
318 if (signature_test == kSignatureGeneratedShellBadKey) {
319 LOG(INFO) << "Generating a mismatched private key.";
320 // The code below executes the equivalent of:
321 // openssl genrsa -out <private_key_path> 2048
322 RSA* rsa = RSA_new();
323 BIGNUM* e = BN_new();
324 EXPECT_EQ(1, BN_set_word(e, RSA_F4));
325 EXPECT_EQ(1, RSA_generate_key_ex(rsa, 2048, e, nullptr));
326 BN_free(e);
327 FILE* fprikey = fopen(private_key_path.c_str(), "w");
328 EXPECT_NE(nullptr, fprikey);
329 EXPECT_EQ(1,
330 PEM_write_RSAPrivateKey(
331 fprikey, rsa, nullptr, nullptr, 0, nullptr, nullptr));
332 fclose(fprikey);
333 RSA_free(rsa);
334 }
335
336 vector<string> private_key_paths = {private_key_path};
337 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
338 signature_test == kSignatureGeneratedShellRotateCl2) {
339 private_key_paths.push_back(
340 GetBuildArtifactsPath(kUnittestPrivateKey2Path));
341 }
342
343 std::string public_key;
344 if (signature_test == kSignatureGeneratedShellRotateCl2) {
345 public_key = GetBuildArtifactsPath(kUnittestPublicKey2Path);
346 } else if (signature_test == kSignatureGeneratedShellECKey) {
347 public_key = GetBuildArtifactsPath(kUnittestPublicKeyECPath);
348 } else {
349 public_key = GetBuildArtifactsPath(kUnittestPublicKeyPath);
350 }
351
352 bool verification_success = signature_test != kSignatureGeneratedShellBadKey;
353 SignGeneratedShellPayloadWithKeys(
354 payload_path, private_key_paths, public_key, verification_success);
355 }
356
GenerateDeltaFile(bool full_kernel,bool full_rootfs,ssize_t chunk_size,SignatureTest signature_test,DeltaState * state,uint32_t minor_version)357 static void GenerateDeltaFile(bool full_kernel,
358 bool full_rootfs,
359 ssize_t chunk_size,
360 SignatureTest signature_test,
361 DeltaState* state,
362 uint32_t minor_version) {
363 EXPECT_TRUE(utils::MakeTempFile("a_img.XXXXXX", &state->a_img, nullptr));
364 EXPECT_TRUE(utils::MakeTempFile("b_img.XXXXXX", &state->b_img, nullptr));
365
366 // result_img is used in minor version 2. Instead of applying the update
367 // in-place on A, we apply it to a new image, result_img.
368 EXPECT_TRUE(
369 utils::MakeTempFile("result_img.XXXXXX", &state->result_img, nullptr));
370
371 EXPECT_TRUE(
372 base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
373 base::FilePath(state->a_img)));
374
375 state->image_size = utils::FileSize(state->a_img);
376
377 // Create ImageInfo A & B
378 ImageInfo old_image_info;
379 ImageInfo new_image_info;
380
381 if (!full_rootfs) {
382 old_image_info.set_channel("src-channel");
383 old_image_info.set_board("src-board");
384 old_image_info.set_version("src-version");
385 old_image_info.set_key("src-key");
386 old_image_info.set_build_channel("src-build-channel");
387 old_image_info.set_build_version("src-build-version");
388 }
389
390 new_image_info.set_channel("test-channel");
391 new_image_info.set_board("test-board");
392 new_image_info.set_version("test-version");
393 new_image_info.set_key("test-key");
394 new_image_info.set_build_channel("test-build-channel");
395 new_image_info.set_build_version("test-build-version");
396
397 // Make some changes to the A image.
398 {
399 string a_mnt;
400 ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
401
402 brillo::Blob hardtocompress;
403 while (hardtocompress.size() < 3 * kBlockSize) {
404 hardtocompress.insert(hardtocompress.end(),
405 std::begin(kRandomString),
406 std::end(kRandomString));
407 }
408 EXPECT_TRUE(utils::WriteFile(
409 base::StringPrintf("%s/hardtocompress", a_mnt.c_str()).c_str(),
410 hardtocompress.data(),
411 hardtocompress.size()));
412
413 brillo::Blob zeros(16 * 1024, 0);
414 EXPECT_EQ(static_cast<int>(zeros.size()),
415 base::WriteFile(base::FilePath(base::StringPrintf(
416 "%s/move-to-sparse", a_mnt.c_str())),
417 reinterpret_cast<const char*>(zeros.data()),
418 zeros.size()));
419
420 EXPECT_TRUE(WriteSparseFile(
421 base::StringPrintf("%s/move-from-sparse", a_mnt.c_str()), 16 * 1024));
422
423 EXPECT_TRUE(WriteByteAtOffset(
424 base::StringPrintf("%s/move-semi-sparse", a_mnt.c_str()), 4096));
425
426 // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
427 // patch fails to zero out the final block.
428 brillo::Blob ones(1024 * 1024, 0xff);
429 EXPECT_TRUE(
430 utils::WriteFile(base::StringPrintf("%s/ones", a_mnt.c_str()).c_str(),
431 ones.data(),
432 ones.size()));
433 }
434
435 // Create a result image with image_size bytes of garbage.
436 brillo::Blob ones(state->image_size, 0xff);
437 EXPECT_TRUE(
438 utils::WriteFile(state->result_img.c_str(), ones.data(), ones.size()));
439 EXPECT_EQ(utils::FileSize(state->a_img), utils::FileSize(state->result_img));
440
441 EXPECT_TRUE(
442 base::CopyFile(GetBuildArtifactsPath().Append("gen/disk_ext2_4k.img"),
443 base::FilePath(state->b_img)));
444 {
445 // Make some changes to the B image.
446 string b_mnt;
447 ScopedLoopMounter b_mounter(state->b_img, &b_mnt, 0);
448 base::FilePath mnt_path(b_mnt);
449
450 EXPECT_TRUE(base::CopyFile(mnt_path.Append("regular-small"),
451 mnt_path.Append("regular-small2")));
452 EXPECT_TRUE(base::DeleteFile(mnt_path.Append("regular-small"), false));
453 EXPECT_TRUE(base::Move(mnt_path.Append("regular-small2"),
454 mnt_path.Append("regular-small")));
455 EXPECT_TRUE(
456 test_utils::WriteFileString(mnt_path.Append("foo").value(), "foo"));
457 EXPECT_EQ(0, base::WriteFile(mnt_path.Append("emptyfile"), "", 0));
458
459 EXPECT_TRUE(
460 WriteSparseFile(mnt_path.Append("fullsparse").value(), 1024 * 1024));
461 EXPECT_TRUE(
462 WriteSparseFile(mnt_path.Append("move-to-sparse").value(), 16 * 1024));
463
464 brillo::Blob zeros(16 * 1024, 0);
465 EXPECT_EQ(static_cast<int>(zeros.size()),
466 base::WriteFile(mnt_path.Append("move-from-sparse"),
467 reinterpret_cast<const char*>(zeros.data()),
468 zeros.size()));
469
470 EXPECT_TRUE(
471 WriteByteAtOffset(mnt_path.Append("move-semi-sparse").value(), 4096));
472 EXPECT_TRUE(WriteByteAtOffset(mnt_path.Append("partsparse").value(), 4096));
473
474 EXPECT_TRUE(
475 base::CopyFile(mnt_path.Append("regular-16k"), mnt_path.Append("tmp")));
476 EXPECT_TRUE(base::Move(mnt_path.Append("tmp"),
477 mnt_path.Append("link-hard-regular-16k")));
478
479 EXPECT_TRUE(base::DeleteFile(mnt_path.Append("link-short_symlink"), false));
480 EXPECT_TRUE(test_utils::WriteFileString(
481 mnt_path.Append("link-short_symlink").value(), "foobar"));
482
483 brillo::Blob hardtocompress;
484 while (hardtocompress.size() < 3 * kBlockSize) {
485 hardtocompress.insert(hardtocompress.end(),
486 std::begin(kRandomString),
487 std::end(kRandomString));
488 }
489 EXPECT_TRUE(utils::WriteFile(
490 base::StringPrintf("%s/hardtocompress", b_mnt.c_str()).c_str(),
491 hardtocompress.data(),
492 hardtocompress.size()));
493 }
494
495 string old_kernel;
496 EXPECT_TRUE(
497 utils::MakeTempFile("old_kernel.XXXXXX", &state->old_kernel, nullptr));
498
499 string new_kernel;
500 EXPECT_TRUE(
501 utils::MakeTempFile("new_kernel.XXXXXX", &state->new_kernel, nullptr));
502
503 string result_kernel;
504 EXPECT_TRUE(utils::MakeTempFile(
505 "result_kernel.XXXXXX", &state->result_kernel, nullptr));
506
507 state->kernel_size = kDefaultKernelSize;
508 state->old_kernel_data.resize(kDefaultKernelSize);
509 state->new_kernel_data.resize(state->old_kernel_data.size());
510 state->result_kernel_data.resize(state->old_kernel_data.size());
511 test_utils::FillWithData(&state->old_kernel_data);
512 test_utils::FillWithData(&state->new_kernel_data);
513 test_utils::FillWithData(&state->result_kernel_data);
514
515 // change the new kernel data
516 std::copy(
517 std::begin(kNewData), std::end(kNewData), state->new_kernel_data.begin());
518
519 // Write kernels to disk
520 EXPECT_TRUE(utils::WriteFile(state->old_kernel.c_str(),
521 state->old_kernel_data.data(),
522 state->old_kernel_data.size()));
523 EXPECT_TRUE(utils::WriteFile(state->new_kernel.c_str(),
524 state->new_kernel_data.data(),
525 state->new_kernel_data.size()));
526 EXPECT_TRUE(utils::WriteFile(state->result_kernel.c_str(),
527 state->result_kernel_data.data(),
528 state->result_kernel_data.size()));
529
530 EXPECT_TRUE(utils::MakeTempFile("delta.XXXXXX", &state->delta_path, nullptr));
531 LOG(INFO) << "delta path: " << state->delta_path;
532 {
533 const string private_key =
534 signature_test == kSignatureGenerator
535 ? GetBuildArtifactsPath(kUnittestPrivateKeyPath)
536 : "";
537
538 PayloadGenerationConfig payload_config;
539 payload_config.is_delta = !full_rootfs;
540 payload_config.hard_chunk_size = chunk_size;
541 payload_config.rootfs_partition_size = kRootFSPartitionSize;
542 payload_config.version.major = kBrilloMajorPayloadVersion;
543 payload_config.version.minor = minor_version;
544 if (!full_rootfs) {
545 payload_config.source.partitions.emplace_back(kPartitionNameRoot);
546 payload_config.source.partitions.emplace_back(kPartitionNameKernel);
547 payload_config.source.partitions.front().path = state->a_img;
548 if (!full_kernel)
549 payload_config.source.partitions.back().path = state->old_kernel;
550 payload_config.source.image_info = old_image_info;
551 EXPECT_TRUE(payload_config.source.LoadImageSize());
552 for (PartitionConfig& part : payload_config.source.partitions)
553 EXPECT_TRUE(part.OpenFilesystem());
554 } else {
555 if (payload_config.hard_chunk_size == -1)
556 // Use 1 MiB chunk size for the full unittests.
557 payload_config.hard_chunk_size = 1024 * 1024;
558 }
559 payload_config.target.partitions.emplace_back(kPartitionNameRoot);
560 payload_config.target.partitions.back().path = state->b_img;
561 payload_config.target.partitions.emplace_back(kPartitionNameKernel);
562 payload_config.target.partitions.back().path = state->new_kernel;
563 payload_config.target.image_info = new_image_info;
564 EXPECT_TRUE(payload_config.target.LoadImageSize());
565 for (PartitionConfig& part : payload_config.target.partitions)
566 EXPECT_TRUE(part.OpenFilesystem());
567
568 EXPECT_TRUE(payload_config.Validate());
569 EXPECT_TRUE(GenerateUpdatePayloadFile(
570 payload_config, state->delta_path, private_key, &state->metadata_size));
571 }
572 // Extend the "partitions" holding the file system a bit.
573 EXPECT_EQ(0,
574 HANDLE_EINTR(truncate(state->a_img.c_str(),
575 state->image_size + 1024 * 1024)));
576 EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
577 utils::FileSize(state->a_img));
578 EXPECT_EQ(0,
579 HANDLE_EINTR(truncate(state->b_img.c_str(),
580 state->image_size + 1024 * 1024)));
581 EXPECT_EQ(static_cast<off_t>(state->image_size + 1024 * 1024),
582 utils::FileSize(state->b_img));
583
584 if (signature_test == kSignatureGeneratedPlaceholder ||
585 signature_test == kSignatureGeneratedPlaceholderMismatch) {
586 size_t signature_size;
587 ASSERT_TRUE(PayloadSigner::GetMaximumSignatureSize(
588 GetBuildArtifactsPath(kUnittestPrivateKeyPath), &signature_size));
589 LOG(INFO) << "Inserting placeholder signature.";
590 ASSERT_TRUE(InsertSignaturePlaceholder(
591 signature_size, state->delta_path, &state->metadata_size));
592
593 if (signature_test == kSignatureGeneratedPlaceholderMismatch) {
594 signature_size -= 1;
595 LOG(INFO) << "Inserting mismatched placeholder signature.";
596 ASSERT_FALSE(InsertSignaturePlaceholder(
597 signature_size, state->delta_path, &state->metadata_size));
598 return;
599 }
600 }
601
602 if (signature_test == kSignatureGenerated ||
603 signature_test == kSignatureGeneratedPlaceholder ||
604 signature_test == kSignatureGeneratedPlaceholderMismatch) {
605 // Generate the signed payload and update the metadata size in state to
606 // reflect the new size after adding the signature operation to the
607 // manifest.
608 LOG(INFO) << "Signing payload.";
609 SignGeneratedPayload(state->delta_path, &state->metadata_size);
610 } else if (signature_test == kSignatureGeneratedShell ||
611 signature_test == kSignatureGeneratedShellECKey ||
612 signature_test == kSignatureGeneratedShellBadKey ||
613 signature_test == kSignatureGeneratedShellRotateCl1 ||
614 signature_test == kSignatureGeneratedShellRotateCl2) {
615 SignGeneratedShellPayload(signature_test, state->delta_path);
616 }
617 }
618
ApplyDeltaFile(bool full_kernel,bool full_rootfs,SignatureTest signature_test,DeltaState * state,bool hash_checks_mandatory,OperationHashTest op_hash_test,DeltaPerformer ** performer,uint32_t minor_version)619 static void ApplyDeltaFile(bool full_kernel,
620 bool full_rootfs,
621 SignatureTest signature_test,
622 DeltaState* state,
623 bool hash_checks_mandatory,
624 OperationHashTest op_hash_test,
625 DeltaPerformer** performer,
626 uint32_t minor_version) {
627 // Check the metadata.
628 {
629 EXPECT_TRUE(utils::ReadFile(state->delta_path, &state->delta));
630 PayloadMetadata payload_metadata;
631 EXPECT_TRUE(payload_metadata.ParsePayloadHeader(state->delta));
632 state->metadata_size = payload_metadata.GetMetadataSize();
633 LOG(INFO) << "Metadata size: " << state->metadata_size;
634 state->metadata_signature_size =
635 payload_metadata.GetMetadataSignatureSize();
636 LOG(INFO) << "Metadata signature size: " << state->metadata_signature_size;
637
638 DeltaArchiveManifest manifest;
639 EXPECT_TRUE(payload_metadata.GetManifest(state->delta, &manifest));
640 if (signature_test == kSignatureNone) {
641 EXPECT_FALSE(manifest.has_signatures_offset());
642 EXPECT_FALSE(manifest.has_signatures_size());
643 } else {
644 EXPECT_TRUE(manifest.has_signatures_offset());
645 EXPECT_TRUE(manifest.has_signatures_size());
646 Signatures sigs_message;
647 EXPECT_TRUE(sigs_message.ParseFromArray(
648 &state->delta[state->metadata_size + state->metadata_signature_size +
649 manifest.signatures_offset()],
650 manifest.signatures_size()));
651 if (signature_test == kSignatureGeneratedShellRotateCl1 ||
652 signature_test == kSignatureGeneratedShellRotateCl2)
653 EXPECT_EQ(2, sigs_message.signatures_size());
654 else
655 EXPECT_EQ(1, sigs_message.signatures_size());
656 const Signatures::Signature& signature = sigs_message.signatures(0);
657
658 vector<string> key_paths{GetBuildArtifactsPath(kUnittestPrivateKeyPath)};
659 if (signature_test == kSignatureGeneratedShellECKey) {
660 key_paths = {GetBuildArtifactsPath(kUnittestPrivateKeyECPath)};
661 } else if (signature_test == kSignatureGeneratedShellRotateCl1 ||
662 signature_test == kSignatureGeneratedShellRotateCl2) {
663 key_paths.push_back(GetBuildArtifactsPath(kUnittestPrivateKey2Path));
664 }
665 uint64_t expected_sig_data_length = 0;
666 EXPECT_TRUE(PayloadSigner::SignatureBlobLength(
667 key_paths, &expected_sig_data_length));
668 EXPECT_EQ(expected_sig_data_length, manifest.signatures_size());
669 EXPECT_FALSE(signature.data().empty());
670 }
671
672 // TODO(ahassani): Make |DeltaState| into a partition list kind of struct
673 // instead of hardcoded kernel/rootfs so its cleaner and we can make the
674 // following code into a helper function instead.
675 const auto& kernel_part = *std::find_if(
676 manifest.partitions().begin(),
677 manifest.partitions().end(),
678 [](const PartitionUpdate& partition) {
679 return partition.partition_name() == kPartitionNameKernel;
680 });
681 if (full_kernel) {
682 EXPECT_FALSE(kernel_part.has_old_partition_info());
683 } else {
684 EXPECT_EQ(state->old_kernel_data.size(),
685 kernel_part.old_partition_info().size());
686 EXPECT_FALSE(kernel_part.old_partition_info().hash().empty());
687 }
688 EXPECT_EQ(state->new_kernel_data.size(),
689 kernel_part.new_partition_info().size());
690 EXPECT_FALSE(kernel_part.new_partition_info().hash().empty());
691
692 const auto& rootfs_part =
693 *std::find_if(manifest.partitions().begin(),
694 manifest.partitions().end(),
695 [](const PartitionUpdate& partition) {
696 return partition.partition_name() == kPartitionNameRoot;
697 });
698 if (full_rootfs) {
699 EXPECT_FALSE(rootfs_part.has_old_partition_info());
700 } else {
701 EXPECT_FALSE(rootfs_part.old_partition_info().hash().empty());
702 }
703 EXPECT_FALSE(rootfs_part.new_partition_info().hash().empty());
704
705 EXPECT_EQ(manifest.new_image_info().channel(), "test-channel");
706 EXPECT_EQ(manifest.new_image_info().board(), "test-board");
707 EXPECT_EQ(manifest.new_image_info().version(), "test-version");
708 EXPECT_EQ(manifest.new_image_info().key(), "test-key");
709 EXPECT_EQ(manifest.new_image_info().build_channel(), "test-build-channel");
710 EXPECT_EQ(manifest.new_image_info().build_version(), "test-build-version");
711
712 if (!full_rootfs) {
713 EXPECT_EQ(manifest.old_image_info().channel(), "src-channel");
714 EXPECT_EQ(manifest.old_image_info().board(), "src-board");
715 EXPECT_EQ(manifest.old_image_info().version(), "src-version");
716 EXPECT_EQ(manifest.old_image_info().key(), "src-key");
717 EXPECT_EQ(manifest.old_image_info().build_channel(), "src-build-channel");
718 EXPECT_EQ(manifest.old_image_info().build_version(), "src-build-version");
719 }
720 }
721
722 MockPrefs prefs;
723 EXPECT_CALL(prefs, SetInt64(kPrefsManifestMetadataSize, state->metadata_size))
724 .WillOnce(Return(true));
725 EXPECT_CALL(
726 prefs,
727 SetInt64(kPrefsManifestSignatureSize, state->metadata_signature_size))
728 .WillOnce(Return(true));
729 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextOperation, _))
730 .WillRepeatedly(Return(true));
731 EXPECT_CALL(prefs, GetInt64(kPrefsUpdateStateNextOperation, _))
732 .WillOnce(Return(false));
733 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataOffset, _))
734 .WillRepeatedly(Return(true));
735 EXPECT_CALL(prefs, SetInt64(kPrefsUpdateStateNextDataLength, _))
736 .WillRepeatedly(Return(true));
737 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSHA256Context, _))
738 .WillRepeatedly(Return(true));
739 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignedSHA256Context, _))
740 .WillRepeatedly(Return(true));
741 EXPECT_CALL(prefs, SetString(kPrefsDynamicPartitionMetadataUpdated, _))
742 .WillRepeatedly(Return(true));
743 EXPECT_CALL(prefs,
744 SetString(kPrefsManifestBytes,
745 testing::SizeIs(state->metadata_signature_size +
746 state->metadata_size)))
747 .WillRepeatedly(Return(true));
748 if (op_hash_test == kValidOperationData && signature_test != kSignatureNone) {
749 EXPECT_CALL(prefs, SetString(kPrefsUpdateStateSignatureBlob, _))
750 .WillOnce(Return(true));
751 }
752
753 EXPECT_CALL(state->mock_delegate_, ShouldCancel(_))
754 .WillRepeatedly(Return(false));
755
756 // Update the A image in place.
757 InstallPlan* install_plan = &state->install_plan;
758 install_plan->hash_checks_mandatory = hash_checks_mandatory;
759 install_plan->payloads = {{.size = state->delta.size(),
760 .metadata_size = state->metadata_size,
761 .type = (full_kernel && full_rootfs)
762 ? InstallPayloadType::kFull
763 : InstallPayloadType::kDelta}};
764 install_plan->source_slot = 0;
765 install_plan->target_slot = 1;
766
767 InstallPlan::Partition root_part;
768 root_part.name = kPartitionNameRoot;
769
770 InstallPlan::Partition kernel_part;
771 kernel_part.name = kPartitionNameKernel;
772
773 LOG(INFO) << "Setting payload metadata size in Omaha = "
774 << state->metadata_size;
775 ASSERT_TRUE(PayloadSigner::GetMetadataSignature(
776 state->delta.data(),
777 state->metadata_size,
778 (signature_test == kSignatureGeneratedShellECKey)
779 ? GetBuildArtifactsPath(kUnittestPrivateKeyECPath)
780 : GetBuildArtifactsPath(kUnittestPrivateKeyPath),
781 &install_plan->payloads[0].metadata_signature));
782 EXPECT_FALSE(install_plan->payloads[0].metadata_signature.empty());
783
784 *performer = new DeltaPerformer(&prefs,
785 &state->fake_boot_control_,
786 &state->fake_hardware_,
787 &state->mock_delegate_,
788 install_plan,
789 &install_plan->payloads[0],
790 false /* interactive */);
791 string public_key_path = signature_test == kSignatureGeneratedShellECKey
792 ? GetBuildArtifactsPath(kUnittestPublicKeyECPath)
793 : GetBuildArtifactsPath(kUnittestPublicKeyPath);
794 EXPECT_TRUE(utils::FileExists(public_key_path.c_str()));
795 (*performer)->set_public_key_path(public_key_path);
796 (*performer)->set_update_certificates_path("");
797
798 EXPECT_EQ(static_cast<off_t>(state->image_size),
799 HashCalculator::RawHashOfFile(
800 state->a_img, state->image_size, &root_part.source_hash));
801 EXPECT_TRUE(HashCalculator::RawHashOfData(state->old_kernel_data,
802 &kernel_part.source_hash));
803
804 // The partitions should be empty before DeltaPerformer.
805 install_plan->partitions.clear();
806
807 state->fake_boot_control_.SetPartitionDevice(
808 kPartitionNameRoot, install_plan->source_slot, state->a_img);
809 state->fake_boot_control_.SetPartitionDevice(
810 kPartitionNameKernel, install_plan->source_slot, state->old_kernel);
811 state->fake_boot_control_.SetPartitionDevice(
812 kPartitionNameRoot, install_plan->target_slot, state->result_img);
813 state->fake_boot_control_.SetPartitionDevice(
814 kPartitionNameKernel, install_plan->target_slot, state->result_kernel);
815
816 ErrorCode expected_error, actual_error;
817 bool continue_writing;
818 switch (op_hash_test) {
819 case kInvalidOperationData: {
820 // Muck with some random offset post the metadata size so that
821 // some operation hash will result in a mismatch.
822 int some_offset = state->metadata_size + 300;
823 LOG(INFO) << "Tampered value at offset: " << some_offset;
824 state->delta[some_offset]++;
825 expected_error = ErrorCode::kDownloadOperationHashMismatch;
826 continue_writing = false;
827 break;
828 }
829
830 case kValidOperationData:
831 default:
832 // no change.
833 expected_error = ErrorCode::kSuccess;
834 continue_writing = true;
835 break;
836 }
837
838 // Write at some number of bytes per operation. Arbitrarily chose 5.
839 const size_t kBytesPerWrite = 5;
840 for (size_t i = 0; i < state->delta.size(); i += kBytesPerWrite) {
841 size_t count = std::min(state->delta.size() - i, kBytesPerWrite);
842 bool write_succeeded =
843 ((*performer)->Write(&state->delta[i], count, &actual_error));
844 // Normally write_succeeded should be true every time and
845 // actual_error should be ErrorCode::kSuccess. If so, continue the loop.
846 // But if we seeded an operation hash error above, then write_succeeded
847 // will be false. The failure may happen at any operation n. So, all
848 // Writes until n-1 should succeed and the nth operation will fail with
849 // actual_error. In this case, we should bail out of the loop because
850 // we cannot proceed applying the delta.
851 if (!write_succeeded) {
852 LOG(INFO) << "Write failed. Checking if it failed with expected error";
853 EXPECT_EQ(expected_error, actual_error);
854 if (!continue_writing) {
855 LOG(INFO) << "Cannot continue writing. Bailing out.";
856 break;
857 }
858 }
859
860 EXPECT_EQ(ErrorCode::kSuccess, actual_error);
861 }
862
863 // If we had continued all the way through, Close should succeed.
864 // Otherwise, it should fail. Check appropriately.
865 bool close_result = (*performer)->Close();
866 if (continue_writing)
867 EXPECT_EQ(0, close_result);
868 else
869 EXPECT_LE(0, close_result);
870 }
871
VerifyPayloadResult(DeltaPerformer * performer,DeltaState * state,ErrorCode expected_result,uint32_t minor_version)872 void VerifyPayloadResult(DeltaPerformer* performer,
873 DeltaState* state,
874 ErrorCode expected_result,
875 uint32_t minor_version) {
876 if (!performer) {
877 EXPECT_TRUE(!"Skipping payload verification since performer is null.");
878 return;
879 }
880
881 LOG(INFO) << "Verifying payload for expected result " << expected_result;
882 brillo::Blob expected_hash;
883 HashCalculator::RawHashOfData(state->delta, &expected_hash);
884 EXPECT_EQ(expected_result,
885 performer->VerifyPayload(expected_hash, state->delta.size()));
886 LOG(INFO) << "Verified payload.";
887
888 if (expected_result != ErrorCode::kSuccess) {
889 // no need to verify new partition if VerifyPayload failed.
890 return;
891 }
892
893 CompareFilesByBlock(
894 state->result_kernel, state->new_kernel, state->kernel_size);
895 CompareFilesByBlock(state->result_img, state->b_img, state->image_size);
896
897 brillo::Blob updated_kernel_partition;
898 EXPECT_TRUE(utils::ReadFile(state->result_kernel, &updated_kernel_partition));
899 ASSERT_GE(updated_kernel_partition.size(), base::size(kNewData));
900 EXPECT_TRUE(std::equal(std::begin(kNewData),
901 std::end(kNewData),
902 updated_kernel_partition.begin()));
903
904 const auto& partitions = state->install_plan.partitions;
905 EXPECT_EQ(2U, partitions.size());
906 EXPECT_EQ(kPartitionNameRoot, partitions[0].name);
907 EXPECT_EQ(kPartitionNameKernel, partitions[1].name);
908
909 EXPECT_EQ(kDefaultKernelSize, partitions[1].target_size);
910 brillo::Blob expected_new_kernel_hash;
911 EXPECT_TRUE(HashCalculator::RawHashOfData(state->new_kernel_data,
912 &expected_new_kernel_hash));
913 EXPECT_EQ(expected_new_kernel_hash, partitions[1].target_hash);
914
915 EXPECT_EQ(state->image_size, partitions[0].target_size);
916 brillo::Blob expected_new_rootfs_hash;
917 EXPECT_EQ(static_cast<off_t>(state->image_size),
918 HashCalculator::RawHashOfFile(
919 state->b_img, state->image_size, &expected_new_rootfs_hash));
920 EXPECT_EQ(expected_new_rootfs_hash, partitions[0].target_hash);
921 }
922
VerifyPayload(DeltaPerformer * performer,DeltaState * state,SignatureTest signature_test,uint32_t minor_version)923 void VerifyPayload(DeltaPerformer* performer,
924 DeltaState* state,
925 SignatureTest signature_test,
926 uint32_t minor_version) {
927 ErrorCode expected_result = ErrorCode::kSuccess;
928 switch (signature_test) {
929 case kSignatureNone:
930 expected_result = ErrorCode::kSignedDeltaPayloadExpectedError;
931 break;
932 case kSignatureGeneratedShellBadKey:
933 expected_result = ErrorCode::kDownloadPayloadPubKeyVerificationError;
934 break;
935 default:
936 break; // appease gcc
937 }
938
939 VerifyPayloadResult(performer, state, expected_result, minor_version);
940 }
941
DoSmallImageTest(bool full_kernel,bool full_rootfs,ssize_t chunk_size,SignatureTest signature_test,bool hash_checks_mandatory,uint32_t minor_version)942 void DoSmallImageTest(bool full_kernel,
943 bool full_rootfs,
944 ssize_t chunk_size,
945 SignatureTest signature_test,
946 bool hash_checks_mandatory,
947 uint32_t minor_version) {
948 DeltaState state;
949 DeltaPerformer* performer = nullptr;
950 GenerateDeltaFile(full_kernel,
951 full_rootfs,
952 chunk_size,
953 signature_test,
954 &state,
955 minor_version);
956
957 ScopedPathUnlinker a_img_unlinker(state.a_img);
958 ScopedPathUnlinker b_img_unlinker(state.b_img);
959 ScopedPathUnlinker new_img_unlinker(state.result_img);
960 ScopedPathUnlinker delta_unlinker(state.delta_path);
961 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
962 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
963 ScopedPathUnlinker result_kernel_unlinker(state.result_kernel);
964 ApplyDeltaFile(full_kernel,
965 full_rootfs,
966 signature_test,
967 &state,
968 hash_checks_mandatory,
969 kValidOperationData,
970 &performer,
971 minor_version);
972 VerifyPayload(performer, &state, signature_test, minor_version);
973 delete performer;
974 }
975
DoOperationHashMismatchTest(OperationHashTest op_hash_test,bool hash_checks_mandatory)976 void DoOperationHashMismatchTest(OperationHashTest op_hash_test,
977 bool hash_checks_mandatory) {
978 DeltaState state;
979 uint64_t minor_version = kFullPayloadMinorVersion;
980 GenerateDeltaFile(true, true, -1, kSignatureGenerated, &state, minor_version);
981 ScopedPathUnlinker a_img_unlinker(state.a_img);
982 ScopedPathUnlinker b_img_unlinker(state.b_img);
983 ScopedPathUnlinker delta_unlinker(state.delta_path);
984 ScopedPathUnlinker old_kernel_unlinker(state.old_kernel);
985 ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
986 DeltaPerformer* performer = nullptr;
987 ApplyDeltaFile(true,
988 true,
989 kSignatureGenerated,
990 &state,
991 hash_checks_mandatory,
992 op_hash_test,
993 &performer,
994 minor_version);
995 delete performer;
996 }
997
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageTest)998 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageTest) {
999 DoSmallImageTest(
1000 false, false, -1, kSignatureGenerator, false, kSourceMinorPayloadVersion);
1001 }
1002
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignaturePlaceholderTest)1003 TEST(DeltaPerformerIntegrationTest,
1004 RunAsRootSmallImageSignaturePlaceholderTest) {
1005 DoSmallImageTest(false,
1006 false,
1007 -1,
1008 kSignatureGeneratedPlaceholder,
1009 false,
1010 kSourceMinorPayloadVersion);
1011 }
1012
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignaturePlaceholderMismatchTest)1013 TEST(DeltaPerformerIntegrationTest,
1014 RunAsRootSmallImageSignaturePlaceholderMismatchTest) {
1015 DeltaState state;
1016 GenerateDeltaFile(false,
1017 false,
1018 -1,
1019 kSignatureGeneratedPlaceholderMismatch,
1020 &state,
1021 kSourceMinorPayloadVersion);
1022 }
1023
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageChunksTest)1024 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageChunksTest) {
1025 DoSmallImageTest(false,
1026 false,
1027 kBlockSize,
1028 kSignatureGenerator,
1029 false,
1030 kSourceMinorPayloadVersion);
1031 }
1032
TEST(DeltaPerformerIntegrationTest,RunAsRootFullKernelSmallImageTest)1033 TEST(DeltaPerformerIntegrationTest, RunAsRootFullKernelSmallImageTest) {
1034 DoSmallImageTest(
1035 true, false, -1, kSignatureGenerator, false, kSourceMinorPayloadVersion);
1036 }
1037
TEST(DeltaPerformerIntegrationTest,RunAsRootFullSmallImageTest)1038 TEST(DeltaPerformerIntegrationTest, RunAsRootFullSmallImageTest) {
1039 DoSmallImageTest(
1040 true, true, -1, kSignatureGenerator, true, kFullPayloadMinorVersion);
1041 }
1042
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignNoneTest)1043 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignNoneTest) {
1044 DoSmallImageTest(
1045 false, false, -1, kSignatureNone, false, kSourceMinorPayloadVersion);
1046 }
1047
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedTest)1048 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedTest) {
1049 DoSmallImageTest(
1050 false, false, -1, kSignatureGenerated, true, kSourceMinorPayloadVersion);
1051 }
1052
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellTest)1053 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSignGeneratedShellTest) {
1054 DoSmallImageTest(false,
1055 false,
1056 -1,
1057 kSignatureGeneratedShell,
1058 false,
1059 kSourceMinorPayloadVersion);
1060 }
1061
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellECKeyTest)1062 TEST(DeltaPerformerIntegrationTest,
1063 RunAsRootSmallImageSignGeneratedShellECKeyTest) {
1064 DoSmallImageTest(false,
1065 false,
1066 -1,
1067 kSignatureGeneratedShellECKey,
1068 false,
1069 kSourceMinorPayloadVersion);
1070 }
1071
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellBadKeyTest)1072 TEST(DeltaPerformerIntegrationTest,
1073 RunAsRootSmallImageSignGeneratedShellBadKeyTest) {
1074 DoSmallImageTest(false,
1075 false,
1076 -1,
1077 kSignatureGeneratedShellBadKey,
1078 false,
1079 kSourceMinorPayloadVersion);
1080 }
1081
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellRotateCl1Test)1082 TEST(DeltaPerformerIntegrationTest,
1083 RunAsRootSmallImageSignGeneratedShellRotateCl1Test) {
1084 DoSmallImageTest(false,
1085 false,
1086 -1,
1087 kSignatureGeneratedShellRotateCl1,
1088 false,
1089 kSourceMinorPayloadVersion);
1090 }
1091
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSignGeneratedShellRotateCl2Test)1092 TEST(DeltaPerformerIntegrationTest,
1093 RunAsRootSmallImageSignGeneratedShellRotateCl2Test) {
1094 DoSmallImageTest(false,
1095 false,
1096 -1,
1097 kSignatureGeneratedShellRotateCl2,
1098 false,
1099 kSourceMinorPayloadVersion);
1100 }
1101
TEST(DeltaPerformerIntegrationTest,RunAsRootSmallImageSourceOpsTest)1102 TEST(DeltaPerformerIntegrationTest, RunAsRootSmallImageSourceOpsTest) {
1103 DoSmallImageTest(
1104 false, false, -1, kSignatureGenerator, false, kSourceMinorPayloadVersion);
1105 }
1106
TEST(DeltaPerformerIntegrationTest,RunAsRootMandatoryOperationHashMismatchTest)1107 TEST(DeltaPerformerIntegrationTest,
1108 RunAsRootMandatoryOperationHashMismatchTest) {
1109 DoOperationHashMismatchTest(kInvalidOperationData, true);
1110 }
1111
1112 } // namespace chromeos_update_engine
1113