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