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