Skip to content

Commit bdfaaf0

Browse files
committed
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
1 parent 44d98d9 commit bdfaaf0

7 files changed

+129
-46
lines changed

delta_performer.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ bool DeltaPerformer::VerifyPayload(
601601
OmahaHashCalculator signed_hasher;
602602
TEST_AND_RETURN_FALSE(signed_hasher.SetContext(signed_hash_context_));
603603
TEST_AND_RETURN_FALSE(signed_hasher.Finalize());
604-
const vector<char>& hash_data = signed_hasher.raw_hash();
604+
vector<char> hash_data = signed_hasher.raw_hash();
605+
PayloadSigner::PadRSA2048SHA256Hash(&hash_data);
605606
TEST_AND_RETURN_FALSE(!hash_data.empty());
606607
TEST_AND_RETURN_FALSE(hash_data == signed_hash_data);
607608
return true;

delta_performer_unittest.cc

+8-2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ void SignGeneratedShellPayload(SignatureTest signature_test,
149149
LOG(INFO) << "Generating a mismatched private key.";
150150
ASSERT_EQ(0,
151151
System(StringPrintf(
152-
"/usr/bin/openssl genrsa -out %s 1024",
152+
"/usr/bin/openssl genrsa -out %s 2048",
153153
private_key_path.c_str())));
154154
}
155155
int signature_size = GetSignatureSize(private_key_path);
@@ -164,12 +164,18 @@ void SignGeneratedShellPayload(SignatureTest signature_test,
164164
signature_size,
165165
hash_file.c_str())));
166166

167+
// Pad the hash
168+
vector<char> hash;
169+
ASSERT_TRUE(utils::ReadFile(hash_file, &hash));
170+
ASSERT_TRUE(PayloadSigner::PadRSA2048SHA256Hash(&hash));
171+
ASSERT_TRUE(WriteFileVector(hash_file, hash));
172+
167173
string sig_file;
168174
ASSERT_TRUE(utils::MakeTempFile("/tmp/signature.XXXXXX", &sig_file, NULL));
169175
ScopedPathUnlinker sig_unlinker(sig_file);
170176
ASSERT_EQ(0,
171177
System(StringPrintf(
172-
"/usr/bin/openssl rsautl -pkcs -sign -inkey %s -in %s -out %s",
178+
"/usr/bin/openssl rsautl -raw -sign -inkey %s -in %s -out %s",
173179
private_key_path.c_str(),
174180
hash_file.c_str(),
175181
sig_file.c_str())));

payload_signer.cc

+40-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,28 @@ namespace chromeos_update_engine {
2323
const uint32_t kSignatureMessageVersion = 1;
2424

2525
namespace {
26+
27+
const char kRSA2048SHA256Padding[] = {
28+
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
29+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
30+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
31+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
32+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
33+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
34+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
35+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
36+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
37+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
38+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
40+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
41+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
44+
0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
45+
0x00, 0x04, 0x20
46+
};
47+
2648
// Given a raw |signature|, packs it into a protobuf and serializes it into a
2749
// binary blob. Returns true on success, false otherwise.
2850
bool ConvertSignatureToProtobufBlob(const vector<char> signature,
@@ -113,14 +135,18 @@ bool PayloadSigner::SignHash(const vector<char>& hash,
113135
TEST_AND_RETURN_FALSE(
114136
utils::MakeTempFile("/tmp/hash.XXXXXX", &hash_path, NULL));
115137
ScopedPathUnlinker hash_path_unlinker(hash_path);
138+
// We expect unpadded SHA256 hash coming in
139+
TEST_AND_RETURN_FALSE(hash.size() == 32);
140+
vector<char> padded_hash(hash);
141+
PadRSA2048SHA256Hash(&padded_hash);
116142
TEST_AND_RETURN_FALSE(utils::WriteFile(hash_path.c_str(),
117-
hash.data(),
118-
hash.size()));
143+
padded_hash.data(),
144+
padded_hash.size()));
119145

120146
// This runs on the server, so it's okay to cop out and call openssl
121147
// executable rather than properly use the library
122148
vector<string> cmd;
123-
SplitString("/usr/bin/openssl rsautl -pkcs -sign -inkey x -in x -out x",
149+
SplitString("/usr/bin/openssl rsautl -raw -sign -inkey x -in x -out x",
124150
' ',
125151
&cmd);
126152
cmd[cmd.size() - 5] = private_key_path;
@@ -220,7 +246,7 @@ bool PayloadSigner::VerifySignature(const std::vector<char>& signature_blob,
220246
reinterpret_cast<const unsigned char*>(sig_data.data()),
221247
reinterpret_cast<unsigned char*>(hash_data.data()),
222248
rsa,
223-
RSA_PKCS1_PADDING);
249+
RSA_NO_PADDING);
224250
RSA_free(rsa);
225251
TEST_AND_RETURN_FALSE(decrypt_size > 0 &&
226252
decrypt_size <= static_cast<int>(hash_data.size()));
@@ -251,6 +277,7 @@ bool PayloadSigner::VerifySignedPayload(const std::string& payload_path,
251277
vector<char> hash;
252278
TEST_AND_RETURN_FALSE(OmahaHashCalculator::RawHashOfBytes(
253279
payload.data(), metadata_size + manifest.signatures_offset(), &hash));
280+
PadRSA2048SHA256Hash(&hash);
254281
TEST_AND_RETURN_FALSE(hash == signed_hash);
255282
return true;
256283
}
@@ -299,4 +326,13 @@ bool PayloadSigner::AddSignatureToPayload(const string& payload_path,
299326
return true;
300327
}
301328

329+
bool PayloadSigner::PadRSA2048SHA256Hash(std::vector<char>* hash) {
330+
TEST_AND_RETURN_FALSE(hash->size() == 32);
331+
hash->insert(hash->begin(),
332+
kRSA2048SHA256Padding,
333+
kRSA2048SHA256Padding + sizeof(kRSA2048SHA256Padding));
334+
TEST_AND_RETURN_FALSE(hash->size() == 256);
335+
return true;
336+
}
337+
302338
} // namespace chromeos_update_engine

payload_signer.h

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ class PayloadSigner {
6767
static bool VerifySignedPayload(const std::string& payload_path,
6868
const std::string& public_key_path);
6969

70+
// Pads a SHA256 hash so that it may be encrypted/signed with RSA2048
71+
// using the PKCS#1 v1.5 scheme.
72+
// hash should be a pointer to vector of exactly 256 bits. The vector
73+
// will be modified in place and will result in having a length of
74+
// 2048 bits. Returns true on success, false otherwise.
75+
static bool PadRSA2048SHA256Hash(std::vector<char>* hash);
7076
private:
7177
// This should never be constructed
7278
DISALLOW_IMPLICIT_CONSTRUCTORS(PayloadSigner);

payload_signer_unittest.cc

+48-20
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ using std::string;
1414
using std::vector;
1515

1616
// Note: the test key was generated with the following command:
17-
// openssl genrsa -out unittest_key.pem 1024
17+
// openssl genrsa -out unittest_key.pem 2048
1818

1919
namespace chromeos_update_engine {
2020

@@ -23,29 +23,55 @@ const char* kUnittestPublicKeyPath = "unittest_key.pub.pem";
2323

2424
// Some data and its corresponding hash and signature:
2525
const char kDataToSign[] = "This is some data to sign.";
26+
27+
// Generated by:
28+
// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
29+
// hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
2630
const char kDataHash[] = {
2731
0x7a, 0x07, 0xa6, 0x44, 0x08, 0x86, 0x20, 0xa6,
2832
0xc1, 0xf8, 0xd9, 0x02, 0x05, 0x63, 0x0d, 0xb7,
2933
0xfc, 0x2b, 0xa0, 0xa9, 0x7c, 0x9d, 0x1d, 0x8c,
3034
0x01, 0xf5, 0x78, 0x6d, 0xc5, 0x11, 0xb4, 0x06
3135
};
36+
37+
// Generated with openssl 1.0, which at the time of this writing, you need
38+
// to download and install yourself. Here's my command:
39+
// echo -n 'This is some data to sign.' | openssl dgst -sha256 -binary |
40+
// ~/local/bin/openssl pkeyutl -sign -inkey unittest_key.pem -pkeyopt
41+
// digest:sha256 | hexdump -v -e '" " 8/1 "0x%02x, " "\n"'
3242
const char kDataSignature[] = {
33-
0xa4, 0xbc, 0x8f, 0xeb, 0x81, 0x05, 0xaa, 0x56,
34-
0x1b, 0x56, 0xe5, 0xcb, 0x9b, 0x1a, 0x00, 0xd7,
35-
0x1d, 0x87, 0x8e, 0xda, 0x5e, 0x90, 0x09, 0xb8,
36-
0x15, 0xf4, 0x25, 0x97, 0x2f, 0x3c, 0xa1, 0xf3,
37-
0x02, 0x75, 0xcd, 0x67, 0x4b, 0x0c, 0x1f, 0xf5,
38-
0x6e, 0xf1, 0x58, 0xd7, 0x0d, 0x8c, 0x18, 0x91,
39-
0x52, 0x30, 0x98, 0x64, 0x58, 0xc0, 0xe2, 0xb5,
40-
0x77, 0x3b, 0x96, 0x8f, 0x05, 0xc4, 0x7f, 0x7a,
41-
0x9a, 0x44, 0x0f, 0xc7, 0x1b, 0x90, 0x83, 0xf8,
42-
0x69, 0x05, 0xa8, 0x02, 0x57, 0xcd, 0x2e, 0x5b,
43-
0x96, 0xc7, 0x77, 0xa6, 0x1f, 0x97, 0x97, 0x05,
44-
0xb3, 0x30, 0x1c, 0x27, 0xd7, 0x2d, 0x31, 0x60,
45-
0x84, 0x7e, 0x99, 0x00, 0xe6, 0xe1, 0x39, 0xa6,
46-
0xf3, 0x3a, 0x72, 0xba, 0xc4, 0xfe, 0x68, 0xa9,
47-
0x08, 0xfa, 0xbc, 0xa8, 0x44, 0x66, 0xa0, 0x60,
48-
0xde, 0xc9, 0xb2, 0xba, 0xbc, 0x80, 0xb5, 0x55
43+
0x9f, 0x86, 0x25, 0x8b, 0xf3, 0xcc, 0xe3, 0x95,
44+
0x5f, 0x45, 0x83, 0xb2, 0x66, 0xf0, 0x2a, 0xcf,
45+
0xb7, 0xaa, 0x52, 0x25, 0x7a, 0xdd, 0x9d, 0x65,
46+
0xe5, 0xd6, 0x02, 0x4b, 0x37, 0x99, 0x53, 0x06,
47+
0xc2, 0xc9, 0x37, 0x36, 0x25, 0x62, 0x09, 0x4f,
48+
0x6b, 0x22, 0xf8, 0xb3, 0x89, 0x14, 0x98, 0x1a,
49+
0xbc, 0x30, 0x90, 0x4a, 0x43, 0xf5, 0xea, 0x2e,
50+
0xf0, 0xa4, 0xba, 0xc3, 0xa7, 0xa3, 0x44, 0x70,
51+
0xd6, 0xc4, 0x89, 0xd8, 0x45, 0x71, 0xbb, 0xee,
52+
0x59, 0x87, 0x3d, 0xd5, 0xe5, 0x40, 0x22, 0x3d,
53+
0x73, 0x7e, 0x2a, 0x58, 0x93, 0x8e, 0xcb, 0x9c,
54+
0xf2, 0xbb, 0x4a, 0xc9, 0xd2, 0x2c, 0x52, 0x42,
55+
0xb0, 0xd1, 0x13, 0x22, 0xa4, 0x78, 0xc7, 0xc6,
56+
0x3e, 0xf1, 0xdc, 0x4c, 0x7b, 0x2d, 0x40, 0xda,
57+
0x58, 0xac, 0x4a, 0x11, 0x96, 0x3d, 0xa0, 0x01,
58+
0xf6, 0x96, 0x74, 0xf6, 0x6c, 0x0c, 0x49, 0x69,
59+
0x4e, 0xc1, 0x7e, 0x9f, 0x2a, 0x42, 0xdd, 0x15,
60+
0x6b, 0x37, 0x2e, 0x3a, 0xa7, 0xa7, 0x6d, 0x91,
61+
0x13, 0xe8, 0x59, 0xde, 0xfe, 0x99, 0x07, 0xd9,
62+
0x34, 0x0f, 0x17, 0xb3, 0x05, 0x4c, 0xd2, 0xc6,
63+
0x82, 0xb7, 0x38, 0x36, 0x63, 0x1d, 0x9e, 0x21,
64+
0xa6, 0x32, 0xef, 0xf1, 0x65, 0xe6, 0xed, 0x95,
65+
0x25, 0x9b, 0x61, 0xe0, 0xba, 0x86, 0xa1, 0x7f,
66+
0xf8, 0xa5, 0x4a, 0x32, 0x1f, 0x15, 0x20, 0x8a,
67+
0x41, 0xc5, 0xb0, 0xd9, 0x4a, 0xda, 0x85, 0xf3,
68+
0xdc, 0xa0, 0x98, 0x5d, 0x1d, 0x18, 0x9d, 0x2e,
69+
0x42, 0xea, 0x69, 0x13, 0x74, 0x3c, 0x74, 0xf7,
70+
0x6d, 0x43, 0xb0, 0x63, 0x90, 0xdb, 0x04, 0xd5,
71+
0x05, 0xc9, 0x73, 0x1f, 0x6c, 0xd6, 0xfa, 0x46,
72+
0x4e, 0x0f, 0x33, 0x58, 0x5b, 0x0d, 0x1b, 0x55,
73+
0x39, 0xb9, 0x0f, 0x43, 0x37, 0xc0, 0x06, 0x0c,
74+
0x29, 0x93, 0x43, 0xc7, 0x43, 0xb9, 0xab, 0x7d
4975
};
5076

5177
//class PayloadSignerTest : public ::testing::Test {};
@@ -96,9 +122,11 @@ TEST(PayloadSignerTest, VerifySignatureTest) {
96122
EXPECT_TRUE(PayloadSigner::VerifySignature(signature_blob,
97123
kUnittestPublicKeyPath,
98124
&hash_data));
99-
ASSERT_EQ(arraysize(kDataHash), hash_data.size());
100-
for (size_t i = 0; i < arraysize(kDataHash); i++) {
101-
EXPECT_EQ(kDataHash[i], hash_data[i]);
125+
vector<char> padded_hash_data(kDataHash, kDataHash + sizeof(kDataHash));
126+
PayloadSigner::PadRSA2048SHA256Hash(&padded_hash_data);
127+
ASSERT_EQ(padded_hash_data.size(), hash_data.size());
128+
for (size_t i = 0; i < padded_hash_data.size(); i++) {
129+
EXPECT_EQ(padded_hash_data[i], hash_data[i]);
102130
}
103131
}
104132

unittest_key.pem

+25-13
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
-----BEGIN RSA PRIVATE KEY-----
2-
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
1527
-----END RSA PRIVATE KEY-----

unittest_key.pub.pem

-6
This file was deleted.

0 commit comments

Comments
 (0)