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