AU: Switch to 2048 bit RSA keys; Pad SHA256 hashes appropriately.

Manually pad hashes according to how SHA256 hashes should be padded
for use in RSA 2048 bit encryption.

Also, remove the public key from the repository, as it's generated by
scons.

In an upcoming CL, I will test via an actual update.

BUG=chromium-os:13341
TEST=unittests

Review URL: http://codereview.chromium.org/6771024

Change-Id: I8aa93ed54e4d32b46f4d817a5ae5c36d9f0885f6
diff --git a/delta_performer.cc b/delta_performer.cc
index 1a98102..54a69fb 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -601,7 +601,8 @@
   OmahaHashCalculator signed_hasher;
   TEST_AND_RETURN_FALSE(signed_hasher.SetContext(signed_hash_context_));
   TEST_AND_RETURN_FALSE(signed_hasher.Finalize());
-  const vector<char>& hash_data = signed_hasher.raw_hash();
+  vector<char> hash_data = signed_hasher.raw_hash();
+  PayloadSigner::PadRSA2048SHA256Hash(&hash_data);
   TEST_AND_RETURN_FALSE(!hash_data.empty());
   TEST_AND_RETURN_FALSE(hash_data == signed_hash_data);
   return true;
diff --git a/delta_performer_unittest.cc b/delta_performer_unittest.cc
index 586d582..0c2d9b9 100755
--- a/delta_performer_unittest.cc
+++ b/delta_performer_unittest.cc
@@ -149,7 +149,7 @@
     LOG(INFO) << "Generating a mismatched private key.";
     ASSERT_EQ(0,
               System(StringPrintf(
-                  "/usr/bin/openssl genrsa -out %s 1024",
+                  "/usr/bin/openssl genrsa -out %s 2048",
                   private_key_path.c_str())));
   }
   int signature_size = GetSignatureSize(private_key_path);
@@ -164,12 +164,18 @@
                 signature_size,
                 hash_file.c_str())));
 
+  // Pad the hash
+  vector<char> hash;
+  ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
+  ASSERT_TRUE(PayloadSigner::PadRSA2048SHA256Hash(&hash));
+  ASSERT_TRUE(WriteFileVector(hash_file, hash));
+
   string sig_file;
   ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file, NULL));
   ScopedPathUnlinker sig_unlinker(sig_file);
   ASSERT_EQ(0,
             System(StringPrintf(
-                "/usr/bin/openssl rsautl -pkcs -sign -inkey %s -in %s -out %s",
+                "/usr/bin/openssl rsautl -raw -sign -inkey %s -in %s -out %s",
                 private_key_path.c_str(),
                 hash_file.c_str(),
                 sig_file.c_str())));
diff --git a/payload_signer.cc b/payload_signer.cc
index 60a80d1..ef9791d 100644
--- a/payload_signer.cc
+++ b/payload_signer.cc
@@ -23,6 +23,28 @@
 const uint32_t kSignatureMessageVersion = 1;
 
 namespace {
+
+const char kRSA2048SHA256Padding[] = {
+  0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
+  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+  0x00, 0x04, 0x20
+};
+
 // Given a raw |signature|, packs it into a protobuf and serializes it into a
 // binary blob. Returns true on success, false otherwise.
 bool ConvertSignatureToProtobufBlob(const vector<char> signature,
@@ -113,14 +135,18 @@
   TEST_AND_RETURN_FALSE(
       utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_path, NULL));
   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);
+  PadRSA2048SHA256Hash(&padded_hash);
   TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(),
-                                         hash.data(),
-                                         hash.size()));
+                                         padded_hash.data(),
+                                         padded_hash.size()));
 
   // This runs on the server, so it's okay to cop out and call openssl
   // executable rather than properly use the library
   vector<string> cmd;
-  SplitString("/usr/bin/openssl rsautl -pkcs -sign -inkey x -in x -out x",
+  SplitString("/usr/bin/openssl rsautl -raw -sign -inkey x -in x -out x",
               ' ',
               &cmd);
   cmd[cmd.size() - 5] = private_key_path;
@@ -220,7 +246,7 @@
       reinterpret_cast<const unsigned char*>(sig_data.data()),
       reinterpret_cast<unsigned char*>(hash_data.data()),
       rsa,
-      RSA_PKCS1_PADDING);
+      RSA_NO_PADDING);
   RSA_free(rsa);
   TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
                         decrypt_size <= static_cast<int>(hash_data.size()));
@@ -251,6 +277,7 @@
   vector<char> hash;
   TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(
       payload.data(), metadata_size + manifest.signatures_offset(), &hash));
+  PadRSA2048SHA256Hash(&hash);
   TEST_AND_RETURN_FALSE(hash == signed_hash);
   return true;
 }
@@ -299,4 +326,13 @@
   return true;
 }
 
+bool PayloadSigner::PadRSA2048SHA256Hash(std::vector<char>* hash) {
+  TEST_AND_RETURN_FALSE(hash->size() == 32);
+  hash->insert(hash->begin(),
+               kRSA2048SHA256Padding,
+               kRSA2048SHA256Padding + sizeof(kRSA2048SHA256Padding));
+  TEST_AND_RETURN_FALSE(hash->size() == 256);
+  return true;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/payload_signer.h b/payload_signer.h
index eb0663d..ee1bee9 100644
--- a/payload_signer.h
+++ b/payload_signer.h
@@ -67,6 +67,12 @@
   static bool VerifySignedPayload(const std::string& payload_path,
                                   const std::string& public_key_path);
 
+  // Pads a SHA256 hash so that it may be encrypted/signed with RSA2048
+  // using the PKCS#1 v1.5 scheme.
+  // 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);
  private:
   // This should never be constructed
   DISALLOW_IMPLICIT_CONSTRUCTORS(PayloadSigner);
diff --git a/payload_signer_unittest.cc b/payload_signer_unittest.cc
index f803156..f7c59a6 100644
--- a/payload_signer_unittest.cc
+++ b/payload_signer_unittest.cc
@@ -14,7 +14,7 @@
 using std::vector;
 
 // Note: the test key was generated with the following command:
-// openssl genrsa -out unittest_key.pem 1024
+// openssl genrsa -out unittest_key.pem 2048
 
 namespace chromeos_update_engine {
 
@@ -23,29 +23,55 @@
 
 // Some data and its corresponding hash and signature:
 const char kDataToSign[] = "This is some data to sign.";
+
+// Generated by:
+// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
+//   hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
 const char 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,
   0x01, 0xf5, 0x78, 0x6d, 0xc5, 0x11, 0xb4, 0x06
 };
+
+// Generated with openssl 1.0, which at the time of this writing, you need
+// to download and install yourself. Here's my command:
+// 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 char kDataSignature[] = {
-  0xa4, 0xbc, 0x8f, 0xeb, 0x81, 0x05, 0xaa, 0x56,
-  0x1b, 0x56, 0xe5, 0xcb, 0x9b, 0x1a, 0x00, 0xd7,
-  0x1d, 0x87, 0x8e, 0xda, 0x5e, 0x90, 0x09, 0xb8,
-  0x15, 0xf4, 0x25, 0x97, 0x2f, 0x3c, 0xa1, 0xf3,
-  0x02, 0x75, 0xcd, 0x67, 0x4b, 0x0c, 0x1f, 0xf5,
-  0x6e, 0xf1, 0x58, 0xd7, 0x0d, 0x8c, 0x18, 0x91,
-  0x52, 0x30, 0x98, 0x64, 0x58, 0xc0, 0xe2, 0xb5,
-  0x77, 0x3b, 0x96, 0x8f, 0x05, 0xc4, 0x7f, 0x7a,
-  0x9a, 0x44, 0x0f, 0xc7, 0x1b, 0x90, 0x83, 0xf8,
-  0x69, 0x05, 0xa8, 0x02, 0x57, 0xcd, 0x2e, 0x5b,
-  0x96, 0xc7, 0x77, 0xa6, 0x1f, 0x97, 0x97, 0x05,
-  0xb3, 0x30, 0x1c, 0x27, 0xd7, 0x2d, 0x31, 0x60,
-  0x84, 0x7e, 0x99, 0x00, 0xe6, 0xe1, 0x39, 0xa6,
-  0xf3, 0x3a, 0x72, 0xba, 0xc4, 0xfe, 0x68, 0xa9,
-  0x08, 0xfa, 0xbc, 0xa8, 0x44, 0x66, 0xa0, 0x60,
-  0xde, 0xc9, 0xb2, 0xba, 0xbc, 0x80, 0xb5, 0x55
+  0x9f, 0x86, 0x25, 0x8b, 0xf3, 0xcc, 0xe3, 0x95,
+  0x5f, 0x45, 0x83, 0xb2, 0x66, 0xf0, 0x2a, 0xcf,
+  0xb7, 0xaa, 0x52, 0x25, 0x7a, 0xdd, 0x9d, 0x65,
+  0xe5, 0xd6, 0x02, 0x4b, 0x37, 0x99, 0x53, 0x06,
+  0xc2, 0xc9, 0x37, 0x36, 0x25, 0x62, 0x09, 0x4f,
+  0x6b, 0x22, 0xf8, 0xb3, 0x89, 0x14, 0x98, 0x1a,
+  0xbc, 0x30, 0x90, 0x4a, 0x43, 0xf5, 0xea, 0x2e,
+  0xf0, 0xa4, 0xba, 0xc3, 0xa7, 0xa3, 0x44, 0x70,
+  0xd6, 0xc4, 0x89, 0xd8, 0x45, 0x71, 0xbb, 0xee,
+  0x59, 0x87, 0x3d, 0xd5, 0xe5, 0x40, 0x22, 0x3d,
+  0x73, 0x7e, 0x2a, 0x58, 0x93, 0x8e, 0xcb, 0x9c,
+  0xf2, 0xbb, 0x4a, 0xc9, 0xd2, 0x2c, 0x52, 0x42,
+  0xb0, 0xd1, 0x13, 0x22, 0xa4, 0x78, 0xc7, 0xc6,
+  0x3e, 0xf1, 0xdc, 0x4c, 0x7b, 0x2d, 0x40, 0xda,
+  0x58, 0xac, 0x4a, 0x11, 0x96, 0x3d, 0xa0, 0x01,
+  0xf6, 0x96, 0x74, 0xf6, 0x6c, 0x0c, 0x49, 0x69,
+  0x4e, 0xc1, 0x7e, 0x9f, 0x2a, 0x42, 0xdd, 0x15,
+  0x6b, 0x37, 0x2e, 0x3a, 0xa7, 0xa7, 0x6d, 0x91,
+  0x13, 0xe8, 0x59, 0xde, 0xfe, 0x99, 0x07, 0xd9,
+  0x34, 0x0f, 0x17, 0xb3, 0x05, 0x4c, 0xd2, 0xc6,
+  0x82, 0xb7, 0x38, 0x36, 0x63, 0x1d, 0x9e, 0x21,
+  0xa6, 0x32, 0xef, 0xf1, 0x65, 0xe6, 0xed, 0x95,
+  0x25, 0x9b, 0x61, 0xe0, 0xba, 0x86, 0xa1, 0x7f,
+  0xf8, 0xa5, 0x4a, 0x32, 0x1f, 0x15, 0x20, 0x8a,
+  0x41, 0xc5, 0xb0, 0xd9, 0x4a, 0xda, 0x85, 0xf3,
+  0xdc, 0xa0, 0x98, 0x5d, 0x1d, 0x18, 0x9d, 0x2e,
+  0x42, 0xea, 0x69, 0x13, 0x74, 0x3c, 0x74, 0xf7,
+  0x6d, 0x43, 0xb0, 0x63, 0x90, 0xdb, 0x04, 0xd5,
+  0x05, 0xc9, 0x73, 0x1f, 0x6c, 0xd6, 0xfa, 0x46,
+  0x4e, 0x0f, 0x33, 0x58, 0x5b, 0x0d, 0x1b, 0x55,
+  0x39, 0xb9, 0x0f, 0x43, 0x37, 0xc0, 0x06, 0x0c,
+  0x29, 0x93, 0x43, 0xc7, 0x43, 0xb9, 0xab, 0x7d
 };
 
 //class PayloadSignerTest : public ::testing::Test {};
@@ -96,9 +122,11 @@
   EXPECT_TRUE(PayloadSigner::VerifySignature(signature_blob,
                                              kUnittestPublicKeyPath,
                                              &hash_data));
-  ASSERT_EQ(arraysize(kDataHash), hash_data.size());
-  for (size_t i = 0; i < arraysize(kDataHash); i++) {
-    EXPECT_EQ(kDataHash[i], hash_data[i]);
+  vector<char> padded_hash_data(kDataHash, kDataHash + sizeof(kDataHash));
+  PayloadSigner::PadRSA2048SHA256Hash(&padded_hash_data);
+  ASSERT_EQ(padded_hash_data.size(), hash_data.size());
+  for (size_t i = 0; i < padded_hash_data.size(); i++) {
+    EXPECT_EQ(padded_hash_data[i], hash_data[i]);
   }
 }
 
diff --git a/unittest_key.pem b/unittest_key.pem
index f3867e4..224d3c3 100644
--- a/unittest_key.pem
+++ b/unittest_key.pem
@@ -1,15 +1,27 @@
 -----BEGIN RSA PRIVATE KEY-----
-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
+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
 -----END RSA PRIVATE KEY-----
diff --git a/unittest_key.pub.pem b/unittest_key.pub.pem
deleted file mode 100644
index 10485f3..0000000
--- a/unittest_key.pub.pem
+++ /dev/null
@@ -1,6 +0,0 @@
------BEGIN PUBLIC KEY-----
-MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDh27889vgney5Fmg89ZR80CFAh
-BWfj/33/6uRfWRs9tNP0kKpyIml8Q4s6acPyp4VUlmfcayVKIkoNYhV+D9oRtNGm
-josPCTRmupQ+55z0/FFHjtT54sJShFvBcCofygvHeYqrzgpZdB8z1z/zhAfJc43h
-s2jFcr82UvkQ8XD3xwIDAQAB
------END PUBLIC KEY-----