AU: Verify that the applied delta update matches the server-sent hashes.

Also, don't try to resume any delta update that fails for any reason
other than download transfer errors.

BUG=7348
TEST=unit tests, gmerged on device

Change-Id: Ice464b8d421256717d7909fd5fa46d762bd48952

Review URL: http://codereview.chromium.org/3599025
diff --git a/delta_performer.cc b/delta_performer.cc
index 3c24d5b..7ee9d4f 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -545,8 +545,6 @@
                                                        key_path,
                                                        &signed_hash_data));
   OmahaHashCalculator signed_hasher;
-  // TODO(petkov): Make sure signed_hash_context_ is loaded when resuming an
-  // update.
   TEST_AND_RETURN_FALSE(signed_hasher.SetContext(signed_hash_context_));
   TEST_AND_RETURN_FALSE(signed_hasher.Finalize());
   const vector<char>& hash_data = signed_hasher.raw_hash();
@@ -555,6 +553,28 @@
   return true;
 }
 
+bool DeltaPerformer::VerifyAppliedUpdate(const string& path,
+                                         const string& kernel_path) {
+  LOG(INFO) << "Verifying applied update.";
+  TEST_AND_RETURN_FALSE(manifest_valid_ &&
+                        manifest_.has_new_kernel_info() &&
+                        manifest_.has_new_rootfs_info());
+  const string* paths[] = { &kernel_path, &path };
+  const PartitionInfo* infos[] = {
+    &manifest_.new_kernel_info(), &manifest_.new_rootfs_info()
+  };
+  for (size_t i = 0; i < arraysize(paths); ++i) {
+    OmahaHashCalculator hasher;
+    TEST_AND_RETURN_FALSE(hasher.UpdateFile(*paths[i], infos[i]->size()));
+    TEST_AND_RETURN_FALSE(hasher.Finalize());
+    TEST_AND_RETURN_FALSE(hasher.raw_hash().size() == infos[i]->hash().size());
+    TEST_AND_RETURN_FALSE(memcmp(hasher.raw_hash().data(),
+                                 infos[i]->hash().data(),
+                                 hasher.raw_hash().size()) == 0);
+  }
+  return true;
+}
+
 void DeltaPerformer::DiscardBufferHeadBytes(size_t count) {
   hash_calculator_.Update(&buffer_[0], count);
   buffer_.erase(buffer_.begin(), buffer_.begin() + count);