key_rotation: Support image_family restriction
Check the IMAGE_FAMILY from BIOS key against the image family of the BIOS image.
Tested:
- Failure Example:
```
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: libcr51sign_validate: potential image descriptor found @10000
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: check cr51hash: b15fef5a03633bc69e1b1fea284e199272a331b66234b6da4304766a53306133
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: Hoth RoT config defined 0 KEY_ROTATION_CHUNK_TYPE_CODE_BASH
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: Not match any trusted bios allowed hash
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: Calculating fingerprint of key in CR51 signature structure with scheme(SIGNATURE_RSA3072_PKCS15), size(780)
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: fingerprint of key in CR51 signature: ba6681661fb19e5f5fa59453257f8a5edc020787caf7d60668ab8dfc40de7b8d
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: Hoth RoT config defined 1 KEY_ROTATION_CHUNK_TYPE_CODE_BKEY
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: trusted bios key finger print in KEY_ROTATION_CHUNK_TYPE_CODE_BKEY_0: ba6681661fb19e5f5fa59453257f8a5edc020787caf7d60668ab8dfc40de7b8d
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: Match trusted bios key finger print in KEY_ROTATION_CHUNK_TYPE_CODE_BKEY_0, but mismatch IMAGE_FAMILY 117 vs. 162
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: Not match any trusted bios key
Dec 15 23:12:49 ladai15-nfd11.prod.google.com msvfud[4718]: validate_signature_with_key_in_signature_struct: key in signature struct is not trusted
```
Google-Bug-Id: 466454964
Google-Bug-Id: 468135652
Change-Id: Iaba285d29681529a1b21610ae3434162f4c1471d
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/subprojects/flashupdate/src/validator/key_rotate_helper.cpp b/subprojects/flashupdate/src/validator/key_rotate_helper.cpp
index 9636977..d272628 100644
--- a/subprojects/flashupdate/src/validator/key_rotate_helper.cpp
+++ b/subprojects/flashupdate/src/validator/key_rotate_helper.cpp
@@ -129,7 +129,7 @@
BiosKeyInfo bios_key_info{};
LOG(flashupdate::LogLevel::Notice,
- "Calculating fingerprint of key in CR51 singature structure with scheme({}), size({})",
+ "Calculating fingerprint of key in CR51 signature structure with scheme({}), size({})",
cr51SignSchemeName(scheme), cr51_signature_size);
switch (scheme)
{
@@ -198,7 +198,7 @@
}
LOG(flashupdate::LogLevel::Notice,
- "fingerprint of key in CR51 singature: {}",
+ "fingerprint of key in CR51 signature: {}",
flashupdate::info::bytesToHex(finger_print));
return true;
}
@@ -365,7 +365,8 @@
LOG(flashupdate::LogLevel::Notice, "Hoth RoT config defined {} {}",
trusted_bios_key_count,
rotConfigChunkName(KEY_ROTATION_CHUNK_TYPE_CODE_BKEY));
-
+ struct libcr51sign_ctx* cr51signCtx =
+ reinterpret_cast<struct libcr51sign_ctx*>(ctx);
for (int chunk_index = 0; chunk_index < trusted_bios_key_count;
++chunk_index)
{
@@ -387,6 +388,17 @@
flashupdate::info::bytesToHex(trusted_bios_key->key_fingerprint));
if (sha256Equal(trusted_bios_key->key_fingerprint, key_fingerprint))
{
+ uint32_t imageFamily = cr51signCtx->descriptor.image_family;
+ if (imageFamily != trusted_bios_key->image_family &&
+ imageFamily != IMAGE_FAMILY_ALL &&
+ trusted_bios_key->image_family != IMAGE_FAMILY_ALL)
+ {
+ LOG(flashupdate::LogLevel::Warning,
+ "Match trusted bios key finger print in {}_{}, but mismatch IMAGE_FAMILY {} vs. {}",
+ rotConfigChunkName(KEY_ROTATION_CHUNK_TYPE_CODE_BKEY),
+ chunk_index, imageFamily, trusted_bios_key->image_family);
+ continue;
+ }
LOG(flashupdate::LogLevel::Notice,
"Match trusted bios key finger print in {}_{}",
rotConfigChunkName(KEY_ROTATION_CHUNK_TYPE_CODE_BKEY),
diff --git a/subprojects/flashupdate/test/validator/key_rotate_helper.cpp b/subprojects/flashupdate/test/validator/key_rotate_helper.cpp
index 308f077..da88f19 100644
--- a/subprojects/flashupdate/test/validator/key_rotate_helper.cpp
+++ b/subprojects/flashupdate/test/validator/key_rotate_helper.cpp
@@ -381,7 +381,7 @@
{
EXPECT_FALSE(
trustKeyInCr51Signature(nullptr, SIGNATURE_RSA2048_PKCS15, nullptr, 0));
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
EXPECT_FALSE(trustKeyInCr51Signature(&dummy_ctx, SIGNATURE_RSA2048_PKCS15,
nullptr, 0)); // NOLINT
struct signature_rsa2048_pkcs15 sig;
@@ -391,7 +391,7 @@
TEST_F(KeyRotateHelperTest, TrustKeyInCr51SignatureUnsupportedScheme)
{
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
struct signature_rsa2048_pkcs15 sig{};
EXPECT_FALSE(trustKeyInCr51Signature(
&dummy_ctx, static_cast<enum signature_scheme>(99), &sig, sizeof(sig)));
@@ -399,7 +399,7 @@
TEST_F(KeyRotateHelperTest, TrustKeyInCr51SignatureHashFails)
{
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
struct signature_rsa2048_pkcs15 sig{};
EXPECT_CALL(*mock_api, hash_init(_, HASH_SHA2_256)).WillOnce(Return(1));
EXPECT_FALSE(trustKeyInCr51Signature(&dummy_ctx, SIGNATURE_RSA2048_PKCS15,
@@ -408,7 +408,8 @@
TEST_F(KeyRotateHelperWithDeviceTest, TrustKeyInCr51SignatureMatch)
{
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
+ dummy_ctx.descriptor.image_family = 2;
struct signature_rsa4096_pkcs15 sig = {};
sha256 key_fingerprint{0x01, 0x02, 0x03, 0x04};
@@ -429,6 +430,7 @@
struct bios_verifiction_key_fingerprint* trusted_key =
reinterpret_cast<struct bios_verifiction_key_fingerprint*>(
&response.data);
+ trusted_key->image_family = 2;
memcpy(trusted_key->key_fingerprint, &key_fingerprint,
sizeof(key_fingerprint));
uint16_t response_size = sizeof(struct bios_verifiction_key_fingerprint);
@@ -444,9 +446,51 @@
&sig, sizeof(sig)));
}
+TEST_F(KeyRotateHelperWithDeviceTest,
+ TrustKeyInCr51SignatureMatchMisMatchFamily)
+{
+ struct libcr51sign_ctx dummy_ctx;
+ dummy_ctx.descriptor.image_family = 2;
+ struct signature_rsa4096_pkcs15 sig = {};
+ sha256 key_fingerprint{0x01, 0x02, 0x03, 0x04};
+
+ EXPECT_CALL(*mock_api, hash_init(_, HASH_SHA2_256)).WillOnce(Return(0));
+ EXPECT_CALL(*mock_api, hash_update(_, _, _)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*mock_api, hash_final(_, _))
+ .WillOnce(DoAll(
+ SetArrayArgument<1>(reinterpret_cast<uint8_t*>(&key_fingerprint),
+ reinterpret_cast<uint8_t*>(&key_fingerprint) +
+ sizeof(key_fingerprint)),
+ Return(0)));
+
+ EXPECT_CALL(*mock_api, libhoth_key_rotation_chunk_type_count(
+ dummy_hoth_device_for_suite,
+ KEY_ROTATION_CHUNK_TYPE_CODE_BKEY, _))
+ .WillOnce(DoAll(SetArgPointee<2>(1), Return(KEY_ROTATION_CMD_SUCCESS)));
+ struct hoth_response_key_rotation_record_read response = {};
+ struct bios_verifiction_key_fingerprint* trusted_key =
+ reinterpret_cast<struct bios_verifiction_key_fingerprint*>(
+ &response.data);
+ // Wrong IMAGE_FAMILY
+ trusted_key->image_family = 3;
+ memcpy(trusted_key->key_fingerprint, &key_fingerprint,
+ sizeof(key_fingerprint));
+ uint16_t response_size = sizeof(struct bios_verifiction_key_fingerprint);
+
+ EXPECT_CALL(*mock_api,
+ libhoth_key_rotation_read_chunk_type(
+ dummy_hoth_device_for_suite,
+ KEY_ROTATION_CHUNK_TYPE_CODE_BKEY, 0, _, _, _, _))
+ .WillOnce(
+ DoAll(SetArgPointee<5>(response), SetArgPointee<6>(response_size),
+ Return(KEY_ROTATION_CMD_SUCCESS)));
+ EXPECT_FALSE(trustKeyInCr51Signature(&dummy_ctx, SIGNATURE_RSA4096_PKCS15,
+ &sig, sizeof(sig)));
+}
+
TEST_F(KeyRotateHelperWithDeviceTest, TrustKeyInCr51SignatureMatchOnSecondChunk)
{
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
struct signature_rsa4096_pkcs15 sig = {};
sha256 key_fingerprint{0x01, 0x02, 0x03, 0x04};
@@ -507,7 +551,7 @@
TEST_F(KeyRotateHelperWithDeviceTest, TrustKeyInCr51SignatureMatchOnThirdChunk)
{
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
struct signature_rsa4096_pkcs15 sig = {};
sha256 key_fingerprint{0x01, 0x02, 0x03, 0x04};
@@ -581,7 +625,7 @@
TEST_F(KeyRotateHelperTest, AlwaysTrustKeyInCr51Signature)
{
- char dummy_ctx;
+ struct libcr51sign_ctx dummy_ctx;
struct signature_rsa2048_pkcs15 sig{};
// It should return true even if the underlying function returns false.
EXPECT_CALL(*mock_api, hash_init(_, _)).WillOnce(Return(1)); // make it fail