update_engine: replace std::vector<char> with chromeos::Blob

To make update engine consistent with the rest of platform2 code
replaced std::vector<char> as the container of binary data with
chromeos::Blob.

BUG=None
TEST=`FEATURES=test emerge-link update_engine`

Change-Id: I6385fd2257d15aa24bfa74ac35512c2a06c33012
Reviewed-on: https://chromium-review.googlesource.com/247793
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/bzip.cc b/bzip.cc
index 2b225c0..323a080 100644
--- a/bzip.cc
+++ b/bzip.cc
@@ -19,38 +19,40 @@
 // BzipData compresses or decompresses the input to the output.
 // Returns true on success.
 // Use one of BzipBuffToBuff*ompress as the template parameter to BzipData().
-int BzipBuffToBuffDecompress(char* out,
+int BzipBuffToBuffDecompress(uint8_t* out,
                              uint32_t* out_length,
-                             const char* in,
+                             const void* in,
                              uint32_t in_length) {
-  return BZ2_bzBuffToBuffDecompress(out,
-                                    out_length,
-                                    const_cast<char*>(in),
-                                    in_length,
-                                    0,  // Silent verbosity
-                                    0);  // Normal algorithm
+  return BZ2_bzBuffToBuffDecompress(
+      reinterpret_cast<char*>(out),
+      out_length,
+      reinterpret_cast<char*>(const_cast<void*>(in)),
+      in_length,
+      0,  // Silent verbosity
+      0);  // Normal algorithm
 }
 
-int BzipBuffToBuffCompress(char* out,
+int BzipBuffToBuffCompress(uint8_t* out,
                            uint32_t* out_length,
-                           const char* in,
+                           const void* in,
                            uint32_t in_length) {
-  return BZ2_bzBuffToBuffCompress(out,
-                                  out_length,
-                                  const_cast<char*>(in),
-                                  in_length,
-                                  9,  // Best compression
-                                  0,  // Silent verbosity
-                                  0);  // Default work factor
+  return BZ2_bzBuffToBuffCompress(
+      reinterpret_cast<char*>(out),
+      out_length,
+      reinterpret_cast<char*>(const_cast<void*>(in)),
+      in_length,
+      9,  // Best compression
+      0,  // Silent verbosity
+      0);  // Default work factor
 }
 
-template<int F(char* out,
+template<int F(uint8_t* out,
                uint32_t* out_length,
-               const char* in,
+               const void* in,
                uint32_t in_length)>
-bool BzipData(const char* const in,
+bool BzipData(const void* const in,
               const int32_t in_size,
-              vector<char>* const out) {
+              chromeos::Blob* const out) {
   TEST_AND_RETURN_FALSE(out);
   out->clear();
   if (in_size == 0) {
@@ -62,7 +64,7 @@
 
   for (;;) {
     uint32_t data_size = buf_size;
-    int rc = F(&(*out)[0], &data_size, in, in_size);
+    int rc = F(out->data(), &data_size, in, in_size);
     TEST_AND_RETURN_FALSE(rc == BZ_OUTBUFF_FULL || rc == BZ_OK);
     if (rc == BZ_OK) {
       // we're done!
@@ -78,40 +80,36 @@
 
 }  // namespace
 
-bool BzipDecompress(const vector<char>& in, vector<char>* out) {
-  return BzipData<BzipBuffToBuffDecompress>(&in[0],
+bool BzipDecompress(const chromeos::Blob& in, chromeos::Blob* out) {
+  return BzipData<BzipBuffToBuffDecompress>(in.data(),
                                             static_cast<int32_t>(in.size()),
                                             out);
 }
 
-bool BzipCompress(const vector<char>& in, vector<char>* out) {
-  return BzipData<BzipBuffToBuffCompress>(&in[0], in.size(), out);
+bool BzipCompress(const chromeos::Blob& in, chromeos::Blob* out) {
+  return BzipData<BzipBuffToBuffCompress>(in.data(), in.size(), out);
 }
 
 namespace {
-template<bool F(const char* const in,
+template<bool F(const void* const in,
                 const int32_t in_size,
-                vector<char>* const out)>
+                chromeos::Blob* const out)>
 bool BzipString(const string& str,
-                vector<char>* out) {
+                chromeos::Blob* out) {
   TEST_AND_RETURN_FALSE(out);
-  vector<char> temp;
-  TEST_AND_RETURN_FALSE(F(str.data(),
-                          str.size(),
-                          &temp));
+  chromeos::Blob temp;
+  TEST_AND_RETURN_FALSE(F(str.data(), str.size(), &temp));
   out->clear();
   out->insert(out->end(), temp.begin(), temp.end());
   return true;
 }
 }  // namespace
 
-bool BzipCompressString(const string& str,
-                        vector<char>* out) {
+bool BzipCompressString(const string& str, chromeos::Blob* out) {
   return BzipString<BzipData<BzipBuffToBuffCompress>>(str, out);
 }
 
-bool BzipDecompressString(const string& str,
-                          vector<char>* out) {
+bool BzipDecompressString(const string& str, chromeos::Blob* out) {
   return BzipString<BzipData<BzipBuffToBuffDecompress>>(str, out);
 }
 
diff --git a/bzip.h b/bzip.h
index e78708b..af3ada4 100644
--- a/bzip.h
+++ b/bzip.h
@@ -8,13 +8,15 @@
 #include <string>
 #include <vector>
 
+#include <chromeos/secure_blob.h>
+
 namespace chromeos_update_engine {
 
 // Bzip2 compresses or decompresses str/in to out.
-bool BzipDecompress(const std::vector<char>& in, std::vector<char>* out);
-bool BzipCompress(const std::vector<char>& in, std::vector<char>* out);
-bool BzipCompressString(const std::string& str, std::vector<char>* out);
-bool BzipDecompressString(const std::string& str, std::vector<char>* out);
+bool BzipDecompress(const chromeos::Blob& in, chromeos::Blob* out);
+bool BzipCompress(const chromeos::Blob& in, chromeos::Blob* out);
+bool BzipCompressString(const std::string& str, chromeos::Blob* out);
+bool BzipDecompressString(const std::string& str, chromeos::Blob* out);
 
 }  // namespace chromeos_update_engine
 
diff --git a/bzip_extent_writer.cc b/bzip_extent_writer.cc
index 7cde7ba..14a0f63 100644
--- a/bzip_extent_writer.cc
+++ b/bzip_extent_writer.cc
@@ -9,7 +9,7 @@
 namespace chromeos_update_engine {
 
 namespace {
-const vector<char>::size_type kOutputBufferLength = 16 * 1024;
+const chromeos::Blob::size_type kOutputBufferLength = 16 * 1024;
 }
 
 bool BzipExtentWriter::Init(FileDescriptorPtr fd,
@@ -26,23 +26,23 @@
 }
 
 bool BzipExtentWriter::Write(const void* bytes, size_t count) {
-  vector<char> output_buffer(kOutputBufferLength);
+  chromeos::Blob output_buffer(kOutputBufferLength);
 
   // Copy the input data into |input_buffer_| only if |input_buffer_| already
   // contains unconsumed data. Otherwise, process the data directly from the
   // source.
-  const char* input = reinterpret_cast<const char*>(bytes);
-  const char* input_end = input + count;
+  const uint8_t* input = reinterpret_cast<const uint8_t*>(bytes);
+  const uint8_t* input_end = input + count;
   if (!input_buffer_.empty()) {
     input_buffer_.insert(input_buffer_.end(), input, input_end);
-    input = &input_buffer_[0];
+    input = input_buffer_.data();
     input_end = input + input_buffer_.size();
   }
-  stream_.next_in = const_cast<char*>(input);
+  stream_.next_in = reinterpret_cast<char*>(const_cast<uint8_t*>(input));
   stream_.avail_in = input_end - input;
 
   for (;;) {
-    stream_.next_out = &output_buffer[0];
+    stream_.next_out = reinterpret_cast<char*>(output_buffer.data());
     stream_.avail_out = output_buffer.size();
 
     int rc = BZ2_bzDecompress(&stream_);
@@ -52,18 +52,18 @@
       break;  // got no new bytes
 
     TEST_AND_RETURN_FALSE(
-        next_->Write(&output_buffer[0],
+        next_->Write(output_buffer.data(),
                      output_buffer.size() - stream_.avail_out));
 
     if (rc == BZ_STREAM_END)
-      CHECK_EQ(stream_.avail_in, static_cast<unsigned int>(0));
+      CHECK_EQ(stream_.avail_in, 0u);
     if (stream_.avail_in == 0)
       break;  // no more input to process
   }
 
   // Store unconsumed data (if any) in |input_buffer_|.
   if (stream_.avail_in || !input_buffer_.empty()) {
-    vector<char> new_input_buffer(input_end - stream_.avail_in, input_end);
+    chromeos::Blob new_input_buffer(input_end - stream_.avail_in, input_end);
     new_input_buffer.swap(input_buffer_);
   }
 
diff --git a/bzip_extent_writer.h b/bzip_extent_writer.h
index 0187c0b..6a6133a 100644
--- a/bzip_extent_writer.h
+++ b/bzip_extent_writer.h
@@ -5,8 +5,11 @@
 #ifndef UPDATE_ENGINE_BZIP_EXTENT_WRITER_H_
 #define UPDATE_ENGINE_BZIP_EXTENT_WRITER_H_
 
-#include <vector>
 #include <bzlib.h>
+#include <vector>
+
+#include <chromeos/secure_blob.h>
+
 #include "update_engine/extent_writer.h"
 #include "update_engine/utils.h"
 
@@ -32,7 +35,7 @@
  private:
   ExtentWriter* const next_;  // The underlying ExtentWriter.
   bz_stream stream_;  // the libbz2 stream
-  std::vector<char> input_buffer_;
+  chromeos::Blob input_buffer_;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/bzip_extent_writer_unittest.cc b/bzip_extent_writer_unittest.cc
index 67611c8..2b98eb1 100644
--- a/bzip_extent_writer_unittest.cc
+++ b/bzip_extent_writer_unittest.cc
@@ -55,7 +55,7 @@
 
   // 'echo test | bzip2 | hexdump' yields:
   static const char test_uncompressed[] = "test\n";
-  static const unsigned char test[] = {
+  static const uint8_t test[] = {
     0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0xcc, 0xc3,
     0x71, 0xd4, 0x00, 0x00, 0x02, 0x41, 0x80, 0x00, 0x10, 0x02, 0x00, 0x0c,
     0x00, 0x20, 0x00, 0x21, 0x9a, 0x68, 0x33, 0x4d, 0x19, 0x97, 0x8b, 0xb9,
@@ -68,14 +68,14 @@
   EXPECT_TRUE(bzip_writer.Write(test, sizeof(test)));
   EXPECT_TRUE(bzip_writer.End());
 
-  vector<char> buf;
+  chromeos::Blob buf;
   EXPECT_TRUE(utils::ReadFile(path_, &buf));
   EXPECT_EQ(strlen(test_uncompressed), buf.size());
-  EXPECT_EQ(string(buf.data(), buf.size()), string(test_uncompressed));
+  EXPECT_EQ(string(buf.begin(), buf.end()), string(test_uncompressed));
 }
 
 TEST_F(BzipExtentWriterTest, ChunkedTest) {
-  const vector<char>::size_type kDecompressedLength = 2048 * 1024;  // 2 MiB
+  const chromeos::Blob::size_type kDecompressedLength = 2048 * 1024;  // 2 MiB
   string decompressed_path;
   ASSERT_TRUE(utils::MakeTempFile("BzipExtentWriterTest-decompressed-XXXXXX",
                                   &decompressed_path, nullptr));
@@ -90,7 +90,7 @@
   extent.set_num_blocks(kDecompressedLength / kBlockSize + 1);
   extents.push_back(extent);
 
-  vector<char> decompressed_data(kDecompressedLength);
+  chromeos::Blob decompressed_data(kDecompressedLength);
   test_utils::FillWithData(&decompressed_data);
 
   EXPECT_TRUE(test_utils::WriteFileVector(
@@ -99,15 +99,15 @@
   EXPECT_EQ(0, test_utils::System(
       string("cat ") + decompressed_path + "|bzip2>" + compressed_path));
 
-  vector<char> compressed_data;
+  chromeos::Blob compressed_data;
   EXPECT_TRUE(utils::ReadFile(compressed_path, &compressed_data));
 
   DirectExtentWriter direct_writer;
   BzipExtentWriter bzip_writer(&direct_writer);
   EXPECT_TRUE(bzip_writer.Init(fd_, extents, kBlockSize));
 
-  vector<char> original_compressed_data = compressed_data;
-  for (vector<char>::size_type i = 0; i < compressed_data.size();
+  chromeos::Blob original_compressed_data = compressed_data;
+  for (chromeos::Blob::size_type i = 0; i < compressed_data.size();
        i += kChunkSize) {
     size_t this_chunk_size = min(kChunkSize, compressed_data.size() - i);
     EXPECT_TRUE(bzip_writer.Write(&compressed_data[i], this_chunk_size));
@@ -117,7 +117,7 @@
   // Check that the const input has not been clobbered.
   test_utils::ExpectVectorsEq(original_compressed_data, compressed_data);
 
-  vector<char> output;
+  chromeos::Blob output;
   EXPECT_TRUE(utils::ReadFile(path_, &output));
   EXPECT_EQ(kDecompressedLength, output.size());
   test_utils::ExpectVectorsEq(decompressed_data, output);
diff --git a/certificate_checker.cc b/certificate_checker.cc
index 4dd9182..4c1d2ed 100644
--- a/certificate_checker.cc
+++ b/certificate_checker.cc
@@ -34,7 +34,7 @@
 bool OpenSSLWrapper::GetCertificateDigest(X509_STORE_CTX* x509_ctx,
                                           int* out_depth,
                                           unsigned int* out_digest_length,
-                                          unsigned char* out_digest) const {
+                                          uint8_t* out_digest) const {
   TEST_AND_RETURN_FALSE(out_digest);
   X509* certificate = X509_STORE_CTX_get_current_cert(x509_ctx);
   TEST_AND_RETURN_FALSE(certificate);
@@ -119,7 +119,7 @@
 
   int depth;
   unsigned int digest_length;
-  unsigned char digest[EVP_MAX_MD_SIZE];
+  uint8_t digest[EVP_MAX_MD_SIZE];
 
   if (!openssl_wrapper_->GetCertificateDigest(x509_ctx,
                                               &depth,
diff --git a/certificate_checker.h b/certificate_checker.h
index b5f7a15..81e7dde 100644
--- a/certificate_checker.h
+++ b/certificate_checker.h
@@ -36,7 +36,7 @@
   virtual bool GetCertificateDigest(X509_STORE_CTX* x509_ctx,
                                     int* out_depth,
                                     unsigned int* out_digest_length,
-                                    unsigned char* out_digest) const;
+                                    uint8_t* out_digest) const;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(OpenSSLWrapper);
diff --git a/certificate_checker_unittest.cc b/certificate_checker_unittest.cc
index a3d7465..5d4d8f0 100644
--- a/certificate_checker_unittest.cc
+++ b/certificate_checker_unittest.cc
@@ -61,7 +61,7 @@
   // Parameters of our mock certificate digest.
   int depth_;
   unsigned int length_;
-  unsigned char digest_[4];
+  uint8_t digest_[4];
   string digest_hex_;
   string diff_digest_hex_;
   string cert_key_prefix_;
diff --git a/delta_performer.cc b/delta_performer.cc
index bcbfb46..9392af3 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -68,11 +68,12 @@
     ret.reset(new UbiFileDescriptor);
   } else if (MtdFileDescriptor::IsMtd(path)) {
     ret.reset(new MtdFileDescriptor);
-  } else
+  } else {
 #endif
-  {
     ret.reset(new EintrSafeFileDescriptor);
+#if USE_MTD
   }
+#endif
   return ret;
 }
 
@@ -273,8 +274,7 @@
 namespace {
 
 void LogPartitionInfoHash(const PartitionInfo& info, const string& tag) {
-  string sha256 = chromeos::data_encoding::Base64Encode(info.hash().data(),
-                                                        info.hash().size());
+  string sha256 = chromeos::data_encoding::Base64Encode(info.hash());
   LOG(INFO) << "PartitionInfo " << tag << " sha256: " << sha256
             << " size: " << info.size();
 }
@@ -320,8 +320,7 @@
 
 
 DeltaPerformer::MetadataParseResult DeltaPerformer::ParsePayloadMetadata(
-    const vector<char>& payload,
-    ErrorCode* error) {
+    const chromeos::Blob& payload, ErrorCode* error) {
   *error = ErrorCode::kSuccess;
   const uint64_t manifest_offset = GetManifestOffset();
   uint64_t manifest_size = (metadata_size_ ?
@@ -403,7 +402,7 @@
 
   // We have the full metadata in |payload|. Verify its integrity
   // and authenticity based on the information we have in Omaha response.
-  *error = ValidateMetadataSignature(&payload[0], metadata_size_);
+  *error = ValidateMetadataSignature(payload.data(), metadata_size_);
   if (*error != ErrorCode::kSuccess) {
     if (install_plan_->hash_checks_mandatory) {
       // The autoupdate_CatchBadSignatures test checks for this string
@@ -433,8 +432,7 @@
 // Wrapper around write. Returns true if all requested bytes
 // were written, or false on any error, regardless of progress
 // and stores an action exit code in |error|.
-bool DeltaPerformer::Write(const void* bytes, size_t count,
-                           ErrorCode *error) {
+bool DeltaPerformer::Write(const void* bytes, size_t count, ErrorCode *error) {
   *error = ErrorCode::kSuccess;
 
   const char* c_bytes = reinterpret_cast<const char*>(bytes);
@@ -626,7 +624,7 @@
   FileDescriptorPtr fd = is_kernel_partition ? kernel_fd_ : fd_;
 
   TEST_AND_RETURN_FALSE(writer->Init(fd, extents, block_size_));
-  TEST_AND_RETURN_FALSE(writer->Write(&buffer_[0], operation.data_length()));
+  TEST_AND_RETURN_FALSE(writer->Write(buffer_.data(), operation.data_length()));
   TEST_AND_RETURN_FALSE(writer->End());
 
   // Update buffer
@@ -651,7 +649,7 @@
     blocks_to_write += operation.dst_extents(i).num_blocks();
 
   DCHECK_EQ(blocks_to_write, blocks_to_read);
-  vector<char> buf(blocks_to_write * block_size_);
+  chromeos::Blob buf(blocks_to_write * block_size_);
 
   FileDescriptorPtr fd = is_kernel_partition ? kernel_fd_ : fd_;
 
@@ -762,7 +760,7 @@
     int fd = open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
     ScopedFdCloser fd_closer(&fd);
     TEST_AND_RETURN_FALSE(
-        utils::WriteAll(fd, &buffer_[0], operation.data_length()));
+        utils::WriteAll(fd, buffer_.data(), operation.data_length()));
   }
 
   // Update the buffer to release the patch data memory as soon as the patch
@@ -802,10 +800,10 @@
         (last_extent.start_block() + last_extent.num_blocks()) * block_size_;
     const uint64_t begin_byte =
         end_byte - (block_size_ - operation.dst_length() % block_size_);
-    vector<char> zeros(end_byte - begin_byte);
+    chromeos::Blob zeros(end_byte - begin_byte);
     FileDescriptorPtr fd = is_kernel_partition ? kernel_fd_ : fd_;
     TEST_AND_RETURN_FALSE(
-        utils::PWriteAll(fd, &zeros[0], end_byte - begin_byte, begin_byte));
+        utils::PWriteAll(fd, zeros.data(), end_byte - begin_byte, begin_byte));
   }
   return true;
 }
@@ -836,8 +834,8 @@
   // 2. Verify the signature as soon as it's received and don't checkpoint the
   // blob and the signed sha-256 context.
   LOG_IF(WARNING, !prefs_->SetString(kPrefsUpdateStateSignatureBlob,
-                                     string(&signatures_message_data_[0],
-                                            signatures_message_data_.size())))
+                                     string(signatures_message_data_.begin(),
+                                            signatures_message_data_.end())))
       << "Unable to store the signature blob.";
   // The hash of all data consumed so far should be verified against the signed
   // hash.
@@ -865,7 +863,7 @@
 }
 
 ErrorCode DeltaPerformer::ValidateMetadataSignature(
-    const char* metadata, uint64_t metadata_size) {
+    const void* metadata, uint64_t metadata_size) {
 
   if (install_plan_->metadata_signature.empty()) {
     if (install_plan_->hash_checks_mandatory) {
@@ -880,14 +878,13 @@
   }
 
   // Convert base64-encoded signature to raw bytes.
-  chromeos::Blob signature;
+  chromeos::Blob metadata_signature;
   if (!chromeos::data_encoding::Base64Decode(install_plan_->metadata_signature,
-                                             &signature)) {
+                                             &metadata_signature)) {
     LOG(ERROR) << "Unable to decode base64 metadata signature: "
                << install_plan_->metadata_signature;
     return ErrorCode::kDownloadMetadataSignatureError;
   }
-  vector<char> metadata_signature{signature.begin(), signature.end()};
 
   // See if we should use the public RSA key in the Omaha response.
   base::FilePath path_to_public_key(public_key_path_);
@@ -901,7 +898,7 @@
   LOG(INFO) << "Verifying metadata hash signature using public key: "
             << path_to_public_key.value();
 
-  vector<char> expected_metadata_hash;
+  chromeos::Blob expected_metadata_hash;
   if (!PayloadVerifier::GetRawHashFromSignature(metadata_signature,
                                                 path_to_public_key.value(),
                                                 &expected_metadata_hash)) {
@@ -916,7 +913,7 @@
     return ErrorCode::kDownloadMetadataSignatureVerificationError;
   }
 
-  vector<char> calculated_metadata_hash = metadata_hasher.raw_hash();
+  chromeos::Blob calculated_metadata_hash = metadata_hasher.raw_hash();
   PayloadVerifier::PadRSA2048SHA256Hash(&calculated_metadata_hash);
   if (calculated_metadata_hash.empty()) {
     LOG(ERROR) << "Computed actual hash of metadata is empty.";
@@ -1018,20 +1015,20 @@
     return ErrorCode::kSuccess;
   }
 
-  vector<char> expected_op_hash;
+  chromeos::Blob expected_op_hash;
   expected_op_hash.assign(operation.data_sha256_hash().data(),
                           (operation.data_sha256_hash().data() +
                            operation.data_sha256_hash().size()));
 
   OmahaHashCalculator operation_hasher;
-  operation_hasher.Update(&buffer_[0], operation.data_length());
+  operation_hasher.Update(buffer_.data(), operation.data_length());
   if (!operation_hasher.Finalize()) {
     LOG(ERROR) << "Unable to compute actual hash of operation "
                << next_operation_num_;
     return ErrorCode::kDownloadOperationHashVerificationError;
   }
 
-  vector<char> calculated_op_hash = operation_hasher.raw_hash();
+  chromeos::Blob calculated_op_hash = operation_hasher.raw_hash();
   if (calculated_op_hash != expected_op_hash) {
     LOG(ERROR) << "Hash verification failed for operation "
                << next_operation_num_ << ". Expected hash = ";
@@ -1088,7 +1085,7 @@
   }
   TEST_AND_RETURN_VAL(ErrorCode::kSignedDeltaPayloadExpectedError,
                       !signatures_message_data_.empty());
-  vector<char> signed_hash_data;
+  chromeos::Blob signed_hash_data;
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
                       PayloadVerifier::VerifySignature(
                           signatures_message_data_,
@@ -1099,7 +1096,7 @@
                       signed_hasher.SetContext(signed_hash_context_));
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
                       signed_hasher.Finalize());
-  vector<char> hash_data = signed_hasher.raw_hash();
+  chromeos::Blob hash_data = signed_hasher.raw_hash();
   PayloadVerifier::PadRSA2048SHA256Hash(&hash_data);
   TEST_AND_RETURN_VAL(ErrorCode::kDownloadPayloadPubKeyVerificationError,
                       !hash_data.empty());
@@ -1127,18 +1124,18 @@
 }
 
 bool DeltaPerformer::GetNewPartitionInfo(uint64_t* kernel_size,
-                                         vector<char>* kernel_hash,
+                                         chromeos::Blob* kernel_hash,
                                          uint64_t* rootfs_size,
-                                         vector<char>* rootfs_hash) {
+                                         chromeos::Blob* rootfs_hash) {
   TEST_AND_RETURN_FALSE(manifest_valid_ &&
                         manifest_.has_new_kernel_info() &&
                         manifest_.has_new_rootfs_info());
   *kernel_size = manifest_.new_kernel_info().size();
   *rootfs_size = manifest_.new_rootfs_info().size();
-  vector<char> new_kernel_hash(manifest_.new_kernel_info().hash().begin(),
-                               manifest_.new_kernel_info().hash().end());
-  vector<char> new_rootfs_hash(manifest_.new_rootfs_info().hash().begin(),
-                               manifest_.new_rootfs_info().hash().end());
+  chromeos::Blob new_kernel_hash(manifest_.new_kernel_info().hash().begin(),
+                                 manifest_.new_kernel_info().hash().end());
+  chromeos::Blob new_rootfs_hash(manifest_.new_rootfs_info().hash().begin(),
+                                 manifest_.new_rootfs_info().hash().end());
   kernel_hash->swap(new_kernel_hash);
   rootfs_hash->swap(new_rootfs_hash);
   return true;
@@ -1228,10 +1225,10 @@
     buffer_offset_ += buffer_.size();
 
   // Hash the content.
-  hash_calculator_.Update(&buffer_[0], buffer_.size());
+  hash_calculator_.Update(buffer_.data(), buffer_.size());
 
   // Swap content with an empty vector to ensure that all memory is released.
-  vector<char>().swap(buffer_);
+  chromeos::Blob().swap(buffer_);
 }
 
 bool DeltaPerformer::CanResumeUpdate(PrefsInterface* prefs,
diff --git a/delta_performer.h b/delta_performer.h
index 15659e7..eed24cb 100644
--- a/delta_performer.h
+++ b/delta_performer.h
@@ -11,6 +11,7 @@
 #include <vector>
 
 #include <base/time/time.h>
+#include <chromeos/secure_blob.h>
 #include <google/protobuf/repeated_field.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
@@ -123,9 +124,9 @@
   // false on failure (e.g., when the values are not present in the update
   // manifest).
   bool GetNewPartitionInfo(uint64_t* kernel_size,
-                           std::vector<char>* kernel_hash,
+                           chromeos::Blob* kernel_hash,
                            uint64_t* rootfs_size,
-                           std::vector<char>* rootfs_hash);
+                           chromeos::Blob* rootfs_hash);
 
   // Converts an ordered collection of Extent objects which contain data of
   // length full_length to a comma-separated string. For each Extent, the
@@ -158,7 +159,7 @@
   // kMetadataParseInsufficientData if more data is needed to parse the complete
   // metadata. Returns kMetadataParseError if the metadata can't be parsed given
   // the payload.
-  MetadataParseResult ParsePayloadMetadata(const std::vector<char>& payload,
+  MetadataParseResult ParsePayloadMetadata(const chromeos::Blob& payload,
                                            ErrorCode* error);
 
   void set_public_key_path(const std::string& public_key_path) {
@@ -239,8 +240,8 @@
   // so that a man-in-the-middle attack on the SSL connection to the payload
   // server doesn't exploit any vulnerability in the code that parses the
   // protocol buffer.
-  ErrorCode ValidateMetadataSignature(const char* protobuf,
-                                           uint64_t protobuf_length);
+  ErrorCode ValidateMetadataSignature(const void* protobuf,
+                                      uint64_t protobuf_length);
 
   // Returns true on success.
   bool PerformInstallOperation(
@@ -316,7 +317,7 @@
   // A buffer used for accumulating downloaded data. Initially, it stores the
   // payload metadata; once that's downloaded and parsed, it stores data for the
   // next update operation.
-  std::vector<char> buffer_;
+  chromeos::Blob buffer_;
   // Offset of buffer_ in the binary blobs section of the update.
   uint64_t buffer_offset_;
 
@@ -333,7 +334,7 @@
   std::string signed_hash_context_;
 
   // Signatures message blob extracted directly from the payload.
-  std::vector<char> signatures_message_data_;
+  chromeos::Blob signatures_message_data_;
 
   // The public key to be used. Provided as a member so that tests can
   // override with test keys.
diff --git a/delta_performer_unittest.cc b/delta_performer_unittest.cc
index af257df..b32ffc9 100644
--- a/delta_performer_unittest.cc
+++ b/delta_performer_unittest.cc
@@ -55,7 +55,8 @@
     "pLRtClp97kN2+tXGNBQqkA==";
 
 static const int kDefaultKernelSize = 4096;  // Something small for a test
-static const char* kNewDataString = "This is new data.";
+static const uint8_t kNewData[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
+                                   'n', 'e', 'w', ' ', 'd', 'a', 't', 'a', '.'};
 
 namespace {
 struct DeltaState {
@@ -67,13 +68,13 @@
   uint64_t metadata_size;
 
   string old_kernel;
-  vector<char> old_kernel_data;
+  chromeos::Blob old_kernel_data;
 
   string new_kernel;
-  vector<char> new_kernel_data;
+  chromeos::Blob new_kernel_data;
 
   // The in-memory copy of delta file.
-  vector<char> delta;
+  chromeos::Blob delta;
 
   // The mock system state object with which we initialize the
   // delta performer.
@@ -109,7 +110,7 @@
 }  // namespace
 
 static void CompareFilesByBlock(const string& a_file, const string& b_file) {
-  vector<char> a_data, b_data;
+  chromeos::Blob a_data, b_data;
   EXPECT_TRUE(utils::ReadFile(a_file, &a_data)) << "file failed: " << a_file;
   EXPECT_TRUE(utils::ReadFile(b_file, &b_data)) << "file failed: " << b_file;
 
@@ -117,8 +118,8 @@
   EXPECT_EQ(0, a_data.size() % kBlockSize);
   for (size_t i = 0; i < a_data.size(); i += kBlockSize) {
     EXPECT_EQ(0, i % kBlockSize);
-    vector<char> a_sub(&a_data[i], &a_data[i + kBlockSize]);
-    vector<char> b_sub(&b_data[i], &b_data[i + kBlockSize]);
+    chromeos::Blob a_sub(&a_data[i], &a_data[i + kBlockSize]);
+    chromeos::Blob b_sub(&b_data[i], &b_data[i + kBlockSize]);
     EXPECT_TRUE(a_sub == b_sub) << "Block " << (i/kBlockSize) << " differs";
   }
 }
@@ -135,10 +136,10 @@
 }
 
 static size_t GetSignatureSize(const string& private_key_path) {
-  const vector<char> data(1, 'x');
-  vector<char> hash;
+  const chromeos::Blob data(1, 'x');
+  chromeos::Blob hash;
   EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(data, &hash));
-  vector<char> signature;
+  chromeos::Blob signature;
   EXPECT_TRUE(PayloadSigner::SignHash(hash,
                                       private_key_path,
                                       &signature));
@@ -148,8 +149,8 @@
 static bool InsertSignaturePlaceholder(int signature_size,
                                        const string& payload_path,
                                        uint64_t* out_metadata_size) {
-  vector<vector<char>> signatures;
-  signatures.push_back(vector<char>(signature_size, 0));
+  vector<chromeos::Blob> signatures;
+  signatures.push_back(chromeos::Blob(signature_size, 0));
 
   return PayloadSigner::AddSignatureToPayload(
       payload_path,
@@ -161,18 +162,18 @@
 static void SignGeneratedPayload(const string& payload_path,
                                  uint64_t* out_metadata_size) {
   int signature_size = GetSignatureSize(kUnittestPrivateKeyPath);
-  vector<char> hash;
+  chromeos::Blob hash;
   ASSERT_TRUE(PayloadSigner::HashPayloadForSigning(
       payload_path,
       vector<int>(1, signature_size),
       &hash));
-  vector<char> signature;
+  chromeos::Blob signature;
   ASSERT_TRUE(PayloadSigner::SignHash(hash,
                                       kUnittestPrivateKeyPath,
                                       &signature));
   ASSERT_TRUE(PayloadSigner::AddSignatureToPayload(
       payload_path,
-      vector<vector<char>>(1, signature),
+      vector<chromeos::Blob>(1, signature),
       payload_path,
       out_metadata_size));
   EXPECT_TRUE(PayloadVerifier::VerifySignedPayload(
@@ -223,7 +224,7 @@
                 hash_file.c_str())));
 
   // Pad the hash
-  vector<char> hash;
+  chromeos::Blob hash;
   ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
   ASSERT_TRUE(PayloadVerifier::PadRSA2048SHA256Hash(&hash));
   ASSERT_TRUE(test_utils::WriteFileVector(hash_file, hash));
@@ -319,22 +320,22 @@
     string a_mnt;
     ScopedLoopMounter b_mounter(state->a_img, &a_mnt, 0);
 
-    vector<char> hardtocompress;
+    chromeos::Blob hardtocompress;
     while (hardtocompress.size() < 3 * kBlockSize) {
       hardtocompress.insert(hardtocompress.end(),
-                            kRandomString,
-                            kRandomString + sizeof(kRandomString) - 1);
+                            std::begin(kRandomString), std::end(kRandomString));
     }
     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
-                                              a_mnt.c_str()).c_str(),
+                                                    a_mnt.c_str()).c_str(),
                                  hardtocompress.data(),
                                  hardtocompress.size()));
 
-    vector<char> zeros(16 * 1024, 0);
+    chromeos::Blob zeros(16 * 1024, 0);
     EXPECT_EQ(zeros.size(),
               base::WriteFile(base::FilePath(base::StringPrintf(
                                   "%s/move-to-sparse", a_mnt.c_str())),
-                              zeros.data(), zeros.size()));
+                              reinterpret_cast<const char*>(zeros.data()),
+                              zeros.size()));
 
     EXPECT_TRUE(
         WriteSparseFile(base::StringPrintf("%s/move-from-sparse",
@@ -347,9 +348,9 @@
 
     // Write 1 MiB of 0xff to try to catch the case where writing a bsdiff
     // patch fails to zero out the final block.
-    vector<char> ones(1024 * 1024, 0xff);
+    chromeos::Blob ones(1024 * 1024, 0xff);
     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/ones",
-                                              a_mnt.c_str()).c_str(),
+                                                    a_mnt.c_str()).c_str(),
                                  ones.data(),
                                  ones.size()));
   }
@@ -390,11 +391,12 @@
         WriteSparseFile(base::StringPrintf("%s/move-to-sparse", b_mnt.c_str()),
                         16 * 1024));
 
-    vector<char> zeros(16 * 1024, 0);
+    chromeos::Blob zeros(16 * 1024, 0);
     EXPECT_EQ(zeros.size(),
               base::WriteFile(base::FilePath(base::StringPrintf(
                                   "%s/move-from-sparse", b_mnt.c_str())),
-                              zeros.data(), zeros.size()));
+                              reinterpret_cast<const char*>(zeros.data()),
+                              zeros.size()));
 
     EXPECT_EQ(0, System(base::StringPrintf("dd if=/dev/zero "
                                            "of=%s/move-semi-sparse "
@@ -415,11 +417,10 @@
         base::StringPrintf("rm %s/boguslink && echo foobar > %s/boguslink",
                            b_mnt.c_str(), b_mnt.c_str()).c_str()));
 
-    vector<char> hardtocompress;
+    chromeos::Blob hardtocompress;
     while (hardtocompress.size() < 3 * kBlockSize) {
       hardtocompress.insert(hardtocompress.end(),
-                            kRandomString,
-                            kRandomString + sizeof(kRandomString));
+                            std::begin(kRandomString), std::end(kRandomString));
     }
     EXPECT_TRUE(utils::WriteFile(base::StringPrintf("%s/hardtocompress",
                                               b_mnt.c_str()).c_str(),
@@ -443,7 +444,8 @@
   test_utils::FillWithData(&state->new_kernel_data);
 
   // change the new kernel data
-  strcpy(&state->new_kernel_data[0], kNewDataString);  // NOLINT(runtime/printf)
+  std::copy(std::begin(kNewData), std::end(kNewData),
+            state->new_kernel_data.begin());
 
   if (noop) {
     state->old_kernel_data = state->new_kernel_data;
@@ -758,26 +760,27 @@
   CompareFilesByBlock(state->old_kernel, state->new_kernel);
   CompareFilesByBlock(state->a_img, state->b_img);
 
-  vector<char> updated_kernel_partition;
+  chromeos::Blob updated_kernel_partition;
   EXPECT_TRUE(utils::ReadFile(state->old_kernel, &updated_kernel_partition));
-  EXPECT_EQ(0, strncmp(updated_kernel_partition.data(), kNewDataString,
-                       strlen(kNewDataString)));
+  ASSERT_GE(updated_kernel_partition.size(), arraysize(kNewData));
+  EXPECT_TRUE(std::equal(std::begin(kNewData), std::end(kNewData),
+                         updated_kernel_partition.begin()));
 
   uint64_t new_kernel_size;
-  vector<char> new_kernel_hash;
+  chromeos::Blob new_kernel_hash;
   uint64_t new_rootfs_size;
-  vector<char> new_rootfs_hash;
+  chromeos::Blob new_rootfs_hash;
   EXPECT_TRUE(performer->GetNewPartitionInfo(&new_kernel_size,
                                              &new_kernel_hash,
                                              &new_rootfs_size,
                                              &new_rootfs_hash));
   EXPECT_EQ(kDefaultKernelSize, new_kernel_size);
-  vector<char> expected_new_kernel_hash;
+  chromeos::Blob expected_new_kernel_hash;
   EXPECT_TRUE(OmahaHashCalculator::RawHashOfData(state->new_kernel_data,
                                                  &expected_new_kernel_hash));
   EXPECT_TRUE(expected_new_kernel_hash == new_kernel_hash);
   EXPECT_EQ(state->image_size, new_rootfs_size);
-  vector<char> expected_new_rootfs_hash;
+  chromeos::Blob expected_new_rootfs_hash;
   EXPECT_EQ(state->image_size,
             OmahaHashCalculator::RawHashOfFile(state->b_img,
                                                state->image_size,
@@ -880,7 +883,7 @@
   ScopedPathUnlinker new_kernel_unlinker(state.new_kernel);
 
   // Loads the payload and parses the manifest.
-  vector<char> payload;
+  chromeos::Blob payload;
   EXPECT_TRUE(utils::ReadFile(state.delta_path, &payload));
   LOG(INFO) << "Payload size: " << payload.size();
 
diff --git a/download_action.cc b/download_action.cc
index 35b1174..6f55220 100644
--- a/download_action.cc
+++ b/download_action.cc
@@ -99,7 +99,7 @@
   return true;
 }
 
-void DownloadAction::WriteToP2PFile(const char *data,
+void DownloadAction::WriteToP2PFile(const void *data,
                                     size_t length,
                                     off_t file_offset) {
   if (p2p_sharing_fd_ == -1) {
@@ -248,8 +248,8 @@
 }
 
 void DownloadAction::ReceivedBytes(HttpFetcher *fetcher,
-                                   const char* bytes,
-                                   int length) {
+                                   const void* bytes,
+                                   size_t length) {
   // Note that bytes_received_ is the current offset.
   if (!p2p_file_id_.empty()) {
     WriteToP2PFile(bytes, length, bytes_received_);
diff --git a/download_action.h b/download_action.h
index 3cf7e6a..52efb46 100644
--- a/download_action.h
+++ b/download_action.h
@@ -70,7 +70,7 @@
 
   // HttpFetcherDelegate methods (see http_fetcher.h)
   void ReceivedBytes(HttpFetcher *fetcher,
-                     const char* bytes, int length) override;
+                     const void* bytes, size_t length) override;
   void SeekToOffset(off_t offset) override;
   void TransferComplete(HttpFetcher *fetcher, bool successful) override;
   void TransferTerminated(HttpFetcher *fetcher) override;
@@ -103,7 +103,7 @@
   //
   // This method does nothing if SetupP2PSharingFd() hasn't been
   // called or if CloseP2PSharingFd() has been called.
-  void WriteToP2PFile(const char *data, size_t length, off_t file_offset);
+  void WriteToP2PFile(const void *data, size_t length, off_t file_offset);
 
   // The InstallPlan passed in
   InstallPlan install_plan_;
diff --git a/download_action_unittest.cc b/download_action_unittest.cc
index 0bb0732..4ecf377 100644
--- a/download_action_unittest.cc
+++ b/download_action_unittest.cc
@@ -63,7 +63,7 @@
                       ErrorCode code) override {
     ASSERT_TRUE(loop_);
     g_main_loop_quit(loop_);
-    vector<char> found_data;
+    chromeos::Blob found_data;
     ASSERT_TRUE(utils::ReadFile(path_, &found_data));
     if (expected_code_ != ErrorCode::kDownloadWriteError) {
       ASSERT_EQ(expected_data_.size(), found_data.size());
@@ -87,7 +87,7 @@
 
   GMainLoop *loop_;
   string path_;
-  vector<char> expected_data_;
+  chromeos::Blob expected_data_;
   bool processing_done_called_;
   ErrorCode expected_code_;
 };
@@ -110,12 +110,6 @@
   int current_write_;
 };
 
-struct EntryPointArgs {
-  const vector<char> *data;
-  GMainLoop *loop;
-  ActionProcessor *processor;
-};
-
 struct StartProcessorInRunLoopArgs {
   ActionProcessor* processor;
   MockHttpFetcher* http_fetcher;
@@ -131,7 +125,7 @@
   return FALSE;
 }
 
-void TestWithData(const vector<char>& data,
+void TestWithData(const chromeos::Blob& data,
                   int fail_write,
                   bool use_download_delegate) {
   GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
@@ -159,7 +153,7 @@
   ObjectFeederAction<InstallPlan> feeder_action;
   feeder_action.set_obj(install_plan);
   MockPrefs prefs;
-  MockHttpFetcher* http_fetcher = new MockHttpFetcher(&data[0],
+  MockHttpFetcher* http_fetcher = new MockHttpFetcher(data.data(),
                                                       data.size(),
                                                       nullptr);
   // takes ownership of passed in HttpFetcher
@@ -182,7 +176,7 @@
     expected_code = ErrorCode::kDownloadWriteError;
   DownloadActionTestProcessorDelegate delegate(expected_code);
   delegate.loop_ = loop;
-  delegate.expected_data_ = vector<char>(data.begin() + 1, data.end());
+  delegate.expected_data_ = chromeos::Blob(data.begin() + 1, data.end());
   delegate.path_ = output_temp_file.GetPath();
   ActionProcessor processor;
   processor.set_delegate(&delegate);
@@ -199,7 +193,7 @@
 }  // namespace
 
 TEST(DownloadActionTest, SimpleTest) {
-  vector<char> small;
+  chromeos::Blob small;
   const char* foo = "foo";
   small.insert(small.end(), foo, foo + strlen(foo));
   TestWithData(small,
@@ -208,7 +202,7 @@
 }
 
 TEST(DownloadActionTest, LargeTest) {
-  vector<char> big(5 * kMockHttpFetcherChunkSize);
+  chromeos::Blob big(5 * kMockHttpFetcherChunkSize);
   char c = '0';
   for (unsigned int i = 0; i < big.size(); i++) {
     big[i] = c;
@@ -220,7 +214,7 @@
 }
 
 TEST(DownloadActionTest, FailWriteTest) {
-  vector<char> big(5 * kMockHttpFetcherChunkSize);
+  chromeos::Blob big(5 * kMockHttpFetcherChunkSize);
   char c = '0';
   for (unsigned int i = 0; i < big.size(); i++) {
     big[i] = c;
@@ -232,7 +226,7 @@
 }
 
 TEST(DownloadActionTest, NoDownloadDelegateTest) {
-  vector<char> small;
+  chromeos::Blob small;
   const char* foo = "foofoo";
   small.insert(small.end(), foo, foo + strlen(foo));
   TestWithData(small,
@@ -261,8 +255,9 @@
 void TestTerminateEarly(bool use_download_delegate) {
   GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
 
-  vector<char> data(kMockHttpFetcherChunkSize + kMockHttpFetcherChunkSize / 2);
-  memset(&data[0], 0, data.size());
+  chromeos::Blob data(kMockHttpFetcherChunkSize +
+                      kMockHttpFetcherChunkSize / 2);
+  memset(data.data(), 0, data.size());
 
   ScopedTempFile temp_file;
   {
@@ -275,7 +270,7 @@
     feeder_action.set_obj(install_plan);
     MockPrefs prefs;
     DownloadAction download_action(&prefs, nullptr,
-                                   new MockHttpFetcher(&data[0],
+                                   new MockHttpFetcher(data.data(),
                                                        data.size(),
                                                        nullptr));
     download_action.SetTestFileWriter(&writer);
@@ -512,8 +507,8 @@
     BondActions(&feeder_action, download_action_.get());
     DownloadActionTestProcessorDelegate delegate(ErrorCode::kSuccess);
     delegate.loop_ = loop_;
-    delegate.expected_data_ = vector<char>(data_.begin() + start_at_offset_,
-                                           data_.end());
+    delegate.expected_data_ = chromeos::Blob(data_.begin() + start_at_offset_,
+                                             data_.end());
     delegate.path_ = output_temp_file.GetPath();
     processor_.set_delegate(&delegate);
     processor_.EnqueueAction(&feeder_action);
diff --git a/extent_writer.h b/extent_writer.h
index 0ea39fc..765bff6 100644
--- a/extent_writer.h
+++ b/extent_writer.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include <base/logging.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/file_descriptor.h"
 #include "update_engine/update_metadata.pb.h"
@@ -110,8 +111,8 @@
   bool EndImpl() {
     if (bytes_written_mod_block_size_) {
       const size_t write_size = block_size_ - bytes_written_mod_block_size_;
-      std::vector<char> zeros(write_size, 0);
-      TEST_AND_RETURN_FALSE(underlying_extent_writer_->Write(&zeros[0],
+      chromeos::Blob zeros(write_size, 0);
+      TEST_AND_RETURN_FALSE(underlying_extent_writer_->Write(zeros.data(),
                                                              write_size));
     }
     return underlying_extent_writer_->End();
diff --git a/extent_writer_unittest.cc b/extent_writer_unittest.cc
index 0a9020c..f6519b6 100644
--- a/extent_writer_unittest.cc
+++ b/extent_writer_unittest.cc
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include <chromeos/secure_blob.h>
 #include <gtest/gtest.h>
 
 #include "update_engine/payload_constants.h"
@@ -74,10 +75,10 @@
 
   EXPECT_EQ(kBlockSize + bytes.size(), utils::FileSize(path_));
 
-  vector<char> result_file;
+  chromeos::Blob result_file;
   EXPECT_TRUE(utils::ReadFile(path_, &result_file));
 
-  vector<char> expected_file(kBlockSize);
+  chromeos::Blob expected_file(kBlockSize);
   expected_file.insert(expected_file.end(),
                        bytes.data(), bytes.data() + bytes.size());
   ExpectVectorsEq(expected_file, result_file);
@@ -122,7 +123,7 @@
   extent.set_num_blocks(1);
   extents.push_back(extent);
 
-  vector<char> data(kBlockSize * 3);
+  chromeos::Blob data(kBlockSize * 3);
   test_utils::FillWithData(&data);
 
   DirectExtentWriter direct_writer;
@@ -141,10 +142,10 @@
 
   EXPECT_EQ(data.size(), utils::FileSize(path_));
 
-  vector<char> result_file;
+  chromeos::Blob result_file;
   EXPECT_TRUE(utils::ReadFile(path_, &result_file));
 
-  vector<char> expected_file;
+  chromeos::Blob expected_file;
   expected_file.insert(expected_file.end(),
                        data.begin() + kBlockSize,
                        data.begin() + kBlockSize * 2);
@@ -173,7 +174,7 @@
   extent.set_num_blocks(1);
   extents.push_back(extent);
 
-  vector<char> data(kBlockSize * 2);
+  chromeos::Blob data(kBlockSize * 2);
   test_utils::FillWithData(&data);
 
   DirectExtentWriter direct_writer;
@@ -185,15 +186,15 @@
   bytes_to_write -= missing_bytes;
   fd_->Seek(kBlockSize - missing_bytes, SEEK_SET);
   EXPECT_EQ(3, fd_->Write("xxx", 3));
-  ASSERT_TRUE(zero_pad_writer.Write(&data[0], bytes_to_write));
+  ASSERT_TRUE(zero_pad_writer.Write(data.data(), bytes_to_write));
   EXPECT_TRUE(zero_pad_writer.End());
 
   EXPECT_EQ(data.size(), utils::FileSize(path_));
 
-  vector<char> result_file;
+  chromeos::Blob result_file;
   EXPECT_TRUE(utils::ReadFile(path_, &result_file));
 
-  vector<char> expected_file;
+  chromeos::Blob expected_file;
   expected_file.insert(expected_file.end(),
                        data.begin() + kBlockSize,
                        data.begin() + kBlockSize * 2);
@@ -221,7 +222,7 @@
   const int block_count = 4;
   const int on_disk_count = 2;
 
-  vector<char> data(17);
+  chromeos::Blob data(17);
   test_utils::FillWithData(&data);
 
   DirectExtentWriter direct_writer;
@@ -231,7 +232,7 @@
   while (bytes_written < (block_count * kBlockSize)) {
     size_t bytes_to_write = min(block_count * kBlockSize - bytes_written,
                                 data.size());
-    EXPECT_TRUE(direct_writer.Write(&data[0], bytes_to_write));
+    EXPECT_TRUE(direct_writer.Write(data.data(), bytes_to_write));
     bytes_written += bytes_to_write;
   }
   EXPECT_TRUE(direct_writer.End());
@@ -239,13 +240,13 @@
   // check file size, then data inside
   ASSERT_EQ(2 * kBlockSize, utils::FileSize(path_));
 
-  vector<char> resultant_data;
+  chromeos::Blob resultant_data;
   EXPECT_TRUE(utils::ReadFile(path_, &resultant_data));
 
   // Create expected data
-  vector<char> expected_data(on_disk_count * kBlockSize);
-  vector<char> big(block_count * kBlockSize);
-  for (vector<char>::size_type i = 0; i < big.size(); i++) {
+  chromeos::Blob expected_data(on_disk_count * kBlockSize);
+  chromeos::Blob big(block_count * kBlockSize);
+  for (chromeos::Blob::size_type i = 0; i < big.size(); i++) {
     big[i] = data[i % data.size()];
   }
   memcpy(&expected_data[kBlockSize], &big[0], kBlockSize);
diff --git a/fake_file_writer.h b/fake_file_writer.h
index 6ba550d..751cbcf 100644
--- a/fake_file_writer.h
+++ b/fake_file_writer.h
@@ -8,6 +8,7 @@
 #include <vector>
 
 #include <base/macros.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/file_writer.h"
 
@@ -43,13 +44,13 @@
     return 0;
   }
 
-  const std::vector<char>& bytes() {
+  const chromeos::Blob& bytes() {
     return bytes_;
   }
 
  private:
   // The internal store of all bytes that have been written
-  std::vector<char> bytes_;
+  chromeos::Blob bytes_;
 
   // These are just to ensure FileWriter methods are called properly.
   bool was_opened_;
diff --git a/file_writer_unittest.cc b/file_writer_unittest.cc
index 8f4ab9e..5bdea3c 100644
--- a/file_writer_unittest.cc
+++ b/file_writer_unittest.cc
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include <gtest/gtest.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/test_utils.h"
 #include "update_engine/utils.h"
@@ -34,10 +35,10 @@
                                 O_CREAT | O_LARGEFILE | O_TRUNC | O_WRONLY,
                                 0644));
   EXPECT_TRUE(file_writer.Write("test", 4));
-  vector<char> actual_data;
+  chromeos::Blob actual_data;
   EXPECT_TRUE(utils::ReadFile(path, &actual_data));
 
-  EXPECT_FALSE(memcmp("test", &actual_data[0], actual_data.size()));
+  EXPECT_FALSE(memcmp("test", actual_data.data(), actual_data.size()));
   EXPECT_EQ(0, file_writer.Close());
 }
 
diff --git a/filesystem_copier_action.h b/filesystem_copier_action.h
index 679ee61..b0544b0 100644
--- a/filesystem_copier_action.h
+++ b/filesystem_copier_action.h
@@ -107,13 +107,13 @@
 
   // Ping-pong buffers for storing data we read/write. Only one buffer is being
   // read at a time and only one buffer is being written at a time.
-  std::vector<char> buffer_[2];
+  chromeos::Blob buffer_[2];
 
   // The state of each buffer.
   BufferState buffer_state_[2];
 
   // Number of valid elements in |buffer_| if its state is kBufferStateFull.
-  std::vector<char>::size_type buffer_valid_size_[2];
+  chromeos::Blob::size_type buffer_valid_size_[2];
 
   // The cancellable objects for the in-flight async calls.
   GCancellable* canceller_[2];
diff --git a/filesystem_copier_action_unittest.cc b/filesystem_copier_action_unittest.cc
index 5973fb6..5b4c3ab 100644
--- a/filesystem_copier_action_unittest.cc
+++ b/filesystem_copier_action_unittest.cc
@@ -139,12 +139,12 @@
 
   // Make random data for a, zero filled data for b.
   const size_t kLoopFileSize = 10 * 1024 * 1024 + 512;
-  vector<char> a_loop_data(kLoopFileSize);
+  chromeos::Blob a_loop_data(kLoopFileSize);
   test_utils::FillWithData(&a_loop_data);
-  vector<char> b_loop_data(run_out_of_space ?
-                           (kLoopFileSize - 1) :
-                           kLoopFileSize,
-                           '\0');  // Fill with 0s
+  chromeos::Blob b_loop_data(run_out_of_space ?
+                             (kLoopFileSize - 1) :
+                             kLoopFileSize,
+                             0);  // Fill with 0s
 
   // Write data to disk
   if (!(test_utils::WriteFileVector(a_loop_file, a_loop_data) &&
@@ -254,7 +254,7 @@
   EXPECT_EQ(ErrorCode::kSuccess, delegate.code());
 
   // Make sure everything in the out_image is there
-  vector<char> a_out;
+  chromeos::Blob a_out;
   if (!utils::ReadFile(a_dev, &a_out)) {
     ADD_FAILURE();
     return false;
@@ -264,7 +264,7 @@
   EXPECT_TRUE(is_a_file_reading_eq);
   success = success && is_a_file_reading_eq;
   if (!verify_hash) {
-    vector<char> b_out;
+    chromeos::Blob b_out;
     if (!utils::ReadFile(b_dev, &b_out)) {
       ADD_FAILURE();
       return false;
diff --git a/http_fetcher.h b/http_fetcher.h
index d291d6d..9eb477d 100644
--- a/http_fetcher.h
+++ b/http_fetcher.h
@@ -130,7 +130,7 @@
 
   // POST data for the transfer, and whether or not it was ever set
   bool post_data_set_;
-  std::vector<char> post_data_;
+  chromeos::Blob post_data_;
   HttpContentType post_content_type_;
 
   // The server's HTTP response code from the last transfer. This
@@ -173,8 +173,8 @@
 
   // Called every time bytes are received.
   virtual void ReceivedBytes(HttpFetcher* fetcher,
-                             const char* bytes,
-                             int length) = 0;
+                             const void* bytes,
+                             size_t length) = 0;
 
   // Called if the fetcher seeks to a particular offset.
   virtual void SeekToOffset(off_t offset) {}
diff --git a/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
index a45b10f..a50654e 100644
--- a/http_fetcher_unittest.cc
+++ b/http_fetcher_unittest.cc
@@ -226,7 +226,7 @@
   // Necessary to unhide the definition in the base class.
   using AnyHttpFetcherTest::NewLargeFetcher;
   HttpFetcher* NewLargeFetcher(size_t num_proxies) override {
-    vector<char> big_data(1000000);
+    chromeos::Blob big_data(1000000);
     CHECK_GT(num_proxies, 0u);
     proxy_resolver_.set_num_proxies(num_proxies);
     return new MockHttpFetcher(
@@ -368,7 +368,7 @@
       times_transfer_terminated_called_(0), times_received_bytes_called_(0) {}
 
   void ReceivedBytes(HttpFetcher* /* fetcher */,
-                     const char* /* bytes */, int /* length */) override {
+                     const void* /* bytes */, size_t /* length */) override {
     // Update counters
     times_received_bytes_called_++;
   }
@@ -495,7 +495,7 @@
 class PausingHttpFetcherTestDelegate : public HttpFetcherDelegate {
  public:
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* /* bytes */, int /* length */) override {
+                     const void* /* bytes */, size_t /* length */) override {
     CHECK(!paused_);
     paused_ = true;
     fetcher->Pause();
@@ -552,7 +552,7 @@
 class AbortingHttpFetcherTestDelegate : public HttpFetcherDelegate {
  public:
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes, int length) override {}
+                     const void* bytes, size_t length) override {}
   void TransferComplete(HttpFetcher* fetcher, bool successful) override {
     ADD_FAILURE();  // We should never get here
     g_main_loop_quit(loop_);
@@ -626,8 +626,8 @@
 class FlakyHttpFetcherTestDelegate : public HttpFetcherDelegate {
  public:
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes, int length) override {
-    data.append(bytes, length);
+                     const void* bytes, size_t length) override {
+    data.append(reinterpret_cast<const char*>(bytes), length);
   }
   void TransferComplete(HttpFetcher* fetcher, bool successful) override {
     EXPECT_TRUE(successful);
@@ -696,7 +696,7 @@
   }
 
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes, int length) override {
+                     const void* bytes, size_t length) override {
     if (server_) {
       LOG(INFO) << "Stopping server in ReceivedBytes";
       delete server_;
@@ -788,8 +788,8 @@
   explicit RedirectHttpFetcherTestDelegate(bool expected_successful)
       : expected_successful_(expected_successful) {}
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes, int length) override {
-    data.append(bytes, length);
+                     const void* bytes, size_t length) override {
+    data.append(reinterpret_cast<const char*>(bytes), length);
   }
   void TransferComplete(HttpFetcher* fetcher, bool successful) override {
     EXPECT_EQ(expected_successful_, successful);
@@ -893,9 +893,9 @@
       : expected_response_code_(expected_response_code) {}
 
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes, int length) override {
+                     const void* bytes, size_t length) override {
     EXPECT_EQ(fetcher, fetcher_.get());
-    data.append(bytes, length);
+    data.append(reinterpret_cast<const char*>(bytes), length);
   }
 
   void TransferComplete(HttpFetcher* fetcher, bool successful) override {
@@ -1090,7 +1090,7 @@
 class BlockedTransferTestDelegate : public HttpFetcherDelegate {
  public:
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes, int length) override {
+                     const void* bytes, size_t length) override {
     ADD_FAILURE();
   }
   void TransferComplete(HttpFetcher* fetcher, bool successful) override {
diff --git a/install_plan.h b/install_plan.h
index c592889..782f2ab 100644
--- a/install_plan.h
+++ b/install_plan.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include <base/macros.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/action.h"
 
@@ -62,8 +63,8 @@
   // applied partition sizes and hashes against the expected values.
   uint64_t kernel_size;
   uint64_t rootfs_size;
-  std::vector<char> kernel_hash;
-  std::vector<char> rootfs_hash;
+  chromeos::Blob kernel_hash;
+  chromeos::Blob rootfs_hash;
 
   // True if payload hash checks are mandatory based on the system state and
   // the Omaha response.
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index a7f6490..e32d925 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -92,7 +92,7 @@
   if (post_data_set_) {
     CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POST, 1), CURLE_OK);
     CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDS,
-                              &post_data_[0]),
+                              post_data_.data()),
              CURLE_OK);
     CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_POSTFIELDSIZE,
                               post_data_.size()),
@@ -383,7 +383,7 @@
   bytes_downloaded_ += payload_size;
   in_write_callback_ = true;
   if (delegate_)
-    delegate_->ReceivedBytes(this, reinterpret_cast<char*>(ptr), payload_size);
+    delegate_->ReceivedBytes(this, ptr, payload_size);
   in_write_callback_ = false;
   return payload_size;
 }
diff --git a/mock_certificate_checker.h b/mock_certificate_checker.h
index 5731062..8c26b42 100644
--- a/mock_certificate_checker.h
+++ b/mock_certificate_checker.h
@@ -18,7 +18,7 @@
                      bool(X509_STORE_CTX* x509_ctx,
                           int* out_depth,
                           unsigned int* out_digest_length,
-                          unsigned char* out_digest));
+                          uint8_t* out_digest));
 };
 
 }  // namespace chromeos_update_engine
diff --git a/mock_http_fetcher.h b/mock_http_fetcher.h
index b9d7cd7..c97eeb3 100644
--- a/mock_http_fetcher.h
+++ b/mock_http_fetcher.h
@@ -31,7 +31,7 @@
  public:
   // The data passed in here is copied and then passed to the delegate after
   // the transfer begins.
-  MockHttpFetcher(const char* data,
+  MockHttpFetcher(const uint8_t* data,
                   size_t size,
                   ProxyResolver* proxy_resolver)
       : HttpFetcher(proxy_resolver, &fake_system_state_),
@@ -46,6 +46,11 @@
     data_.insert(data_.end(), data, data + size);
   }
 
+  // Constructor overload for string data.
+  MockHttpFetcher(const char* data, size_t size, ProxyResolver* proxy_resolver)
+      : MockHttpFetcher(reinterpret_cast<const uint8_t*>(data), size,
+                        proxy_resolver) {}
+
   // Cleans up all internal state. Does not notify delegate
   ~MockHttpFetcher() override;
 
@@ -87,7 +92,7 @@
   // If set to true, this will EXPECT fail on BeginTransfer
   void set_never_use(bool never_use) { never_use_ = never_use; }
 
-  const std::vector<char>& post_data() const {
+  const chromeos::Blob& post_data() const {
     return post_data_;
   }
 
@@ -111,7 +116,7 @@
   void SignalTransferComplete();
 
   // A full copy of the data we'll return to the delegate
-  std::vector<char> data_;
+  chromeos::Blob data_;
 
   // The number of bytes we've sent so far
   size_t sent_size_;
diff --git a/multi_range_http_fetcher.cc b/multi_range_http_fetcher.cc
index 63b85c9..07118a3 100644
--- a/multi_range_http_fetcher.cc
+++ b/multi_range_http_fetcher.cc
@@ -74,8 +74,8 @@
 
 // State change: Downloading -> Downloading or Pending transfer ended
 void MultiRangeHttpFetcher::ReceivedBytes(HttpFetcher* fetcher,
-                                          const char* bytes,
-                                          int length) {
+                                          const void* bytes,
+                                          size_t length) {
   CHECK_LT(current_index_, ranges_.size());
   CHECK_EQ(fetcher, base_fetcher_.get());
   CHECK(!pending_transfer_ended_);
diff --git a/multi_range_http_fetcher.h b/multi_range_http_fetcher.h
index 1cdeb7b..0b6edfa 100644
--- a/multi_range_http_fetcher.h
+++ b/multi_range_http_fetcher.h
@@ -131,8 +131,8 @@
   // HttpFetcherDelegate overrides.
   // State change: Downloading -> Downloading or Pending transfer ended
   void ReceivedBytes(HttpFetcher* fetcher,
-                     const char* bytes,
-                     int length) override;
+                     const void* bytes,
+                     size_t length) override;
 
   // State change: Pending transfer ended -> Stopped
   void TransferEnded(HttpFetcher* fetcher, bool successful);
diff --git a/omaha_hash_calculator.cc b/omaha_hash_calculator.cc
index 49f2dae..4a919b8 100644
--- a/omaha_hash_calculator.cc
+++ b/omaha_hash_calculator.cc
@@ -24,7 +24,7 @@
 
 // Update is called with all of the data that should be hashed in order.
 // Mostly just passes the data through to OpenSSL's SHA256_Update()
-bool OmahaHashCalculator::Update(const char* data, size_t length) {
+bool OmahaHashCalculator::Update(const void* data, size_t length) {
   TEST_AND_RETURN_FALSE(valid_);
   TEST_AND_RETURN_FALSE(hash_.empty());
   static_assert(sizeof(size_t) <= sizeof(unsigned long),  // NOLINT(runtime/int)
@@ -40,7 +40,7 @@
   }
 
   const int kBufferSize = 128 * 1024;  // 128 KiB
-  vector<char> buffer(kBufferSize);
+  chromeos::Blob buffer(kBufferSize);
   off_t bytes_processed = 0;
   while (length < 0 || bytes_processed < length) {
     off_t bytes_to_read = buffer.size();
@@ -67,9 +67,7 @@
   TEST_AND_RETURN_FALSE(hash_.empty());
   TEST_AND_RETURN_FALSE(raw_hash_.empty());
   raw_hash_.resize(SHA256_DIGEST_LENGTH);
-  TEST_AND_RETURN_FALSE(
-      SHA256_Final(reinterpret_cast<unsigned char*>(&raw_hash_[0]),
-                   &ctx_) == 1);
+  TEST_AND_RETURN_FALSE(SHA256_Final(raw_hash_.data(), &ctx_) == 1);
 
   // Convert raw_hash_ to base64 encoding and store it in hash_.
   hash_ = chromeos::data_encoding::Base64Encode(raw_hash_.data(),
@@ -77,9 +75,9 @@
   return true;
 }
 
-bool OmahaHashCalculator::RawHashOfBytes(const char* data,
+bool OmahaHashCalculator::RawHashOfBytes(const void* data,
                                          size_t length,
-                                         vector<char>* out_hash) {
+                                         chromeos::Blob* out_hash) {
   OmahaHashCalculator calc;
   TEST_AND_RETURN_FALSE(calc.Update(data, length));
   TEST_AND_RETURN_FALSE(calc.Finalize());
@@ -87,13 +85,13 @@
   return true;
 }
 
-bool OmahaHashCalculator::RawHashOfData(const vector<char>& data,
-                                        vector<char>* out_hash) {
+bool OmahaHashCalculator::RawHashOfData(const chromeos::Blob& data,
+                                        chromeos::Blob* out_hash) {
   return RawHashOfBytes(data.data(), data.size(), out_hash);
 }
 
 off_t OmahaHashCalculator::RawHashOfFile(const string& name, off_t length,
-                                         vector<char>* out_hash) {
+                                         chromeos::Blob* out_hash) {
   OmahaHashCalculator calc;
   off_t res = calc.UpdateFile(name, length);
   if (res < 0) {
@@ -106,10 +104,9 @@
   return res;
 }
 
-string OmahaHashCalculator::OmahaHashOfBytes(
-    const void* data, size_t length) {
+string OmahaHashCalculator::OmahaHashOfBytes(const void* data, size_t length) {
   OmahaHashCalculator calc;
-  calc.Update(reinterpret_cast<const char*>(data), length);
+  calc.Update(data, length);
   calc.Finalize();
   return calc.hash();
 }
@@ -118,8 +115,8 @@
   return OmahaHashOfBytes(str.data(), str.size());
 }
 
-string OmahaHashCalculator::OmahaHashOfData(const vector<char>& data) {
-  return OmahaHashOfBytes(&data[0], data.size());
+string OmahaHashCalculator::OmahaHashOfData(const chromeos::Blob& data) {
+  return OmahaHashOfBytes(data.data(), data.size());
 }
 
 string OmahaHashCalculator::GetContext() const {
diff --git a/omaha_hash_calculator.h b/omaha_hash_calculator.h
index 4689bf7..a32ac18 100644
--- a/omaha_hash_calculator.h
+++ b/omaha_hash_calculator.h
@@ -13,6 +13,7 @@
 
 #include <base/logging.h>
 #include <base/macros.h>
+#include <chromeos/secure_blob.h>
 
 // Omaha uses base64 encoded SHA-256 as the hash. This class provides a simple
 // wrapper around OpenSSL providing such a formatted hash of data passed in.
@@ -29,7 +30,7 @@
   // Update is called with all of the data that should be hashed in order.
   // Update will read |length| bytes of |data|.
   // Returns true on success.
-  bool Update(const char* data, size_t length);
+  bool Update(const void* data, size_t length);
 
   // Updates the hash with up to |length| bytes of data from |file|. If |length|
   // is negative, reads in and updates with the whole file. Returns the number
@@ -48,7 +49,7 @@
     return hash_;
   }
 
-  const std::vector<char>& raw_hash() const {
+  const chromeos::Blob& raw_hash() const {
     DCHECK(!raw_hash_.empty()) << "Call Finalize() first";
     return raw_hash_;
   }
@@ -62,24 +63,24 @@
   // success, and false otherwise.
   bool SetContext(const std::string& context);
 
-  static bool RawHashOfBytes(const char* data,
+  static bool RawHashOfBytes(const void* data,
                              size_t length,
-                             std::vector<char>* out_hash);
-  static bool RawHashOfData(const std::vector<char>& data,
-                            std::vector<char>* out_hash);
+                             chromeos::Blob* out_hash);
+  static bool RawHashOfData(const chromeos::Blob& data,
+                            chromeos::Blob* out_hash);
   static off_t RawHashOfFile(const std::string& name, off_t length,
-                             std::vector<char>* out_hash);
+                             chromeos::Blob* out_hash);
 
   // Used by tests
   static std::string OmahaHashOfBytes(const void* data, size_t length);
   static std::string OmahaHashOfString(const std::string& str);
-  static std::string OmahaHashOfData(const std::vector<char>& data);
+  static std::string OmahaHashOfData(const chromeos::Blob& data);
 
  private:
   // If non-empty, the final base64 encoded hash and the raw hash. Will only be
   // set to non-empty when Finalize is called.
   std::string hash_;
-  std::vector<char> raw_hash_;
+  chromeos::Blob raw_hash_;
 
   // Init success
   bool valid_;
diff --git a/omaha_hash_calculator_unittest.cc b/omaha_hash_calculator_unittest.cc
index 08e8698..29a0e45 100644
--- a/omaha_hash_calculator_unittest.cc
+++ b/omaha_hash_calculator_unittest.cc
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include <chromeos/secure_blob.h>
 #include <glib.h>
 #include <gtest/gtest.h>
 
@@ -25,7 +26,7 @@
 // $ echo -n hi | openssl dgst -sha256 -binary | openssl base64
 static const char kExpectedHash[] =
     "j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ=";
-static const unsigned char kRawExpectedRawHash[] = {
+static const uint8_t kExpectedRawHash[] = {
   0x8f, 0x43, 0x43, 0x46, 0x64, 0x8f, 0x6b, 0x96,
   0xdf, 0x89, 0xdd, 0xa9, 0x01, 0xc5, 0x17, 0x6b,
   0x10, 0xa6, 0xd8, 0x39, 0x61, 0xdd, 0x3c, 0x1a,
@@ -34,13 +35,7 @@
 
 class OmahaHashCalculatorTest : public ::testing::Test {
  public:
-  const char *kExpectedRawHash;
-  const char *kExpectedRawHashEnd;
-
-  OmahaHashCalculatorTest() :
-    kExpectedRawHash(reinterpret_cast<const char*>(kRawExpectedRawHash)),
-    kExpectedRawHashEnd(kExpectedRawHash + arraysize(kRawExpectedRawHash))
-  {}
+  OmahaHashCalculatorTest() {}
 };
 
 TEST_F(OmahaHashCalculatorTest, SimpleTest) {
@@ -48,7 +43,8 @@
   calc.Update("hi", 2);
   calc.Finalize();
   EXPECT_EQ(kExpectedHash, calc.hash());
-  vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
+  chromeos::Blob raw_hash(std::begin(kExpectedRawHash),
+                          std::end(kExpectedRawHash));
   EXPECT_TRUE(raw_hash == calc.raw_hash());
 }
 
@@ -58,7 +54,8 @@
   calc.Update("i", 1);
   calc.Finalize();
   EXPECT_EQ(kExpectedHash, calc.hash());
-  vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
+  chromeos::Blob raw_hash(std::begin(kExpectedRawHash),
+                          std::end(kExpectedRawHash));
   EXPECT_TRUE(raw_hash == calc.raw_hash());
 }
 
@@ -72,7 +69,8 @@
   calc_next.Update("i", 1);
   calc_next.Finalize();
   EXPECT_EQ(kExpectedHash, calc_next.hash());
-  vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
+  chromeos::Blob raw_hash(std::begin(kExpectedRawHash),
+                          std::end(kExpectedRawHash));
   EXPECT_TRUE(raw_hash == calc_next.raw_hash());
 }
 
@@ -114,7 +112,8 @@
     EXPECT_EQ(2, calc.UpdateFile(data_path, kLengths[i]));
     EXPECT_TRUE(calc.Finalize());
     EXPECT_EQ(kExpectedHash, calc.hash());
-    vector<char> raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
+    chromeos::Blob raw_hash(std::begin(kExpectedRawHash),
+                            std::end(kExpectedRawHash));
     EXPECT_TRUE(raw_hash == calc.raw_hash());
   }
 
@@ -135,8 +134,9 @@
 
   static const int kLengths[] = { -1, 2, 10 };
   for (size_t i = 0; i < arraysize(kLengths); i++) {
-    vector<char> exp_raw_hash(kExpectedRawHash, kExpectedRawHashEnd);
-    vector<char> raw_hash;
+    chromeos::Blob exp_raw_hash(std::begin(kExpectedRawHash),
+                                std::end(kExpectedRawHash));
+    chromeos::Blob raw_hash;
     EXPECT_EQ(2, OmahaHashCalculator::RawHashOfFile(data_path,
                                                     kLengths[i],
                                                     &raw_hash));
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 7d7af81..0955983 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -527,10 +527,10 @@
 // We just store the response in the buffer. Once we've received all bytes,
 // we'll look in the buffer and decide what to do.
 void OmahaRequestAction::ReceivedBytes(HttpFetcher *fetcher,
-                                       const char* bytes,
-                                       int length) {
-  response_buffer_.reserve(response_buffer_.size() + length);
-  response_buffer_.insert(response_buffer_.end(), bytes, bytes + length);
+                                       const void* bytes,
+                                       size_t length) {
+  const uint8_t* byte_ptr = reinterpret_cast<const uint8_t*>(bytes);
+  response_buffer_.insert(response_buffer_.end(), byte_ptr, byte_ptr + length);
 }
 
 namespace {
@@ -797,8 +797,11 @@
   XML_SetUserData(parser, &parser_data);
   XML_SetElementHandler(parser, ParserHandlerStart, ParserHandlerEnd);
   XML_SetEntityDeclHandler(parser, ParserHandlerEntityDecl);
-  XML_Status res = XML_Parse(parser, &response_buffer_[0],
-                             response_buffer_.size(), XML_TRUE);
+  XML_Status res = XML_Parse(
+      parser,
+      reinterpret_cast<const char*>(response_buffer_.data()),
+      response_buffer_.size(),
+      XML_TRUE);
   XML_ParserFree(parser);
 
   if (res != XML_STATUS_OK || parser_data.failed) {
diff --git a/omaha_request_action.h b/omaha_request_action.h
index d086a24..b9f70f0 100644
--- a/omaha_request_action.h
+++ b/omaha_request_action.h
@@ -13,6 +13,7 @@
 #include <string>
 #include <vector>
 
+#include <chromeos/secure_blob.h>
 #include <curl/curl.h>
 
 #include "update_engine/action.h"
@@ -139,7 +140,7 @@
 
   // Delegate methods (see http_fetcher.h)
   void ReceivedBytes(HttpFetcher *fetcher,
-                     const char* bytes, int length) override;
+                     const void* bytes, size_t length) override;
 
   void TransferComplete(HttpFetcher *fetcher, bool successful) override;
 
@@ -285,7 +286,7 @@
   bool ping_only_;
 
   // Stores the response from the omaha server
-  std::vector<char> response_buffer_;
+  chromeos::Blob response_buffer_;
 
   // Initialized by InitPingDays to values that may be sent to Omaha
   // as part of a ping message. Note that only positive values and -1
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index 5bf48de..c40fa3b 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -79,9 +79,9 @@
                        metrics::CheckReaction expected_check_reaction,
                        metrics::DownloadErrorCode expected_download_error_code,
                        OmahaResponse* out_response,
-                       vector<char>* out_post_data);
+                       chromeos::Blob* out_post_data);
 
-  // Runs and checks a ping test. |ping_only| indicates wheter it should send
+  // Runs and checks a ping test. |ping_only| indicates whether it should send
   // only a ping or also an updatecheck.
   void PingTest(bool ping_only);
 
@@ -295,7 +295,7 @@
     metrics::CheckReaction expected_check_reaction,
     metrics::DownloadErrorCode expected_download_error_code,
     OmahaResponse* out_response,
-    vector<char>* out_post_data) {
+    chromeos::Blob* out_post_data) {
   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
   MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
                                                  http_response.size(),
@@ -355,7 +355,7 @@
 void TestEvent(OmahaRequestParams params,
                OmahaEvent* event,
                const string& http_response,
-               vector<char>* out_post_data) {
+               chromeos::Blob* out_post_data) {
   GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
   MockHttpFetcher* fetcher = new MockHttpFetcher(http_response.data(),
                                                  http_response.size(),
@@ -1035,7 +1035,7 @@
   EXPECT_EQ("&lt;&amp;&gt;", XmlEncode("<&>"));
   EXPECT_EQ("&amp;lt;&amp;amp;&amp;gt;", XmlEncode("&lt;&amp;&gt;"));
 
-  vector<char> post_data;
+  chromeos::Blob post_data;
 
   // Make sure XML Encode is being called on the params
   OmahaRequestParams params(&fake_system_state_,
@@ -1067,7 +1067,7 @@
                       &response,
                       &post_data));
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(post_str.find("testtheservice_pack&gt;"), string::npos);
   EXPECT_EQ(post_str.find("testtheservice_pack>"), string::npos);
   EXPECT_NE(post_str.find("x86 generic&lt;id"), string::npos);
@@ -1134,7 +1134,7 @@
 }
 
 TEST_F(OmahaRequestActionTest, FormatUpdateCheckOutputTest) {
-  vector<char> post_data;
+  chromeos::Blob post_data;
   NiceMock<MockPrefs> prefs;
   fake_system_state_.set_prefs(&prefs);
 
@@ -1152,7 +1152,7 @@
                                nullptr,  // response
                                &post_data));
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(post_str.find(
       "        <ping active=\"1\" a=\"-1\" r=\"-1\"></ping>\n"
       "        <updatecheck targetversionprefix=\"\"></updatecheck>\n"),
@@ -1167,13 +1167,13 @@
 
 
 TEST_F(OmahaRequestActionTest, FormatSuccessEventOutputTest) {
-  vector<char> post_data;
+  chromeos::Blob post_data;
   TestEvent(request_params_,
             new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
             "invalid xml>",
             &post_data);
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   string expected_event = base::StringPrintf(
       "        <event eventtype=\"%d\" eventresult=\"%d\"></event>\n",
       OmahaEvent::kTypeUpdateDownloadStarted,
@@ -1184,7 +1184,7 @@
 }
 
 TEST_F(OmahaRequestActionTest, FormatErrorEventOutputTest) {
-  vector<char> post_data;
+  chromeos::Blob post_data;
   TestEvent(request_params_,
             new OmahaEvent(OmahaEvent::kTypeDownloadComplete,
                            OmahaEvent::kResultError,
@@ -1192,7 +1192,7 @@
             "invalid xml>",
             &post_data);
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   string expected_event = base::StringPrintf(
       "        <event eventtype=\"%d\" eventresult=\"%d\" "
       "errorcode=\"%d\"></event>\n",
@@ -1233,7 +1233,7 @@
   for (int i = 0; i < 2; i++) {
     bool delta_okay = i == 1;
     const char* delta_okay_str = delta_okay ? "true" : "false";
-    vector<char> post_data;
+    chromeos::Blob post_data;
     OmahaRequestParams params(&fake_system_state_,
                               OmahaRequestParams::kOsPlatform,
                               OmahaRequestParams::kOsVersion,
@@ -1261,7 +1261,7 @@
                                  nullptr,
                                  &post_data));
     // convert post_data to string
-    string post_str(post_data.data(), post_data.size());
+    string post_str(post_data.begin(), post_data.end());
     EXPECT_NE(post_str.find(base::StringPrintf(" delta_okay=\"%s\"",
                                                delta_okay_str)),
               string::npos)
@@ -1273,7 +1273,7 @@
   for (int i = 0; i < 2; i++) {
     bool interactive = i == 1;
     const char* interactive_str = interactive ? "ondemandupdate" : "scheduler";
-    vector<char> post_data;
+    chromeos::Blob post_data;
     FakeSystemState fake_system_state;
     OmahaRequestParams params(&fake_system_state_,
                               OmahaRequestParams::kOsPlatform,
@@ -1302,7 +1302,7 @@
                                  nullptr,
                                  &post_data));
     // convert post_data to string
-    string post_str(&post_data[0], post_data.size());
+    string post_str(post_data.begin(), post_data.end());
     EXPECT_NE(post_str.find(base::StringPrintf("installsource=\"%s\"",
                                                interactive_str)),
               string::npos)
@@ -1346,7 +1346,7 @@
       .WillOnce(DoAll(SetArgumentPointee<1>(six_days_ago), Return(true)));
   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
       .WillOnce(DoAll(SetArgumentPointee<1>(five_days_ago), Return(true)));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
@@ -1358,7 +1358,7 @@
                       metrics::DownloadErrorCode::kUnset,
                       nullptr,
                       &post_data));
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(post_str.find("<ping active=\"1\" a=\"6\" r=\"5\"></ping>"),
             string::npos);
   if (ping_only) {
@@ -1393,7 +1393,7 @@
       .WillOnce(DoAll(SetArgumentPointee<1>(three_days_ago), Return(true)));
   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
       .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
@@ -1405,7 +1405,7 @@
                       metrics::DownloadErrorCode::kUnset,
                       nullptr,
                       &post_data));
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(post_str.find("<ping active=\"1\" a=\"3\"></ping>"),
             string::npos);
 }
@@ -1425,7 +1425,7 @@
       .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
   EXPECT_CALL(prefs, GetInt64(kPrefsLastRollCallPingDay, _))
       .WillOnce(DoAll(SetArgumentPointee<1>(four_days_ago), Return(true)));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
@@ -1437,7 +1437,7 @@
                       metrics::DownloadErrorCode::kUnset,
                       nullptr,
                       &post_data));
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(post_str.find("<ping active=\"1\" r=\"4\"></ping>\n"),
             string::npos);
 }
@@ -1462,7 +1462,7 @@
       .WillOnce(Return(true));
   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
       .WillOnce(Return(true));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
@@ -1474,7 +1474,7 @@
                       metrics::DownloadErrorCode::kUnset,
                       nullptr,
                       &post_data));
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_EQ(post_str.find("ping"), string::npos);
 }
 
@@ -1489,7 +1489,7 @@
       .WillOnce(DoAll(SetArgumentPointee<1>(now), Return(true)));
   EXPECT_CALL(prefs, SetInt64(kPrefsLastActivePingDay, _)).Times(0);
   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _)).Times(0);
-  vector<char> post_data;
+  chromeos::Blob post_data;
   EXPECT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
@@ -1522,7 +1522,7 @@
       .WillOnce(Return(true));
   EXPECT_CALL(prefs, SetInt64(kPrefsLastRollCallPingDay, _))
       .WillOnce(Return(true));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response "
@@ -1537,7 +1537,7 @@
                       metrics::DownloadErrorCode::kUnset,
                       nullptr,
                       &post_data));
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_EQ(post_str.find("ping"), string::npos);
 }
 
@@ -1623,7 +1623,7 @@
 }
 
 TEST_F(OmahaRequestActionTest, NoUniqueIDTest) {
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_FALSE(TestUpdateCheck(nullptr,  // request_params
                                "invalid xml>",
                                -1,
@@ -1635,7 +1635,7 @@
                                nullptr,  // response
                                &post_data));
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_EQ(post_str.find("machineid="), string::npos);
   EXPECT_EQ(post_str.find("userid="), string::npos);
 }
@@ -1797,7 +1797,7 @@
   ASSERT_EQ(0, System(string("mkdir -p ") + test_dir + "/etc"));
   ASSERT_EQ(0, System(string("mkdir -p ") + test_dir +
                       kStatefulPartition + "/etc"));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   NiceMock<MockPrefs> prefs;
   fake_system_state_.set_prefs(&prefs);
   ASSERT_TRUE(WriteFileString(
@@ -1828,7 +1828,7 @@
                                nullptr,  // response
                                &post_data));
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(string::npos, post_str.find(
       "appid=\"{22222222-2222-2222-2222-222222222222}\" "
       "version=\"0.0.0.0\" from_version=\"1.2.3.4\" "
@@ -1846,7 +1846,7 @@
   ASSERT_EQ(0, System(string("mkdir -p ") + test_dir + "/etc"));
   ASSERT_EQ(0, System(string("mkdir -p ") + test_dir +
                       kStatefulPartition + "/etc"));
-  vector<char> post_data;
+  chromeos::Blob post_data;
   NiceMock<MockPrefs> prefs;
   fake_system_state_.set_prefs(&prefs);
   ASSERT_TRUE(WriteFileString(
@@ -1876,7 +1876,7 @@
                                nullptr,  // response
                                &post_data));
   // convert post_data to string
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_NE(string::npos, post_str.find(
       "appid=\"{11111111-1111-1111-1111-111111111111}\" "
       "version=\"5.6.7.8\" "
@@ -1892,7 +1892,7 @@
   // Flag that the device was powerwashed in the past.
   fake_system_state_.fake_hardware()->SetPowerwashCount(1);
 
-  vector<char> post_data;
+  chromeos::Blob post_data;
   ASSERT_TRUE(
       TestUpdateCheck(nullptr,  // request_params
                       GetNoUpdateResponse(OmahaRequestParams::kAppId),
@@ -1905,7 +1905,7 @@
                       nullptr,
                       &post_data));
   // We shouldn't send a ping in this case since powerwash > 0.
-  string post_str(&post_data[0], post_data.size());
+  string post_str(post_data.begin(), post_data.end());
   EXPECT_EQ(string::npos, post_str.find("<ping"));
 }
 
diff --git a/payload_generator/delta_diff_generator.cc b/payload_generator/delta_diff_generator.cc
index 3a5e1eb..0791f4d 100644
--- a/payload_generator/delta_diff_generator.cc
+++ b/payload_generator/delta_diff_generator.cc
@@ -128,7 +128,7 @@
                    off_t chunk_size,
                    int data_fd,
                    off_t* data_file_size) {
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation operation;
 
   string old_path = (old_root == kEmptyPath) ? kEmptyPath :
@@ -172,7 +172,7 @@
     operation.set_data_length(data.size());
   }
 
-  TEST_AND_RETURN_FALSE(utils::WriteAll(data_fd, &data[0], data.size()));
+  TEST_AND_RETURN_FALSE(utils::WriteAll(data_fd, data.data(), data.size()));
   *data_file_size += data.size();
 
   // Now, insert into graph and blocks vector
@@ -336,8 +336,8 @@
 
   // Code will handle buffers of any size that's a multiple of kBlockSize,
   // so we arbitrarily set it to 1024 * kBlockSize.
-  vector<char> new_buf(1024 * kBlockSize);
-  vector<char> old_buf(1024 * kBlockSize);
+  chromeos::Blob new_buf(1024 * kBlockSize);
+  chromeos::Blob old_buf(1024 * kBlockSize);
 
   LOG(INFO) << "Scanning " << block_count << " unwritten blocks";
   vector<Extent> changed_extents;
@@ -355,15 +355,15 @@
       const uint64_t copy_first_block = extent.start_block() + blocks_read;
       const int copy_block_cnt =
           min(new_buf.size() / kBlockSize,
-              static_cast<vector<char>::size_type>(
+              static_cast<chromeos::Blob::size_type>(
                   extent.num_blocks() - blocks_read));
       const size_t count = copy_block_cnt * kBlockSize;
       const off_t offset = copy_first_block * kBlockSize;
-      ssize_t rc = pread(new_image_fd, &new_buf[0], count, offset);
+      ssize_t rc = pread(new_image_fd, new_buf.data(), count, offset);
       TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
       TEST_AND_RETURN_FALSE(static_cast<size_t>(rc) == count);
 
-      rc = pread(old_image_fd, &old_buf[0], count, offset);
+      rc = pread(old_image_fd, old_buf.data(), count, offset);
       TEST_AND_RETURN_FALSE_ERRNO(rc >= 0);
       TEST_AND_RETURN_FALSE(static_cast<size_t>(rc) == count);
 
@@ -407,7 +407,7 @@
 
   LOG(INFO) << "Compressed " << changed_block_count << " blocks ("
             << block_count - changed_block_count << " blocks unchanged)";
-  vector<char> compressed_data;
+  chromeos::Blob compressed_data;
   if (changed_block_count > 0) {
     LOG(INFO) << "Reading compressed data off disk";
     TEST_AND_RETURN_FALSE(utils::ReadFile(temp_file_path, &compressed_data));
@@ -426,7 +426,7 @@
                                    out_op->mutable_dst_extents());
 
   TEST_AND_RETURN_FALSE(utils::WriteAll(blobs_fd,
-                                        &compressed_data[0],
+                                        compressed_data.data(),
                                         compressed_data.size()));
   LOG(INFO) << "Done processing unwritten blocks";
   return true;
@@ -503,7 +503,7 @@
   LOG_IF(INFO, old_kernel_part.empty()) << "Generating full kernel update...";
 
   DeltaArchiveManifest_InstallOperation op;
-  vector<char> data;
+  chromeos::Blob data;
   TEST_AND_RETURN_FALSE(
       DeltaDiffGenerator::ReadFileToDiff(old_kernel_part,
                                          new_kernel_part,
@@ -535,7 +535,7 @@
   ops->clear();
   ops->push_back(op);
 
-  TEST_AND_RETURN_FALSE(utils::WriteAll(blobs_fd, &data[0], data.size()));
+  TEST_AND_RETURN_FALSE(utils::WriteAll(blobs_fd, data.data(), data.size()));
   *blobs_length += data.size();
 
   LOG(INFO) << "Done delta compressing kernel partition: "
@@ -708,11 +708,11 @@
     off_t chunk_offset,
     off_t chunk_size,
     bool bsdiff_allowed,
-    vector<char>* out_data,
+    chromeos::Blob* out_data,
     DeltaArchiveManifest_InstallOperation* out_op,
     bool gather_extents) {
   // Read new data in
-  vector<char> new_data;
+  chromeos::Blob new_data;
   TEST_AND_RETURN_FALSE(
       utils::ReadFileChunk(new_filename, chunk_offset, chunk_size, &new_data));
 
@@ -720,11 +720,11 @@
   TEST_AND_RETURN_FALSE(chunk_size == -1 ||
                         static_cast<off_t>(new_data.size()) <= chunk_size);
 
-  vector<char> new_data_bz;
+  chromeos::Blob new_data_bz;
   TEST_AND_RETURN_FALSE(BzipCompress(new_data, &new_data_bz));
   CHECK(!new_data_bz.empty());
 
-  vector<char> data;  // Data blob that will be written to delta file.
+  chromeos::Blob data;  // Data blob that will be written to delta file.
 
   DeltaArchiveManifest_InstallOperation operation;
   size_t current_best_size = 0;
@@ -747,7 +747,7 @@
     original = false;
   }
 
-  vector<char> old_data;
+  chromeos::Blob old_data;
   if (original) {
     // Read old data
     TEST_AND_RETURN_FALSE(
@@ -766,18 +766,18 @@
       ScopedPathUnlinker old_unlinker(old_chunk.value());
       TEST_AND_RETURN_FALSE(
           utils::WriteFile(old_chunk.value().c_str(),
-                           &old_data[0], old_data.size()));
+                           old_data.data(), old_data.size()));
       base::FilePath new_chunk;
       TEST_AND_RETURN_FALSE(base::CreateTemporaryFile(&new_chunk));
       ScopedPathUnlinker new_unlinker(new_chunk.value());
       TEST_AND_RETURN_FALSE(
           utils::WriteFile(new_chunk.value().c_str(),
-                           &new_data[0], new_data.size()));
+                           new_data.data(), new_data.size()));
 
-      vector<char> bsdiff_delta;
+      chromeos::Blob bsdiff_delta;
       TEST_AND_RETURN_FALSE(
           BsdiffFiles(old_chunk.value(), new_chunk.value(), &bsdiff_delta));
-      CHECK_GT(bsdiff_delta.size(), static_cast<vector<char>::size_type>(0));
+      CHECK_GT(bsdiff_delta.size(), static_cast<chromeos::Blob::size_type>(0));
       if (bsdiff_delta.size() < current_best_size) {
         operation.set_type(DeltaArchiveManifest_InstallOperation_Type_BSDIFF);
         current_best_size = bsdiff_delta.size();
@@ -863,7 +863,7 @@
   OmahaHashCalculator hasher;
   TEST_AND_RETURN_FALSE(hasher.UpdateFile(partition, size) == size);
   TEST_AND_RETURN_FALSE(hasher.Finalize());
-  const vector<char>& hash = hasher.raw_hash();
+  const chromeos::Blob& hash = hasher.raw_hash();
   info->set_hash(hash.data(), hash.size());
   LOG(INFO) << partition << ": size=" << size << " hash=" << hasher.hash();
   return true;
@@ -1422,15 +1422,15 @@
     if (!op->has_data_offset())
       continue;
     CHECK(op->has_data_length());
-    vector<char> buf(op->data_length());
-    ssize_t rc = pread(in_fd, &buf[0], buf.size(), op->data_offset());
+    chromeos::Blob buf(op->data_length());
+    ssize_t rc = pread(in_fd, buf.data(), buf.size(), op->data_offset());
     TEST_AND_RETURN_FALSE(rc == static_cast<ssize_t>(buf.size()));
 
     // Add the hash of the data blobs for this operation
     TEST_AND_RETURN_FALSE(AddOperationHash(op, buf));
 
     op->set_data_offset(out_file_size);
-    TEST_AND_RETURN_FALSE(writer.Write(&buf[0], buf.size()));
+    TEST_AND_RETURN_FALSE(writer.Write(buf.data(), buf.size()));
     out_file_size += buf.size();
   }
   return true;
@@ -1438,13 +1438,13 @@
 
 bool DeltaDiffGenerator::AddOperationHash(
     DeltaArchiveManifest_InstallOperation* op,
-    const vector<char>& buf) {
+    const chromeos::Blob& buf) {
   OmahaHashCalculator hasher;
 
-  TEST_AND_RETURN_FALSE(hasher.Update(&buf[0], buf.size()));
+  TEST_AND_RETURN_FALSE(hasher.Update(buf.data(), buf.size()));
   TEST_AND_RETURN_FALSE(hasher.Finalize());
 
-  const vector<char>& hash = hasher.raw_hash();
+  const chromeos::Blob& hash = hasher.raw_hash();
   op->set_data_sha256_hash(hash.data(), hash.size());
   return true;
 }
@@ -1844,12 +1844,12 @@
   // Write signature blob.
   if (!private_key_path.empty()) {
     LOG(INFO) << "Signing the update...";
-    vector<char> signature_blob;
+    chromeos::Blob signature_blob;
     TEST_AND_RETURN_FALSE(PayloadSigner::SignPayload(
         output_path,
         vector<string>(1, private_key_path),
         &signature_blob));
-    TEST_AND_RETURN_FALSE(writer.Write(&signature_blob[0],
+    TEST_AND_RETURN_FALSE(writer.Write(signature_blob.data(),
                                        signature_blob.size()));
   }
 
@@ -1866,7 +1866,7 @@
 // 'out'. Returns true on success.
 bool DeltaDiffGenerator::BsdiffFiles(const string& old_file,
                                      const string& new_file,
-                                     vector<char>* out) {
+                                     chromeos::Blob* out) {
   const string kPatchFile = "delta.patchXXXXXX";
   string patch_file_path;
 
@@ -1880,7 +1880,7 @@
   cmd.push_back(patch_file_path);
 
   int rc = 1;
-  vector<char> patch_file;
+  chromeos::Blob patch_file;
   TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &rc, nullptr));
   TEST_AND_RETURN_FALSE(rc == 0);
   TEST_AND_RETURN_FALSE(utils::ReadFile(patch_file_path, out));
diff --git a/payload_generator/delta_diff_generator.h b/payload_generator/delta_diff_generator.h
index 109004e..a6dfa6a 100644
--- a/payload_generator/delta_diff_generator.h
+++ b/payload_generator/delta_diff_generator.h
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include <base/macros.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/payload_generator/graph_types.h"
 #include "update_engine/update_metadata.pb.h"
@@ -118,7 +119,7 @@
                              off_t chunk_offset,
                              off_t chunk_size,
                              bool bsdiff_allowed,
-                             std::vector<char>* out_data,
+                             chromeos::Blob* out_data,
                              DeltaArchiveManifest_InstallOperation* out_op,
                              bool gather_extents);
 
@@ -196,7 +197,7 @@
   // blob will not be available at payload creation time. So, update_engine will
   // gracefully ignore the dummy signature operation.
   static bool AddOperationHash(DeltaArchiveManifest_InstallOperation* op,
-                               const std::vector<char>& buf);
+                               const chromeos::Blob& buf);
 
   // Handles allocation of temp blocks to a cut edge by converting the
   // dest node to a full op. This removes the need for temp blocks, but
@@ -246,7 +247,7 @@
   // |out|. Returns true on success.
   static bool BsdiffFiles(const std::string& old_file,
                           const std::string& new_file,
-                          std::vector<char>* out);
+                          chromeos::Blob* out);
 
   // The |blocks| vector contains a reader and writer for each block on the
   // filesystem that's being in-place updated. We populate the reader/writer
diff --git a/payload_generator/delta_diff_generator_unittest.cc b/payload_generator/delta_diff_generator_unittest.cc
index 9febf70..88e1b75 100644
--- a/payload_generator/delta_diff_generator_unittest.cc
+++ b/payload_generator/delta_diff_generator_unittest.cc
@@ -88,7 +88,7 @@
   EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
                                reinterpret_cast<const char*>(kRandomString),
                                sizeof(kRandomString)));
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation op;
   EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
                                                  new_path(),
@@ -178,7 +178,7 @@
   EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
                                random_data.c_str(), file_len));
 
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation op;
   EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
                                                  new_path(),
@@ -242,7 +242,7 @@
   EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
                                reinterpret_cast<const char*>(kRandomString),
                                sizeof(kRandomString)));
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation op;
   EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
                                                  new_path(),
@@ -274,7 +274,7 @@
   EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
                                reinterpret_cast<const char*>(kRandomString),
                                sizeof(kRandomString)));
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation op;
 
   EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
@@ -300,7 +300,7 @@
   EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
                                reinterpret_cast<const char*>(kRandomString),
                                sizeof(kRandomString)));
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation op;
 
   EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
@@ -320,15 +320,14 @@
 }
 
 TEST_F(DeltaDiffGeneratorTest, RunAsRootReplaceSmallTest) {
-  vector<char> new_data;
+  chromeos::Blob new_data;
   for (int i = 0; i < 2; i++) {
     new_data.insert(new_data.end(),
-                    kRandomString,
-                    kRandomString + sizeof(kRandomString));
+                    std::begin(kRandomString), std::end(kRandomString));
     EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
-                                 &new_data[0],
+                                 new_data.data(),
                                  new_data.size()));
-    vector<char> data;
+    chromeos::Blob data;
     DeltaArchiveManifest_InstallOperation op;
     EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
                                                    new_path(),
@@ -362,7 +361,7 @@
   EXPECT_TRUE(utils::WriteFile(new_path().c_str(),
                                reinterpret_cast<const char*>(kRandomString),
                                sizeof(kRandomString)));
-  vector<char> data;
+  chromeos::Blob data;
   DeltaArchiveManifest_InstallOperation op;
   EXPECT_TRUE(DeltaDiffGenerator::ReadFileToDiff(old_path(),
                                                  new_path(),
@@ -713,7 +712,7 @@
   ScopedDirRemover temp_dir_remover(temp_dir);
 
   const size_t kBlockSize = 4096;
-  vector<char> temp_data(kBlockSize * 50);
+  chromeos::Blob temp_data(kBlockSize * 50);
   FillWithData(&temp_data);
   EXPECT_TRUE(WriteFileVector(temp_dir + kFilename, temp_data));
   ScopedPathUnlinker filename_unlinker(temp_dir + kFilename);
@@ -830,7 +829,7 @@
   ScopedDirRemover temp_dir_remover(temp_dir);
 
   const size_t kBlockSize = 4096;
-  vector<char> temp_data(kBlockSize);
+  chromeos::Blob temp_data(kBlockSize);
   FillWithData(&temp_data);
   EXPECT_TRUE(WriteFileVector(temp_dir + kFilename, temp_data));
   ScopedPathUnlinker filename_unlinker(temp_dir + kFilename);
@@ -1091,7 +1090,7 @@
   ScopedDirRemover temp_dir_remover(temp_dir);
 
   const size_t kBlockSize = 4096;
-  vector<char> temp_data(kBlockSize * 3);
+  chromeos::Blob temp_data(kBlockSize * 3);
   FillWithData(&temp_data);
   EXPECT_TRUE(WriteFileVector(temp_dir + kFilename, temp_data));
   ScopedPathUnlinker filename_unlinker(temp_dir + kFilename);
diff --git a/payload_generator/full_update_generator.cc b/payload_generator/full_update_generator.cc
index 2b114f7..f1d6b23 100644
--- a/payload_generator/full_update_generator.cc
+++ b/payload_generator/full_update_generator.cc
@@ -40,8 +40,8 @@
   ~ChunkProcessor() { Wait(); }
 
   off_t offset() const { return offset_; }
-  const vector<char>& buffer_in() const { return buffer_in_; }
-  const vector<char>& buffer_compressed() const { return buffer_compressed_; }
+  const chromeos::Blob& buffer_in() const { return buffer_in_; }
+  const chromeos::Blob& buffer_compressed() const { return buffer_compressed_; }
 
   // Starts the processor. Returns true on success, false on failure.
   bool Start();
@@ -63,8 +63,8 @@
   GThread* thread_;
   int fd_;
   off_t offset_;
-  vector<char> buffer_in_;
-  vector<char> buffer_compressed_;
+  chromeos::Blob buffer_in_;
+  chromeos::Blob buffer_compressed_;
 
   DISALLOW_COPY_AND_ASSIGN(ChunkProcessor);
 };
@@ -174,13 +174,14 @@
       }
 
       const bool compress = processor->ShouldCompress();
-      const vector<char>& use_buf =
+      const chromeos::Blob& use_buf =
           compress ? processor->buffer_compressed() : processor->buffer_in();
       op->set_type(compress ?
                    DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ :
                    DeltaArchiveManifest_InstallOperation_Type_REPLACE);
       op->set_data_offset(*data_file_size);
-      TEST_AND_RETURN_FALSE(utils::WriteAll(fd, &use_buf[0], use_buf.size()));
+      TEST_AND_RETURN_FALSE(utils::WriteAll(fd, use_buf.data(),
+                                            use_buf.size()));
       *data_file_size += use_buf.size();
       op->set_data_length(use_buf.size());
       Extent* dst_extent = op->add_dst_extents();
diff --git a/payload_generator/full_update_generator_unittest.cc b/payload_generator/full_update_generator_unittest.cc
index 95a40ae..9f4aad5 100644
--- a/payload_generator/full_update_generator_unittest.cc
+++ b/payload_generator/full_update_generator_unittest.cc
@@ -26,8 +26,8 @@
 
 
 TEST(FullUpdateGeneratorTest, RunTest) {
-  vector<char> new_root(20 * 1024 * 1024);
-  vector<char> new_kern(16 * 1024 * 1024);
+  chromeos::Blob new_root(20 * 1024 * 1024);
+  chromeos::Blob new_kern(16 * 1024 * 1024);
   const off_t kChunkSize = 128 * 1024;
   FillWithData(&new_root);
   FillWithData(&new_kern);
diff --git a/payload_generator/generate_delta_main.cc b/payload_generator/generate_delta_main.cc
index c0dfe18..cbcbaf0 100644
--- a/payload_generator/generate_delta_main.cc
+++ b/payload_generator/generate_delta_main.cc
@@ -103,7 +103,7 @@
   LOG_IF(FATAL, out_hash_file.empty())
       << "Must pass --out_hash_file to calculate hash for signing.";
 
-  vector<char> hash;
+  chromeos::Blob hash;
   bool result = PayloadSigner::HashPayloadForSigning(in_file, sizes,
                                                      &hash);
   CHECK(result);
@@ -123,7 +123,7 @@
   LOG_IF(FATAL, out_metadata_hash_file.empty())
       << "Must pass --out_metadata_hash_file to calculate metadata hash.";
 
-  vector<char> hash;
+  chromeos::Blob hash;
   bool result = PayloadSigner::HashMetadataForSigning(in_file, sizes,
                                                       &hash);
   CHECK(result);
@@ -145,11 +145,11 @@
       << "Must pass --out_file to sign payload.";
   LOG_IF(FATAL, signature_file.empty())
       << "Must pass --signature_file to sign payload.";
-  vector<vector<char>> signatures;
+  vector<chromeos::Blob> signatures;
   vector<string> signature_files;
   base::SplitString(signature_file, ':', &signature_files);
   for (const string& signature_file : signature_files) {
-    vector<char> signature;
+    chromeos::Blob signature;
     CHECK(utils::ReadFile(signature_file, &signature));
     signatures.push_back(signature);
   }
@@ -201,16 +201,16 @@
   DeltaPerformer performer(&prefs, nullptr, &install_plan);
   CHECK_EQ(performer.Open(old_image.c_str(), 0, 0), 0);
   CHECK(performer.OpenKernel(old_kernel.c_str()));
-  vector<char> buf(1024 * 1024);
+  chromeos::Blob buf(1024 * 1024);
   int fd = open(in_file.c_str(), O_RDONLY, 0);
   CHECK_GE(fd, 0);
   ScopedFdCloser fd_closer(&fd);
   for (off_t offset = 0;; offset += buf.size()) {
     ssize_t bytes_read;
-    CHECK(utils::PReadAll(fd, &buf[0], buf.size(), offset, &bytes_read));
+    CHECK(utils::PReadAll(fd, buf.data(), buf.size(), offset, &bytes_read));
     if (bytes_read == 0)
       break;
-    CHECK_EQ(performer.Write(&buf[0], bytes_read), bytes_read);
+    CHECK_EQ(performer.Write(buf.data(), bytes_read), bytes_read);
   }
   CHECK_EQ(performer.Close(), 0);
   DeltaPerformer::ResetUpdateProgress(&prefs, false);
diff --git a/payload_generator/metadata.cc b/payload_generator/metadata.cc
index 4e0265a..7a6493c 100644
--- a/payload_generator/metadata.cc
+++ b/payload_generator/metadata.cc
@@ -36,7 +36,7 @@
 // Read data from the specified extents.
 bool ReadExtentsData(const ext2_filsys fs,
                      const vector<Extent>& extents,
-                     vector<char>* data) {
+                     chromeos::Blob* data) {
   // Resize the data buffer to hold all data in the extents
   size_t num_data_blocks = 0;
   for (const Extent& extent : extents) {
@@ -69,9 +69,9 @@
 }
 
 // Compute the bsdiff between two metadata blobs.
-bool ComputeMetadataBsdiff(const vector<char>& old_metadata,
-                           const vector<char>& new_metadata,
-                           vector<char>* bsdiff_delta) {
+bool ComputeMetadataBsdiff(const chromeos::Blob& old_metadata,
+                           const chromeos::Blob& new_metadata,
+                           chromeos::Blob* bsdiff_delta) {
   const string kTempFileTemplate("CrAU_temp_data.XXXXXX");
 
   // Write the metadata buffers to temporary files
@@ -83,7 +83,7 @@
   ScopedPathUnlinker temp_old_file_path_unlinker(temp_old_file_path);
   ScopedFdCloser old_fd_closer(&old_fd);
   TEST_AND_RETURN_FALSE(utils::WriteAll(old_fd,
-                                        &old_metadata[0],
+                                        old_metadata.data(),
                                         old_metadata.size()));
 
   int new_fd;
@@ -94,7 +94,7 @@
   ScopedPathUnlinker temp_new_file_path_unlinker(temp_new_file_path);
   ScopedFdCloser new_fd_closer(&new_fd);
   TEST_AND_RETURN_FALSE(utils::WriteAll(new_fd,
-                                        &new_metadata[0],
+                                        new_metadata.data(),
                                         new_metadata.size()));
 
   // Perform bsdiff on these files
@@ -115,19 +115,19 @@
                         const vector<Extent>& extents,
                         int data_fd,
                         off_t* data_file_size) {
-  vector<char> data;  // Data blob that will be written to delta file.
+  chromeos::Blob data;  // Data blob that will be written to delta file.
   DeltaArchiveManifest_InstallOperation op;
 
   {
     // Read in the metadata blocks from the old and new image.
-    vector<char> old_data;
+    chromeos::Blob old_data;
     TEST_AND_RETURN_FALSE(ReadExtentsData(fs_old, extents, &old_data));
 
-    vector<char> new_data;
+    chromeos::Blob new_data;
     TEST_AND_RETURN_FALSE(ReadExtentsData(fs_new, extents, &new_data));
 
     // Determine the best way to compress this.
-    vector<char> new_data_bz;
+    chromeos::Blob new_data_bz;
     TEST_AND_RETURN_FALSE(BzipCompress(new_data, &new_data_bz));
     CHECK(!new_data_bz.empty());
 
@@ -149,11 +149,11 @@
       data.clear();
     } else {
       // Try bsdiff of old to new data
-      vector<char> bsdiff_delta;
+      chromeos::Blob bsdiff_delta;
       TEST_AND_RETURN_FALSE(ComputeMetadataBsdiff(old_data,
                                                   new_data,
                                                   &bsdiff_delta));
-      CHECK_GT(bsdiff_delta.size(), static_cast<vector<char>::size_type>(0));
+      CHECK_GT(bsdiff_delta.size(), 0u);
 
       if (bsdiff_delta.size() < current_best_size) {
         op.set_type(DeltaArchiveManifest_InstallOperation_Type_BSDIFF);
@@ -182,7 +182,7 @@
     op.set_data_length(data.size());
   }
 
-  TEST_AND_RETURN_FALSE(utils::WriteAll(data_fd, &data[0], data.size()));
+  TEST_AND_RETURN_FALSE(utils::WriteAll(data_fd, data.data(), data.size()));
   *data_file_size += data.size();
 
   // Now, insert into graph and blocks vector
diff --git a/payload_generator/payload_signer.cc b/payload_generator/payload_signer.cc
index f3cc4de..6e0b4ee 100644
--- a/payload_generator/payload_signer.cc
+++ b/payload_generator/payload_signer.cc
@@ -26,8 +26,8 @@
 
 // Given raw |signatures|, packs them into a protobuf and serializes it into a
 // binary blob. Returns true on success, false otherwise.
-bool ConvertSignatureToProtobufBlob(const vector<vector<char>>& signatures,
-                                    vector<char>* out_signature_blob) {
+bool ConvertSignatureToProtobufBlob(const vector<chromeos::Blob>& signatures,
+                                    chromeos::Blob* out_signature_blob) {
   // Pack it into a protobuf
   Signatures out_message;
   uint32_t version = kSignatureMessageOriginalVersion;
@@ -37,7 +37,7 @@
       << kSignatureMessageOriginalVersion << ", "
       << kSignatureMessageCurrentVersion << "] inclusive, but you only "
       << "provided " << signatures.size() << " signatures.";
-  for (const vector<char>& signature : signatures) {
+  for (const chromeos::Blob& signature : signatures) {
     Signatures_Signature* sig_message = out_message.add_signatures();
     sig_message->set_version(version++);
     sig_message->set_data(signature.data(), signature.size());
@@ -61,14 +61,14 @@
 // true on success, false otherwise.
 bool AddSignatureOpToPayload(const string& payload_path,
                              uint64_t signature_blob_size,
-                             vector<char>* out_payload,
+                             chromeos::Blob* out_payload,
                              uint64_t* out_metadata_size,
                              uint64_t* out_signatures_offset) {
   const int kProtobufOffset = 20;
   const int kProtobufSizeOffset = 12;
 
   // Loads the payload.
-  vector<char> payload;
+  chromeos::Blob payload;
   DeltaArchiveManifest manifest;
   uint64_t metadata_size;
   TEST_AND_RETURN_FALSE(PayloadVerifier::LoadPayload(
@@ -121,9 +121,9 @@
 }
 }  // namespace
 
-bool PayloadSigner::SignHash(const vector<char>& hash,
+bool PayloadSigner::SignHash(const chromeos::Blob& hash,
                              const string& private_key_path,
-                             vector<char>* out_signature) {
+                             chromeos::Blob* out_signature) {
   LOG(INFO) << "Signing hash with private key: " << private_key_path;
   string sig_path;
   TEST_AND_RETURN_FALSE(
@@ -136,7 +136,7 @@
   ScopedPathUnlinker hash_path_unlinker(hash_path);
   // We expect unpadded SHA256 hash coming in
   TEST_AND_RETURN_FALSE(hash.size() == 32);
-  vector<char> padded_hash(hash);
+  chromeos::Blob padded_hash(hash);
   PayloadVerifier::PadRSA2048SHA256Hash(&padded_hash);
   TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(),
                                          padded_hash.data(),
@@ -161,7 +161,7 @@
                                                     nullptr));
   TEST_AND_RETURN_FALSE(return_code == 0);
 
-  vector<char> signature;
+  chromeos::Blob signature;
   TEST_AND_RETURN_FALSE(utils::ReadFile(sig_path, &signature));
   out_signature->swap(signature);
   return true;
@@ -169,15 +169,15 @@
 
 bool PayloadSigner::SignPayload(const string& unsigned_payload_path,
                                 const vector<string>& private_key_paths,
-                                vector<char>* out_signature_blob) {
-  vector<char> hash_data;
+                                chromeos::Blob* out_signature_blob) {
+  chromeos::Blob hash_data;
   TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfFile(
       unsigned_payload_path, -1, &hash_data) ==
                         utils::FileSize(unsigned_payload_path));
 
-  vector<vector<char>> signatures;
+  vector<chromeos::Blob> signatures;
   for (const string& path : private_key_paths) {
-    vector<char> signature;
+    chromeos::Blob signature;
     TEST_AND_RETURN_FALSE(SignHash(hash_data, path, &signature));
     signatures.push_back(signature);
   }
@@ -196,7 +196,7 @@
   ScopedPathUnlinker x_path_unlinker(x_path);
   TEST_AND_RETURN_FALSE(utils::WriteFile(x_path.c_str(), "x", 1));
 
-  vector<char> sig_blob;
+  chromeos::Blob sig_blob;
   TEST_AND_RETURN_FALSE(PayloadSigner::SignPayload(x_path,
                                                    private_key_paths,
                                                    &sig_blob));
@@ -207,17 +207,17 @@
 bool PayloadSigner::PrepPayloadForHashing(
         const string& payload_path,
         const vector<int>& signature_sizes,
-        vector<char>* payload_out,
+        chromeos::Blob* payload_out,
         uint64_t* metadata_size_out,
         uint64_t* signatures_offset_out) {
   // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory.
 
   // Loads the payload and adds the signature op to it.
-  vector<vector<char>> signatures;
+  vector<chromeos::Blob> signatures;
   for (int signature_size : signature_sizes) {
     signatures.emplace_back(signature_size, 0);
   }
-  vector<char> signature_blob;
+  chromeos::Blob signature_blob;
   TEST_AND_RETURN_FALSE(ConvertSignatureToProtobufBlob(signatures,
                                                        &signature_blob));
   TEST_AND_RETURN_FALSE(AddSignatureOpToPayload(payload_path,
@@ -231,8 +231,8 @@
 
 bool PayloadSigner::HashPayloadForSigning(const string& payload_path,
                                           const vector<int>& signature_sizes,
-                                          vector<char>* out_hash_data) {
-  vector<char> payload;
+                                          chromeos::Blob* out_hash_data) {
+  chromeos::Blob payload;
   uint64_t metadata_size;
   uint64_t signatures_offset;
 
@@ -244,7 +244,7 @@
 
   // Calculates the hash on the updated payload. Note that we stop calculating
   // before we reach the signature information.
-  TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(&payload[0],
+  TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(payload.data(),
                                                             signatures_offset,
                                                             out_hash_data));
   return true;
@@ -252,8 +252,8 @@
 
 bool PayloadSigner::HashMetadataForSigning(const string& payload_path,
                                            const vector<int>& signature_sizes,
-                                           vector<char>* out_metadata_hash) {
-  vector<char> payload;
+                                           chromeos::Blob* out_metadata_hash) {
+  chromeos::Blob payload;
   uint64_t metadata_size;
   uint64_t signatures_offset;
 
@@ -264,7 +264,7 @@
                                               &signatures_offset));
 
   // Calculates the hash on the manifest.
-  TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(&payload[0],
+  TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(payload.data(),
                                                             metadata_size,
                                                             out_metadata_hash));
   return true;
@@ -272,16 +272,16 @@
 
 bool PayloadSigner::AddSignatureToPayload(
     const string& payload_path,
-    const vector<vector<char>>& signatures,
+    const vector<chromeos::Blob>& signatures,
     const string& signed_payload_path,
     uint64_t *out_metadata_size) {
   // TODO(petkov): Reduce memory usage -- the payload is manipulated in memory.
 
   // Loads the payload and adds the signature op to it.
-  vector<char> signature_blob;
+  chromeos::Blob signature_blob;
   TEST_AND_RETURN_FALSE(ConvertSignatureToProtobufBlob(signatures,
                                                        &signature_blob));
-  vector<char> payload;
+  chromeos::Blob payload;
   uint64_t signatures_offset;
   TEST_AND_RETURN_FALSE(AddSignatureOpToPayload(payload_path,
                                                 signature_blob.size(),
@@ -302,24 +302,23 @@
   return true;
 }
 
-bool PayloadSigner::GetMetadataSignature(const char* const metadata,
+bool PayloadSigner::GetMetadataSignature(const void* const metadata,
                                          size_t metadata_size,
                                          const string& private_key_path,
                                          string* out_signature) {
   // Calculates the hash on the updated payload. Note that the payload includes
   // the signature op but doesn't include the signature blob at the end.
-  vector<char> metadata_hash;
+  chromeos::Blob metadata_hash;
   TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(metadata,
                                                             metadata_size,
                                                             &metadata_hash));
 
-  vector<char> signature;
+  chromeos::Blob signature;
   TEST_AND_RETURN_FALSE(SignHash(metadata_hash,
                                  private_key_path,
                                  &signature));
 
-  *out_signature = chromeos::data_encoding::Base64Encode(signature.data(),
-                                                         signature.size());
+  *out_signature = chromeos::data_encoding::Base64Encode(signature);
   return true;
 }
 
diff --git a/payload_generator/payload_signer.h b/payload_generator/payload_signer.h
index 4a35785..a17a984 100644
--- a/payload_generator/payload_signer.h
+++ b/payload_generator/payload_signer.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include <base/macros.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/update_metadata.pb.h"
 
@@ -21,9 +22,9 @@
  public:
   // Given a raw |hash| and a private key in |private_key_path| calculates the
   // raw signature in |out_signature|. Returns true on success, false otherwise.
-  static bool SignHash(const std::vector<char>& hash,
+  static bool SignHash(const chromeos::Blob& hash,
                        const std::string& private_key_path,
-                       std::vector<char>* out_signature);
+                       chromeos::Blob* out_signature);
 
   // Given an unsigned payload in |unsigned_payload_path| and private keys in
   // |private_key_path|, calculates the signature blob into
@@ -32,7 +33,7 @@
   // false otherwise.
   static bool SignPayload(const std::string& unsigned_payload_path,
                           const std::vector<std::string>& private_key_paths,
-                          std::vector<char>* out_signature_blob);
+                          chromeos::Blob* out_signature_blob);
 
   // Returns the length of out_signature_blob that will result in a call
   // to SignPayload with the given private keys. Returns true on success.
@@ -46,7 +47,7 @@
   static bool PrepPayloadForHashing(
         const std::string& payload_path,
         const std::vector<int>& signature_sizes,
-        std::vector<char>* payload_out,
+        chromeos::Blob* payload_out,
         uint64_t* metadata_size_out,
         uint64_t* signatures_offset_out);
 
@@ -61,7 +62,7 @@
   // The dummy signatures are not preserved or written to disk.
   static bool HashPayloadForSigning(const std::string& payload_path,
                                     const std::vector<int>& signature_sizes,
-                                    std::vector<char>* out_hash_data);
+                                    chromeos::Blob* out_hash_data);
 
   // Given an unsigned payload in |payload_path|,
   // this method does two things:
@@ -75,7 +76,7 @@
   // The dummy signatures are not preserved or written to disk.
   static bool HashMetadataForSigning(const std::string& payload_path,
                                      const std::vector<int>& signature_sizes,
-                                     std::vector<char>* out_metadata_hash);
+                                     chromeos::Blob* out_metadata_hash);
 
   // Given an unsigned payload in |payload_path| (with no dummy signature op)
   // and the raw |signatures| updates the payload to include the signature thus
@@ -86,7 +87,7 @@
   // on success, false otherwise.
   static bool AddSignatureToPayload(
       const std::string& payload_path,
-      const std::vector<std::vector<char>>& signatures,
+      const std::vector<chromeos::Blob>& signatures,
       const std::string& signed_payload_path,
       uint64_t* out_metadata_size);
 
@@ -94,7 +95,7 @@
   // and signs the hash with the given private_key_path and writes the signed
   // hash in |out_signature|. Returns true if successful or false if there was
   // any error in the computations.
-  static bool GetMetadataSignature(const char* const metadata,
+  static bool GetMetadataSignature(const void* const metadata,
                                    size_t metadata_size,
                                    const std::string& private_key_path,
                                    std::string* out_signature);
diff --git a/payload_generator/payload_signer_unittest.cc b/payload_generator/payload_signer_unittest.cc
index c2cd209..d74cdfb 100644
--- a/payload_generator/payload_signer_unittest.cc
+++ b/payload_generator/payload_signer_unittest.cc
@@ -34,7 +34,7 @@
 // Generated by:
 // echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
 //   hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
-const unsigned char kDataHash[] = {
+const uint8_t kDataHash[] = {
   0x7a, 0x07, 0xa6, 0x44, 0x08, 0x86, 0x20, 0xa6,
   0xc1, 0xf8, 0xd9, 0x02, 0x05, 0x63, 0x0d, 0xb7,
   0xfc, 0x2b, 0xa0, 0xa9, 0x7c, 0x9d, 0x1d, 0x8c,
@@ -46,7 +46,7 @@
 // echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
 //    ~/local/bin/openssl pkeyutl -sign -inkey unittest_key.pem -pkeyopt
 //    digest:sha256 | hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
-const unsigned char kDataSignature[] = {
+const uint8_t kDataSignature[] = {
   0x9f, 0x86, 0x25, 0x8b, 0xf3, 0xcc, 0xe3, 0x95,
   0x5f, 0x45, 0x83, 0xb2, 0x66, 0xf0, 0x2a, 0xcf,
   0xb7, 0xaa, 0x52, 0x25, 0x7a, 0xdd, 0x9d, 0x65,
@@ -82,7 +82,7 @@
 };
 
 namespace {
-void SignSampleData(vector<char>* out_signature_blob) {
+void SignSampleData(chromeos::Blob* out_signature_blob) {
   string data_path;
   ASSERT_TRUE(
       utils::MakeTempFile("data.XXXXXX", &data_path, nullptr));
@@ -104,12 +104,12 @@
 }  // namespace
 
 TEST(PayloadSignerTest, SimpleTest) {
-  vector<char> signature_blob;
+  chromeos::Blob signature_blob;
   SignSampleData(&signature_blob);
 
   // Check the signature itself
   Signatures signatures;
-  EXPECT_TRUE(signatures.ParseFromArray(&signature_blob[0],
+  EXPECT_TRUE(signatures.ParseFromArray(signature_blob.data(),
                                         signature_blob.size()));
   EXPECT_EQ(1, signatures.signatures_size());
   const Signatures_Signature& signature = signatures.signatures(0);
@@ -117,21 +117,19 @@
   const string sig_data = signature.data();
   ASSERT_EQ(arraysize(kDataSignature), sig_data.size());
   for (size_t i = 0; i < arraysize(kDataSignature); i++) {
-    EXPECT_EQ(static_cast<char>(kDataSignature[i]), sig_data[i]);
+    EXPECT_EQ(kDataSignature[i], static_cast<uint8_t>(sig_data[i]));
   }
 }
 
 TEST(PayloadSignerTest, VerifySignatureTest) {
-  vector<char> signature_blob;
+  chromeos::Blob signature_blob;
   SignSampleData(&signature_blob);
 
-  vector<char> hash_data;
+  chromeos::Blob hash_data;
   EXPECT_TRUE(PayloadVerifier::VerifySignature(signature_blob,
                                              kUnittestPublicKeyPath,
                                              &hash_data));
-  vector<char> padded_hash_data(reinterpret_cast<const char *>(kDataHash),
-                                reinterpret_cast<const char *>(kDataHash +
-                                                         sizeof(kDataHash)));
+  chromeos::Blob padded_hash_data(std::begin(kDataHash), std::end(kDataHash));
   PayloadVerifier::PadRSA2048SHA256Hash(&padded_hash_data);
   ASSERT_EQ(padded_hash_data.size(), hash_data.size());
   for (size_t i = 0; i < padded_hash_data.size(); i++) {
diff --git a/payload_verifier.cc b/payload_verifier.cc
index 2f821ea..2b96186 100644
--- a/payload_verifier.cc
+++ b/payload_verifier.cc
@@ -13,7 +13,6 @@
 #include "update_engine/utils.h"
 
 using std::string;
-using std::vector;
 
 namespace chromeos_update_engine {
 
@@ -41,7 +40,7 @@
 //   }
 //   OCTET STRING(2+32) <actual signature bytes...>
 //  }
-const unsigned char kRSA2048SHA256Padding[] = {
+const uint8_t kRSA2048SHA256Padding[] = {
   // PKCS1-v1_5 padding
   0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -78,10 +77,10 @@
 }  // namespace
 
 bool PayloadVerifier::LoadPayload(const string& payload_path,
-                                  vector<char>* out_payload,
+                                  chromeos::Blob* out_payload,
                                   DeltaArchiveManifest* out_manifest,
                                   uint64_t* out_metadata_size) {
-  vector<char> payload;
+  chromeos::Blob payload;
   // Loads the payload and parses the manifest.
   TEST_AND_RETURN_FALSE(utils::ReadFile(payload_path, &payload));
   LOG(INFO) << "Payload size: " << payload.size();
@@ -98,23 +97,23 @@
   return true;
 }
 
-bool PayloadVerifier::VerifySignature(const vector<char>& signature_blob,
+bool PayloadVerifier::VerifySignature(const chromeos::Blob& signature_blob,
                                       const string& public_key_path,
-                                      vector<char>* out_hash_data) {
+                                      chromeos::Blob* out_hash_data) {
   return VerifySignatureBlob(signature_blob, public_key_path,
                              kSignatureMessageCurrentVersion, out_hash_data);
 }
 
 bool PayloadVerifier::VerifySignatureBlob(
-    const vector<char>& signature_blob,
+    const chromeos::Blob& signature_blob,
     const string& public_key_path,
     uint32_t client_version,
-    vector<char>* out_hash_data) {
+    chromeos::Blob* out_hash_data) {
   TEST_AND_RETURN_FALSE(!public_key_path.empty());
 
   Signatures signatures;
   LOG(INFO) << "signature size = " <<  signature_blob.size();
-  TEST_AND_RETURN_FALSE(signatures.ParseFromArray(&signature_blob[0],
+  TEST_AND_RETURN_FALSE(signatures.ParseFromArray(signature_blob.data(),
                                                   signature_blob.size()));
 
   // Finds a signature that matches the current version.
@@ -129,16 +128,16 @@
   TEST_AND_RETURN_FALSE(sig_index < signatures.signatures_size());
 
   const Signatures_Signature& signature = signatures.signatures(sig_index);
-  vector<char> sig_data(signature.data().begin(), signature.data().end());
+  chromeos::Blob sig_data(signature.data().begin(), signature.data().end());
 
   return GetRawHashFromSignature(sig_data, public_key_path, out_hash_data);
 }
 
 
 bool PayloadVerifier::GetRawHashFromSignature(
-    const vector<char>& sig_data,
+    const chromeos::Blob& sig_data,
     const string& public_key_path,
-    vector<char>* out_hash_data) {
+    chromeos::Blob* out_hash_data) {
   TEST_AND_RETURN_FALSE(!public_key_path.empty());
 
   // The code below executes the equivalent of:
@@ -165,13 +164,12 @@
   }
 
   // Decrypts the signature.
-  vector<char> hash_data(keysize);
-  int decrypt_size = RSA_public_decrypt(
-      sig_data.size(),
-      reinterpret_cast<const unsigned char*>(sig_data.data()),
-      reinterpret_cast<unsigned char*>(hash_data.data()),
-      rsa,
-      RSA_NO_PADDING);
+  chromeos::Blob hash_data(keysize);
+  int decrypt_size = RSA_public_decrypt(sig_data.size(),
+                                        sig_data.data(),
+                                        hash_data.data(),
+                                        rsa,
+                                        RSA_NO_PADDING);
   RSA_free(rsa);
   TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
                         decrypt_size <= static_cast<int>(hash_data.size()));
@@ -183,7 +181,7 @@
 bool PayloadVerifier::VerifySignedPayload(const string& payload_path,
                                           const string& public_key_path,
                                           uint32_t client_key_check_version) {
-  vector<char> payload;
+  chromeos::Blob payload;
   DeltaArchiveManifest manifest;
   uint64_t metadata_size;
   TEST_AND_RETURN_FALSE(LoadPayload(
@@ -193,14 +191,14 @@
   CHECK_EQ(payload.size(),
            metadata_size + manifest.signatures_offset() +
            manifest.signatures_size());
-  vector<char> signature_blob(
+  chromeos::Blob signature_blob(
       payload.begin() + metadata_size + manifest.signatures_offset(),
       payload.end());
-  vector<char> signed_hash;
+  chromeos::Blob signed_hash;
   TEST_AND_RETURN_FALSE(VerifySignatureBlob(
       signature_blob, public_key_path, client_key_check_version, &signed_hash));
   TEST_AND_RETURN_FALSE(!signed_hash.empty());
-  vector<char> hash;
+  chromeos::Blob hash;
   TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(
       payload.data(), metadata_size + manifest.signatures_offset(), &hash));
   PadRSA2048SHA256Hash(&hash);
@@ -208,7 +206,7 @@
   return true;
 }
 
-bool PayloadVerifier::PadRSA2048SHA256Hash(vector<char>* hash) {
+bool PayloadVerifier::PadRSA2048SHA256Hash(chromeos::Blob* hash) {
   TEST_AND_RETURN_FALSE(hash->size() == 32);
   hash->insert(hash->begin(),
                reinterpret_cast<const char*>(kRSA2048SHA256Padding),
diff --git a/payload_verifier.h b/payload_verifier.h
index f1668e9..3f4f165 100644
--- a/payload_verifier.h
+++ b/payload_verifier.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include <base/macros.h>
+#include <chromeos/secure_blob.h>
 
 #include "update_engine/update_metadata.pb.h"
 
@@ -24,26 +25,26 @@
  public:
   // Returns false if the payload signature can't be verified. Returns true
   // otherwise and sets |out_hash| to the signed payload hash.
-  static bool VerifySignature(const std::vector<char>& signature_blob,
+  static bool VerifySignature(const chromeos::Blob& signature_blob,
                               const std::string& public_key_path,
-                              std::vector<char>* out_hash_data);
+                              chromeos::Blob* out_hash_data);
 
   // Interprets signature_blob as a protocol buffer containing the Signatures
   // message and decrypts the signature data using the public_key_path and
   // stores the resultant raw hash data in out_hash_data. Returns true if
   // everything is successful. False otherwise. It also takes the client_version
   // and interprets the signature blob according to that version.
-  static bool VerifySignatureBlob(const std::vector<char>& signature_blob,
+  static bool VerifySignatureBlob(const chromeos::Blob& signature_blob,
                                   const std::string& public_key_path,
                                   uint32_t client_version,
-                                  std::vector<char>* out_hash_data);
+                                  chromeos::Blob* out_hash_data);
 
   // Decrypts sig_data with the given public_key_path and populates
   // out_hash_data with the decoded raw hash. Returns true if successful,
   // false otherwise.
-  static bool GetRawHashFromSignature(const std::vector<char>& sig_data,
+  static bool GetRawHashFromSignature(const chromeos::Blob& sig_data,
                                       const std::string& public_key_path,
-                                      std::vector<char>* out_hash_data);
+                                      chromeos::Blob* out_hash_data);
 
   // Returns true if the payload in |payload_path| is signed and its hash can be
   // verified using the public key in |public_key_path| with the signature
@@ -57,14 +58,14 @@
   // hash should be a pointer to vector of exactly 256 bits. The vector
   // will be modified in place and will result in having a length of
   // 2048 bits. Returns true on success, false otherwise.
-  static bool PadRSA2048SHA256Hash(std::vector<char>* hash);
+  static bool PadRSA2048SHA256Hash(chromeos::Blob* hash);
 
   // Reads the payload from the given |payload_path| into the |out_payload|
   // vector. It also parses the manifest protobuf in the payload and returns it
   // in |out_manifest| along with the size of the entire metadata in
   // |out_metadata_size|.
   static bool LoadPayload(const std::string& payload_path,
-                          std::vector<char>* out_payload,
+                          chromeos::Blob* out_payload,
                           DeltaArchiveManifest* out_manifest,
                           uint64_t* out_metadata_size);
 
diff --git a/postinstall_runner_action_unittest.cc b/postinstall_runner_action_unittest.cc
index 15169e4..fc61f4e 100644
--- a/postinstall_runner_action_unittest.cc
+++ b/postinstall_runner_action_unittest.cc
@@ -116,8 +116,8 @@
   string orig_cwd;
   {
     vector<char> buf(1000);
-    ASSERT_EQ(&buf[0], getcwd(&buf[0], buf.size()));
-    orig_cwd = string(&buf[0], strlen(&buf[0]));
+    ASSERT_EQ(buf.data(), getcwd(buf.data(), buf.size()));
+    orig_cwd = string(buf.data(), strlen(buf.data()));
   }
 
   // Create a unique named working directory and chdir into it.
diff --git a/test_utils.cc b/test_utils.cc
index bd55ccb..beda798 100644
--- a/test_utils.cc
+++ b/test_utils.cc
@@ -35,7 +35,7 @@
 
 const char* const kMountPathTemplate = "UpdateEngineTests_mnt-XXXXXX";
 
-const unsigned char kRandomString[] = {
+const uint8_t kRandomString[] = {
   0xf2, 0xb7, 0x55, 0x92, 0xea, 0xa6, 0xc9, 0x57,
   0xe0, 0xf8, 0xeb, 0x34, 0x93, 0xd9, 0xc4, 0x8f,
   0xcb, 0x20, 0xfa, 0x37, 0x4b, 0x40, 0xcf, 0xdc,
@@ -106,8 +106,8 @@
   return xattr_res == 0;
 }
 
-bool WriteFileVector(const string& path, const vector<char>& data) {
-  return utils::WriteFile(path.c_str(), &data[0], data.size());
+bool WriteFileVector(const string& path, const chromeos::Blob& data) {
+  return utils::WriteFile(path.c_str(), data.data(), data.size());
 }
 
 bool WriteFileString(const string& path, const string& data) {
@@ -137,7 +137,8 @@
   return true;
 }
 
-bool ExpectVectorsEq(const vector<char>& expected, const vector<char>& actual) {
+bool ExpectVectorsEq(const chromeos::Blob& expected,
+                     const chromeos::Blob& actual) {
   EXPECT_EQ(expected.size(), actual.size());
   if (expected.size() != actual.size())
     return false;
@@ -149,10 +150,10 @@
   return is_all_eq;
 }
 
-void FillWithData(vector<char>* buffer) {
+void FillWithData(chromeos::Blob* buffer) {
   size_t input_counter = 0;
-  for (vector<char>::iterator it = buffer->begin(); it != buffer->end(); ++it) {
-    *it = kRandomString[input_counter];
+  for (uint8_t& b : *buffer) {
+    b = kRandomString[input_counter];
     input_counter++;
     input_counter %= sizeof(kRandomString);
   }
diff --git a/test_utils.h b/test_utils.h
index 379eb5f..a65b042 100644
--- a/test_utils.h
+++ b/test_utils.h
@@ -29,18 +29,18 @@
 
 // 300 byte pseudo-random string. Not null terminated.
 // This does not gzip compress well.
-extern const unsigned char kRandomString[300];
+extern const uint8_t kRandomString[300];
 
 // Writes the data passed to path. The file at path will be overwritten if it
 // exists. Returns true on success, false otherwise.
-bool WriteFileVector(const std::string& path, const std::vector<char>& data);
+bool WriteFileVector(const std::string& path, const chromeos::Blob& data);
 bool WriteFileString(const std::string& path, const std::string& data);
 
 bool BindToUnusedLoopDevice(const std::string &filename,
                             std::string* lo_dev_name_ptr);
 
 // Returns true iff a == b
-bool ExpectVectorsEq(const std::vector<char>& a, const std::vector<char>& b);
+bool ExpectVectorsEq(const chromeos::Blob& a, const chromeos::Blob& b);
 
 inline int System(const std::string& cmd) {
   return system(cmd.c_str());
@@ -64,10 +64,10 @@
 
 // Checks if xattr is supported in the directory specified by
 // |dir_path| which must be writable. Returns true if the feature is
-// supported, false if not or if an error occured.
+// supported, false if not or if an error occurred.
 bool IsXAttrSupported(const base::FilePath& dir_path);
 
-void FillWithData(std::vector<char>* buffer);
+void FillWithData(chromeos::Blob* buffer);
 
 // Creates an empty ext image.
 void CreateEmptyExtImageAtPath(const std::string& path,
diff --git a/utils.cc b/utils.cc
index 2007e9b..77e5a35 100644
--- a/utils.cc
+++ b/utils.cc
@@ -123,7 +123,7 @@
 }
 
 
-bool WriteFile(const char* path, const char* data, int data_len) {
+bool WriteFile(const char* path, const void* data, int data_len) {
   DirectFileWriter writer;
   TEST_AND_RETURN_FALSE_ERRNO(0 == writer.Open(path,
                                                O_WRONLY | O_CREAT | O_TRUNC,
@@ -219,17 +219,17 @@
 
 // Append |nbytes| of content from |buf| to the vector pointed to by either
 // |vec_p| or |str_p|.
-static void AppendBytes(const char* buf, size_t nbytes,
-                        vector<char>* vec_p) {
+static void AppendBytes(const uint8_t* buf, size_t nbytes,
+                        chromeos::Blob* vec_p) {
   CHECK(buf);
   CHECK(vec_p);
   vec_p->insert(vec_p->end(), buf, buf + nbytes);
 }
-static void AppendBytes(const char* buf, size_t nbytes,
+static void AppendBytes(const uint8_t* buf, size_t nbytes,
                         string* str_p) {
   CHECK(buf);
   CHECK(str_p);
-  str_p->append(buf, nbytes);
+  str_p->append(buf, buf + nbytes);
 }
 
 // Reads from an open file |fp|, appending the read content to the container
@@ -240,7 +240,7 @@
 static bool Read(FILE* fp, off_t size, T* out_p) {
   CHECK(fp);
   CHECK(size == -1 || size >= 0);
-  char buf[1024];
+  uint8_t buf[1024];
   while (size == -1 || size > 0) {
     off_t bytes_to_read = sizeof(buf);
     if (size > 0 && bytes_to_read > size) {
@@ -296,7 +296,7 @@
   return (success && pclose(fp) >= 0);
 }
 
-bool ReadFile(const string& path, vector<char>* out_p) {
+bool ReadFile(const string& path, chromeos::Blob* out_p) {
   return ReadFileChunkAndAppend(path, 0, -1, out_p);
 }
 
@@ -305,7 +305,7 @@
 }
 
 bool ReadFileChunk(const string& path, off_t offset, off_t size,
-                   vector<char>* out_p) {
+                   chromeos::Blob* out_p) {
   return ReadFileChunkAndAppend(path, offset, size, out_p);
 }
 
@@ -363,9 +363,7 @@
   return size;
 }
 
-void HexDumpArray(const unsigned char* const arr, const size_t length) {
-  const unsigned char* const char_arr =
-      reinterpret_cast<const unsigned char* const>(arr);
+void HexDumpArray(const uint8_t* const arr, const size_t length) {
   LOG(INFO) << "Logging array of length: " << length;
   const unsigned int bytes_per_line = 16;
   for (uint32_t i = 0; i < length; i += bytes_per_line) {
@@ -378,7 +376,7 @@
     string line = header;
     for (unsigned int j = 0; j < bytes_per_this_line; j++) {
       char buf[20];
-      unsigned char c = char_arr[i + j];
+      uint8_t c = arr[i + j];
       r = snprintf(buf, sizeof(buf), "%02x ", static_cast<unsigned int>(c));
       TEST_AND_RETURN(r == 3);
       line += buf;
@@ -551,13 +549,13 @@
   const string filename_template = PrependTmpdir(base_filename_template);
   DCHECK(filename || fd);
   vector<char> buf(filename_template.size() + 1);
-  memcpy(&buf[0], filename_template.data(), filename_template.size());
+  memcpy(buf.data(), filename_template.data(), filename_template.size());
   buf[filename_template.size()] = '\0';
 
-  int mkstemp_fd = mkstemp(&buf[0]);
+  int mkstemp_fd = mkstemp(buf.data());
   TEST_AND_RETURN_FALSE_ERRNO(mkstemp_fd >= 0);
   if (filename) {
-    *filename = &buf[0];
+    *filename = buf.data();
   }
   if (fd) {
     *fd = mkstemp_fd;
@@ -572,12 +570,12 @@
   const string dirname_template = PrependTmpdir(base_dirname_template);
   DCHECK(dirname);
   vector<char> buf(dirname_template.size() + 1);
-  memcpy(&buf[0], dirname_template.data(), dirname_template.size());
+  memcpy(buf.data(), dirname_template.data(), dirname_template.size());
   buf[dirname_template.size()] = '\0';
 
-  char* return_code = mkdtemp(&buf[0]);
+  char* return_code = mkdtemp(buf.data());
   TEST_AND_RETURN_FALSE_ERRNO(return_code != nullptr);
-  *dirname = &buf[0];
+  *dirname = buf.data();
   return true;
 }
 
@@ -689,7 +687,7 @@
   return true;
 }
 
-bool GetSquashfs4Size(const unsigned char* buffer, size_t buffer_size,
+bool GetSquashfs4Size(const uint8_t* buffer, size_t buffer_size,
                       int* out_block_count,
                       int* out_block_size) {
   // See fs/squashfs/squashfs_fs.h for format details. We only support
@@ -751,7 +749,8 @@
 
 // Tries to parse the header of an ELF file to obtain a human-readable
 // description of it on the |output| string.
-static bool GetFileFormatELF(const char* buffer, size_t size, string* output) {
+static bool GetFileFormatELF(const uint8_t* buffer, size_t size,
+                             string* output) {
   // 0x00: EI_MAG - ELF magic header, 4 bytes.
   if (size < SELFMAG || memcmp(buffer, ELFMAG, SELFMAG) != 0)
     return false;
@@ -774,7 +773,7 @@
   // 0x05: EI_DATA, endianness, 1 byte.
   if (size < EI_DATA + 1)
     return true;
-  char ei_data = buffer[EI_DATA];
+  uint8_t ei_data = buffer[EI_DATA];
   switch (ei_data) {
     case ELFDATA2LSB:
       *output += " little-endian";
@@ -820,7 +819,7 @@
 }
 
 string GetFileFormat(const string& path) {
-  vector<char> buffer;
+  chromeos::Blob buffer;
   if (!ReadFileChunkAndAppend(path, 0, kGetFileFormatMaxHeaderSize, &buffer))
     return "File not found.";
 
diff --git a/utils.h b/utils.h
index 0fe373a..661a260 100644
--- a/utils.h
+++ b/utils.h
@@ -18,6 +18,7 @@
 #include <base/files/file_path.h>
 #include <base/posix/eintr_wrapper.h>
 #include <base/time/time.h>
+#include <chromeos/secure_blob.h>
 #include <glib.h>
 #include "metrics/metrics_library.h"
 
@@ -63,7 +64,7 @@
 
 // Writes the data passed to path. The file at path will be overwritten if it
 // exists. Returns true on success, false otherwise.
-bool WriteFile(const char* path, const char* data, int data_len);
+bool WriteFile(const char* path, const void* data, int data_len);
 
 // Calls write() or pwrite() repeatedly until all count bytes at buf are
 // written to fd or an error occurs. Returns true on success.
@@ -89,10 +90,10 @@
 // file's content, false otherwise, in which case the state of the output
 // container is unknown. ReadFileChunk starts reading the file from |offset|; if
 // |size| is not -1, only up to |size| bytes are read in.
-bool ReadFile(const std::string& path, std::vector<char>* out_p);
+bool ReadFile(const std::string& path, chromeos::Blob* out_p);
 bool ReadFile(const std::string& path, std::string* out_p);
 bool ReadFileChunk(const std::string& path, off_t offset, off_t size,
-                   std::vector<char>* out_p);
+                   chromeos::Blob* out_p);
 
 // Invokes |cmd| in a pipe and appends its stdout to the container pointed to by
 // |out_p|. Returns true upon successfully reading all of the output, false
@@ -254,12 +255,12 @@
 int FuzzInt(int value, unsigned int range);
 
 // Log a string in hex to LOG(INFO). Useful for debugging.
-void HexDumpArray(const unsigned char* const arr, const size_t length);
+void HexDumpArray(const uint8_t* const arr, const size_t length);
 inline void HexDumpString(const std::string& str) {
-  HexDumpArray(reinterpret_cast<const unsigned char*>(str.data()), str.size());
+  HexDumpArray(reinterpret_cast<const uint8_t*>(str.data()), str.size());
 }
-inline void HexDumpVector(const std::vector<char>& vect) {
-  HexDumpArray(reinterpret_cast<const unsigned char*>(&vect[0]), vect.size());
+inline void HexDumpVector(const chromeos::Blob& vect) {
+  HexDumpArray(vect.data(), vect.size());
 }
 
 template<typename KeyType, typename ValueType>
diff --git a/utils_unittest.cc b/utils_unittest.cc
index d216893..ce65c50 100644
--- a/utils_unittest.cc
+++ b/utils_unittest.cc
@@ -110,7 +110,7 @@
 }
 
 TEST(UtilsTest, ReadFileFailure) {
-  vector<char> empty;
+  chromeos::Blob empty;
   EXPECT_FALSE(utils::ReadFile("/this/doesn't/exist", &empty));
 }
 
@@ -118,20 +118,20 @@
   base::FilePath file;
   EXPECT_TRUE(base::CreateTemporaryFile(&file));
   ScopedPathUnlinker unlinker(file.value());
-  vector<char> data;
+  chromeos::Blob data;
   const size_t kSize = 1024 * 1024;
   for (size_t i = 0; i < kSize; i++) {
     data.push_back(i % 255);
   }
-  EXPECT_TRUE(utils::WriteFile(file.value().c_str(), &data[0], data.size()));
-  vector<char> in_data;
+  EXPECT_TRUE(utils::WriteFile(file.value().c_str(), data.data(), data.size()));
+  chromeos::Blob in_data;
   EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), kSize, 10, &in_data));
   EXPECT_TRUE(in_data.empty());
   EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), 0, -1, &in_data));
   EXPECT_TRUE(data == in_data);
   in_data.clear();
   EXPECT_TRUE(utils::ReadFileChunk(file.value().c_str(), 10, 20, &in_data));
-  EXPECT_TRUE(vector<char>(data.begin() + 10, data.begin() + 10 + 20) ==
+  EXPECT_TRUE(chromeos::Blob(data.begin() + 10, data.begin() + 10 + 20) ==
               in_data);
 }
 
@@ -244,8 +244,7 @@
 
 TEST(UtilsTest, FuzzIntTest) {
   static const unsigned int kRanges[] = { 0, 1, 2, 20 };
-  for (size_t r = 0; r < arraysize(kRanges); ++r) {
-    unsigned int range = kRanges[r];
+  for (unsigned int range : kRanges) {
     const int kValue = 50;
     for (int tries = 0; tries < 100; ++tries) {
       int value = utils::FuzzInt(kValue, range);
@@ -257,8 +256,7 @@
 
 TEST(UtilsTest, ApplyMapTest) {
   int initial_values[] = {1, 2, 3, 4, 6};
-  vector<int> collection(&initial_values[0],
-                         initial_values + arraysize(initial_values));
+  vector<int> collection(std::begin(initial_values), std::end(initial_values));
   EXPECT_EQ(arraysize(initial_values), collection.size());
   int expected_values[] = {1, 2, 5, 4, 8};
   map<int, int> value_map;
@@ -295,7 +293,7 @@
 //   echo hola>hola
 //   mksquashfs hola hola.sqfs -noappend -nopad
 //   hexdump hola.sqfs -e '16/1 "%02x, " "\n"'
-const unsigned char kSquashfsFile[] = {
+const uint8_t kSquashfsFile[] = {
   0x68, 0x73, 0x71, 0x73, 0x02, 0x00, 0x00, 0x00,  // magic, inodes
   0x3e, 0x49, 0x61, 0x54, 0x00, 0x00, 0x02, 0x00,
   0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, 0x00,
@@ -329,7 +327,7 @@
 };
 
 TEST(UtilsTest, GetSquashfs4Size) {
-  unsigned char buffer[sizeof(kSquashfsFile)];
+  uint8_t buffer[sizeof(kSquashfsFile)];
   memcpy(buffer, kSquashfsFile, sizeof(kSquashfsFile));
 
   int block_count = -1;
diff --git a/zip_unittest.cc b/zip_unittest.cc
index 0b6e5b8..4dcee59 100644
--- a/zip_unittest.cc
+++ b/zip_unittest.cc
@@ -23,14 +23,14 @@
 template <typename T>
 class ZipTest : public ::testing::Test {
  public:
-  bool ZipDecompress(const vector<char>& in,
-                     vector<char>* out) const = 0;
-  bool ZipCompress(const vector<char>& in,
-                   vector<char>* out) const = 0;
+  bool ZipDecompress(const chromeos::Blob& in,
+                     chromeos::Blob* out) const = 0;
+  bool ZipCompress(const chromeos::Blob& in,
+                   chromeos::Blob* out) const = 0;
   bool ZipCompressString(const string& str,
-                         vector<char>* out) const = 0;
+                         chromeos::Blob* out) const = 0;
   bool ZipDecompressString(const string& str,
-                           vector<char>* out) const = 0;
+                           chromeos::Blob* out) const = 0;
 };
 
 class BzipTest {};
@@ -38,20 +38,20 @@
 template <>
 class ZipTest<BzipTest> : public ::testing::Test {
  public:
-  bool ZipDecompress(const vector<char>& in,
-                     vector<char>* out) const {
+  bool ZipDecompress(const chromeos::Blob& in,
+                     chromeos::Blob* out) const {
     return BzipDecompress(in, out);
   }
-  bool ZipCompress(const vector<char>& in,
-                   vector<char>* out) const {
+  bool ZipCompress(const chromeos::Blob& in,
+                   chromeos::Blob* out) const {
     return BzipCompress(in, out);
   }
   bool ZipCompressString(const string& str,
-                         vector<char>* out) const {
+                         chromeos::Blob* out) const {
     return BzipCompressString(str, out);
   }
   bool ZipDecompressString(const string& str,
-                           vector<char>* out) const {
+                           chromeos::Blob* out) const {
     return BzipDecompressString(str, out);
   }
 };
@@ -68,39 +68,39 @@
             "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
             "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
             "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-  vector<char> out;
+  chromeos::Blob out;
   EXPECT_TRUE(this->ZipCompressString(in, &out));
   EXPECT_LT(out.size(), in.size());
   EXPECT_GT(out.size(), 0);
-  vector<char> decompressed;
+  chromeos::Blob decompressed;
   EXPECT_TRUE(this->ZipDecompress(out, &decompressed));
   EXPECT_EQ(in.size(), decompressed.size());
-  EXPECT_TRUE(!memcmp(in.data(), &decompressed[0], in.size()));
+  EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size()));
 }
 
 TYPED_TEST(ZipTest, PoorCompressionTest) {
   string in(reinterpret_cast<const char*>(kRandomString),
             sizeof(kRandomString));
-  vector<char> out;
+  chromeos::Blob out;
   EXPECT_TRUE(this->ZipCompressString(in, &out));
   EXPECT_GT(out.size(), in.size());
-  string out_string(&out[0], out.size());
-  vector<char> decompressed;
+  string out_string(out.begin(), out.end());
+  chromeos::Blob decompressed;
   EXPECT_TRUE(this->ZipDecompressString(out_string, &decompressed));
   EXPECT_EQ(in.size(), decompressed.size());
-  EXPECT_TRUE(!memcmp(in.data(), &decompressed[0], in.size()));
+  EXPECT_TRUE(!memcmp(in.data(), decompressed.data(), in.size()));
 }
 
 TYPED_TEST(ZipTest, MalformedZipTest) {
   string in(reinterpret_cast<const char*>(kRandomString),
             sizeof(kRandomString));
-  vector<char> out;
+  chromeos::Blob out;
   EXPECT_FALSE(this->ZipDecompressString(in, &out));
 }
 
 TYPED_TEST(ZipTest, EmptyInputsTest) {
   string in;
-  vector<char> out;
+  chromeos::Blob out;
   EXPECT_TRUE(this->ZipDecompressString(in, &out));
   EXPECT_EQ(0, out.size());