| // Copyright 2023 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <attestation/proto_bindings/attestation_ca.pb.h> |
| #include <base/hash/sha1.h> |
| #include <brillo/secure_blob.h> |
| #include <gtest/gtest.h> |
| #include <libhwsec-foundation/crypto/rsa.h> |
| #include <libhwsec-foundation/crypto/secure_blob_util.h> |
| #include <libhwsec-foundation/error/testing_helper.h> |
| #include <openssl/sha.h> |
| #include <tpm_manager/proto_bindings/tpm_manager.pb.h> |
| #include <tpm_manager-client-test/tpm_manager/dbus-proxy-mocks.h> |
| |
| #include "libhwsec/backend/tpm1/backend_test_base.h" |
| #include "libhwsec/backend/tpm1/static_utils.h" |
| #include "libhwsec/overalls/mock_overalls.h" |
| #include "libhwsec/structures/key.h" |
| |
| using brillo::BlobFromString; |
| using brillo::BlobToString; |
| using testing::_; |
| using testing::Args; |
| using testing::DoAll; |
| using testing::ElementsAreArray; |
| using testing::Not; |
| using testing::Return; |
| using testing::SetArgPointee; |
| using testing::SetArrayArgument; |
| |
| namespace hwsec { |
| |
| namespace { |
| |
| constexpr unsigned int kDefaultTpmRsaKeyBits = 2048; |
| constexpr int kKeySizeBytes = kDefaultTpmRsaKeyBits / 8; |
| |
| MATCHER_P(HasBits, bits, "") { |
| return bits == (bits & arg); |
| } |
| |
| } // namespace |
| |
| class BackendAttestationTpm1Test : public BackendTpm1TestBase { |
| protected: |
| StatusOr<ScopedKey> LoadFakeKey(const uint32_t fake_key_handle) { |
| const OperationPolicy kFakePolicy{}; |
| const brillo::Blob kFakeKeyBlob = brillo::BlobFromString("fake_key_blob"); |
| const brillo::Blob kFakePubkey = brillo::BlobFromString("fake_pubkey"); |
| |
| SetupSrk(); |
| |
| EXPECT_CALL( |
| proxy_->GetMockOveralls(), |
| Ospi_Context_LoadKeyByBlob(kDefaultContext, kDefaultSrkHandle, _, _, _)) |
| .WillOnce( |
| DoAll(SetArgPointee<4>(fake_key_handle), Return(TPM_SUCCESS))); |
| |
| brillo::Blob fake_pubkey = kFakePubkey; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_Key_GetPubKey(fake_key_handle, _, _)) |
| .WillOnce(DoAll(SetArgPointee<1>(fake_pubkey.size()), |
| SetArgPointee<2>(fake_pubkey.data()), |
| Return(TPM_SUCCESS))); |
| |
| return backend_->GetKeyManagementTpm1().LoadKey( |
| kFakePolicy, kFakeKeyBlob, Backend::KeyManagement::LoadKeyOptions{}); |
| } |
| }; |
| |
| TEST_F(BackendAttestationTpm1Test, Quote) { |
| const DeviceConfigs kFakeDeviceConfigs = |
| DeviceConfigs{DeviceConfig::kBootMode}; |
| const brillo::Blob kNonZeroPcr(SHA_DIGEST_LENGTH, 'X'); |
| const uint32_t kFakeKeyHandle = 0x1337; |
| const std::string kFakeQuotedData = "fake_quoted_data"; |
| const std::string kFakeQuote = "fake_quote"; |
| std::string fake_quoted_data = kFakeQuotedData; |
| std::string fake_quote = kFakeQuote; |
| TSS_VALIDATION fake_validation = { |
| .ulDataLength = static_cast<UINT32>(fake_quoted_data.size()), |
| .rgbData = reinterpret_cast<unsigned char*>(fake_quoted_data.data()), |
| .ulValidationDataLength = static_cast<UINT32>(fake_quote.size()), |
| .rgbValidationData = reinterpret_cast<unsigned char*>(fake_quote.data()), |
| }; |
| |
| auto load_key_result = LoadFakeKey(kFakeKeyHandle); |
| ASSERT_OK(load_key_result); |
| const ScopedKey& fake_key = load_key_result.value(); |
| |
| brillo::Blob non_zero_pcr = kNonZeroPcr; |
| EXPECT_CALL(proxy_->GetMockOveralls(), Ospi_TPM_PcrRead(_, _, _, _)) |
| .WillOnce(DoAll(SetArgPointee<2>(non_zero_pcr.size()), |
| SetArgPointee<3>(non_zero_pcr.data()), |
| Return(TPM_SUCCESS))); |
| |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_TPM_Quote(_, kFakeKeyHandle, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_validation), Return(TPM_SUCCESS))); |
| |
| auto result = backend_->GetAttestationTpm1().Quote(kFakeDeviceConfigs, |
| fake_key.GetKey()); |
| ASSERT_OK(result); |
| ASSERT_TRUE(result->has_quoted_pcr_value()); |
| EXPECT_EQ(result->quoted_pcr_value(), BlobToString(kNonZeroPcr)); |
| ASSERT_TRUE(result->has_quoted_data()); |
| EXPECT_EQ(result->quoted_data(), "fake_quoted_data"); |
| ASSERT_TRUE(result->has_quote()); |
| EXPECT_EQ(result->quote(), "fake_quote"); |
| EXPECT_FALSE(result->has_pcr_source_hint()); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, QuoteDeviceModel) { |
| const DeviceConfigs kFakeDeviceConfigs = |
| DeviceConfigs{DeviceConfig::kDeviceModel}; |
| const brillo::Blob kNonZeroPcr(SHA_DIGEST_LENGTH, 'X'); |
| const uint32_t kFakeKeyHandle = 0x1337; |
| const std::string kFakeQuotedData = "fake_quoted_data"; |
| const std::string kFakeQuote = "fake_quote"; |
| std::string fake_quoted_data = kFakeQuotedData; |
| std::string fake_quote = kFakeQuote; |
| TSS_VALIDATION fake_validation = { |
| .ulDataLength = static_cast<UINT32>(fake_quoted_data.size()), |
| .rgbData = reinterpret_cast<unsigned char*>(fake_quoted_data.data()), |
| .ulValidationDataLength = static_cast<UINT32>(fake_quote.size()), |
| .rgbValidationData = reinterpret_cast<unsigned char*>(fake_quote.data()), |
| }; |
| proxy_->GetFakeCrossystem().VbSetSystemPropertyString("hwid", |
| "fake_pcr_source_hint"); |
| |
| auto load_key_result = LoadFakeKey(kFakeKeyHandle); |
| ASSERT_OK(load_key_result); |
| const ScopedKey& fake_key = load_key_result.value(); |
| |
| brillo::Blob non_zero_pcr = kNonZeroPcr; |
| EXPECT_CALL(proxy_->GetMockOveralls(), Ospi_TPM_PcrRead(_, _, _, _)) |
| .WillOnce(DoAll(SetArgPointee<2>(non_zero_pcr.size()), |
| SetArgPointee<3>(non_zero_pcr.data()), |
| Return(TPM_SUCCESS))); |
| |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_TPM_Quote(_, kFakeKeyHandle, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_validation), Return(TPM_SUCCESS))); |
| |
| auto result = backend_->GetAttestationTpm1().Quote(kFakeDeviceConfigs, |
| fake_key.GetKey()); |
| ASSERT_OK(result); |
| ASSERT_TRUE(result->has_quoted_pcr_value()); |
| EXPECT_EQ(result->quoted_pcr_value(), BlobToString(kNonZeroPcr)); |
| ASSERT_TRUE(result->has_quoted_data()); |
| EXPECT_EQ(result->quoted_data(), "fake_quoted_data"); |
| ASSERT_TRUE(result->has_quote()); |
| EXPECT_EQ(result->quote(), "fake_quote"); |
| ASSERT_TRUE(result->has_pcr_source_hint()); |
| EXPECT_EQ(result->pcr_source_hint(), "fake_pcr_source_hint"); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, QuoteMultipleDeviceConfigs) { |
| const DeviceConfigs kFakeDeviceConfigs = |
| DeviceConfigs{DeviceConfig::kBootMode, DeviceConfig::kCurrentUser}; |
| const uint32_t kFakeKeyHandle = 0x1337; |
| const std::string kFakeQuotedData = "fake_quoted_data"; |
| const std::string kFakeQuote = "fake_quote"; |
| std::string fake_quoted_data = kFakeQuotedData; |
| std::string fake_quote = kFakeQuote; |
| TSS_VALIDATION fake_validation = { |
| .ulDataLength = static_cast<UINT32>(fake_quoted_data.size()), |
| .rgbData = reinterpret_cast<unsigned char*>(fake_quoted_data.data()), |
| .ulValidationDataLength = static_cast<UINT32>(fake_quote.size()), |
| .rgbValidationData = reinterpret_cast<unsigned char*>(fake_quote.data()), |
| }; |
| |
| auto load_key_result = LoadFakeKey(kFakeKeyHandle); |
| ASSERT_OK(load_key_result); |
| const ScopedKey& fake_key = load_key_result.value(); |
| |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_TPM_Quote(_, kFakeKeyHandle, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_validation), Return(TPM_SUCCESS))); |
| |
| auto result = backend_->GetAttestationTpm1().Quote(kFakeDeviceConfigs, |
| fake_key.GetKey()); |
| ASSERT_OK(result); |
| EXPECT_FALSE(result->has_quoted_pcr_value()); |
| ASSERT_TRUE(result->has_quoted_data()); |
| EXPECT_EQ(result->quoted_data(), "fake_quoted_data"); |
| ASSERT_TRUE(result->has_quote()); |
| EXPECT_EQ(result->quote(), "fake_quote"); |
| EXPECT_FALSE(result->has_pcr_source_hint()); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, QuoteFailure) { |
| const DeviceConfigs kFakeDeviceConfigs = |
| DeviceConfigs{DeviceConfig::kBootMode}; |
| const brillo::Blob kNonZeroPcr(SHA_DIGEST_LENGTH, 'X'); |
| const uint32_t kFakeKeyHandle = 0x1337; |
| |
| auto load_key_result = LoadFakeKey(kFakeKeyHandle); |
| ASSERT_OK(load_key_result); |
| const ScopedKey& fake_key = load_key_result.value(); |
| |
| brillo::Blob non_zero_pcr = kNonZeroPcr; |
| EXPECT_CALL(proxy_->GetMockOveralls(), Ospi_TPM_PcrRead(_, _, _, _)) |
| .WillOnce(DoAll(SetArgPointee<2>(non_zero_pcr.size()), |
| SetArgPointee<3>(non_zero_pcr.data()), |
| Return(TPM_SUCCESS))); |
| |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_TPM_Quote(_, kFakeKeyHandle, _, _)) |
| .WillOnce(Return(TSS_E_FAIL)); |
| |
| auto result = backend_->GetAttestationTpm1().Quote(kFakeDeviceConfigs, |
| fake_key.GetKey()); |
| ASSERT_NOT_OK(result); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, IsQuoted) { |
| const DeviceConfigs kFakeDeviceConfigs = |
| DeviceConfigs{DeviceConfig::kBootMode}; |
| const DeviceConfigSettings::BootModeSetting::Mode fake_mode = { |
| .developer_mode = false, |
| .recovery_mode = true, |
| .verified_firmware = false, |
| }; |
| brillo::Blob valid_pcr_blob = GetTpm1PCRValueForMode(fake_mode); |
| |
| EXPECT_CALL(proxy_->GetMockOveralls(), Ospi_TPM_PcrRead(_, _, _, _)) |
| .WillOnce(DoAll(SetArgPointee<2>(valid_pcr_blob.size()), |
| SetArgPointee<3>(valid_pcr_blob.data()), |
| Return(TPM_SUCCESS))); |
| |
| const std::string valid_pcr = BlobToString(valid_pcr_blob); |
| const uint8_t value_size = static_cast<unsigned char>(valid_pcr.size()); |
| const uint8_t kFakeCompositeHeaderBuffer[] = { |
| 0, 2, // select_size = 2 (big-endian) |
| 1, 0, // select_bitmap = bit 0 selected |
| 0, 0, 0, value_size, // value_size = valid_pcr.size() (big-endian) |
| }; |
| const std::string kFakeCompositeHeader(std::begin(kFakeCompositeHeaderBuffer), |
| std::end(kFakeCompositeHeaderBuffer)); |
| const std::string kFakePcrComposite = kFakeCompositeHeader + valid_pcr; |
| const std::string kFakePcrDigest = base::SHA1HashString(kFakePcrComposite); |
| const std::string kQuotedData = std::string('x', 8) + kFakePcrDigest; |
| |
| attestation::Quote fake_quote; |
| fake_quote.set_quoted_pcr_value(valid_pcr); |
| fake_quote.set_quoted_data(kQuotedData); |
| auto result = |
| backend_->GetAttestationTpm1().IsQuoted(kFakeDeviceConfigs, fake_quote); |
| ASSERT_OK(result); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, CreateCertifiedKey) { |
| const uint32_t kFakeIdentityHandle = 0x1773; |
| const uint32_t kFakePcrHandle = 0; |
| const uint32_t kFakeKeyHandle = 0x1337; |
| const brillo::Blob kFakeKeyBlob = brillo::BlobFromString("fake_key_blob"); |
| const brillo::Blob kFakePubkey = brillo::BlobFromString("fake_pubkey"); |
| const std::string kFakeCertifyInfo = "fake_certify_info"; |
| const std::string kFakeSignature = "fake_signature"; |
| const attestation::KeyType kFakeKeyType = attestation::KeyType::KEY_TYPE_RSA; |
| const attestation::KeyUsage kFakeKeyUsage = |
| attestation::KeyUsage::KEY_USAGE_DECRYPT; |
| |
| // Load the identity key. |
| auto load_key_result = LoadFakeKey(kFakeIdentityHandle); |
| ASSERT_OK(load_key_result); |
| const ScopedKey& fake_identity_key = load_key_result.value(); |
| |
| // Setup CreateKey |
| brillo::Blob fake_key_blob = kFakeKeyBlob; |
| brillo::Blob fake_pubkey = kFakePubkey; |
| EXPECT_CALL( |
| proxy_->GetMockOveralls(), |
| Ospi_Context_CreateObject(kDefaultContext, TSS_OBJECT_TYPE_RSAKEY, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(kFakeKeyHandle), Return(TPM_SUCCESS))); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_SetAttribUint32(kFakeKeyHandle, TSS_TSPATTRIB_KEY_INFO, |
| TSS_TSPATTRIB_KEYINFO_ENCSCHEME, _)) |
| .WillOnce(Return(TPM_SUCCESS)); |
| EXPECT_CALL( |
| proxy_->GetMockOveralls(), |
| Ospi_Key_CreateKey(kFakeKeyHandle, kDefaultSrkHandle, kFakePcrHandle)) |
| .WillOnce(Return(TPM_SUCCESS)); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_Key_LoadKey(kFakeKeyHandle, kDefaultSrkHandle)) |
| .WillOnce(Return(TPM_SUCCESS)); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_GetAttribData(kFakeKeyHandle, TSS_TSPATTRIB_KEY_BLOB, |
| TSS_TSPATTRIB_KEYBLOB_BLOB, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_key_blob.size()), |
| SetArgPointee<4>(fake_key_blob.data()), |
| Return(TPM_SUCCESS))); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_Key_GetPubKey(kFakeKeyHandle, _, _)) |
| .WillOnce(DoAll(SetArgPointee<1>(fake_pubkey.size()), |
| SetArgPointee<2>(fake_pubkey.data()), |
| Return(TPM_SUCCESS))); |
| |
| // Setup CertifyKey |
| std::string fake_certify_info = kFakeCertifyInfo; |
| std::string fake_signature = kFakeSignature; |
| TSS_VALIDATION fake_validation = { |
| .ulDataLength = static_cast<UINT32>(fake_certify_info.size()), |
| .rgbData = reinterpret_cast<unsigned char*>(fake_certify_info.data()), |
| .ulValidationDataLength = static_cast<UINT32>(fake_signature.size()), |
| .rgbValidationData = |
| reinterpret_cast<unsigned char*>(fake_signature.data()), |
| }; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_Key_CertifyKey(kFakeKeyHandle, kFakeIdentityHandle, _)) |
| .WillOnce(DoAll(SetArgPointee<2>(fake_validation), Return(TPM_SUCCESS))); |
| |
| // Setup GetPublicKeyDer |
| brillo::Blob fake_public_key_der = SetupGetPublicKeyDer(fake_pubkey); |
| |
| std::string external_data = "external_data"; |
| auto result = backend_->GetAttestationTpm1().CreateCertifiedKey( |
| fake_identity_key.GetKey(), kFakeKeyType, kFakeKeyUsage, |
| KeyRestriction::kUnrestricted, EndorsementAuth::kNoEndorsement, |
| external_data); |
| ASSERT_OK(result); |
| ASSERT_TRUE(result->has_key_blob()); |
| ASSERT_TRUE(result->has_public_key()); |
| ASSERT_TRUE(result->has_public_key_tpm_format()); |
| ASSERT_TRUE(result->has_certified_key_info()); |
| ASSERT_TRUE(result->has_certified_key_proof()); |
| ASSERT_TRUE(result->has_key_type()); |
| ASSERT_TRUE(result->has_key_usage()); |
| EXPECT_EQ(result->key_blob(), BlobToString(kFakeKeyBlob)); |
| EXPECT_EQ(result->public_key(), BlobToString(fake_public_key_der)); |
| EXPECT_EQ(result->public_key_tpm_format(), BlobToString(kFakePubkey)); |
| EXPECT_EQ(result->certified_key_info(), kFakeCertifyInfo); |
| EXPECT_EQ(result->certified_key_proof(), kFakeSignature); |
| EXPECT_EQ(result->key_type(), kFakeKeyType); |
| EXPECT_EQ(result->key_usage(), kFakeKeyUsage); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, CreateIdentity) { |
| attestation::KeyType kFakeKeyType = attestation::KEY_TYPE_RSA; |
| const uint32_t kFakePcaKeyHandle = 0x1337; |
| const uint32_t kFakeIdentityKeyHandle = 0x7331; |
| const brillo::Blob kFakePcaPubkey = BlobFromString("fake_pca_pubkey"); |
| const brillo::Blob kFakeIdentityLabel = BlobFromString("fake_identity_label"); |
| const brillo::Blob kFakeRequest = BlobFromString("fake_request"); |
| const brillo::Blob kFakeIdentityPubkey = |
| BlobFromString("fake_identity_pubkey"); |
| const brillo::Blob kFakeIdentityKeyBlob = |
| BlobFromString("fake_identity_key_blob"); |
| |
| const brillo::Blob kFakeSymBlob = BlobFromString("fake_sym_blob"); |
| uint8_t* fake_asym_blob_ptr = static_cast<uint8_t*>(malloc(kKeySizeBytes)); |
| uint8_t* fake_sym_blob_ptr = |
| static_cast<uint8_t*>(malloc(kFakeSymBlob.size())); |
| memcpy(fake_sym_blob_ptr, kFakeSymBlob.data(), kFakeSymBlob.size()); |
| TPM_IDENTITY_REQ fake_identity_req{ |
| .asymSize = static_cast<UINT32>(kKeySizeBytes), |
| .symSize = static_cast<UINT32>(kFakeSymBlob.size()), |
| .asymBlob = fake_asym_blob_ptr, |
| .symBlob = fake_sym_blob_ptr, |
| }; |
| |
| const TPM_ALGORITHM_ID kFakeSymetricKeyAlg = TPM_ALG_RSA; |
| const brillo::Blob kFakeSymmetricKeyData = |
| BlobFromString("fake_symmetric_key_data"); |
| uint8_t* fake_symmetric_key_data_ptr = |
| static_cast<uint8_t*>(malloc(kFakeSymmetricKeyData.size())); |
| memcpy(fake_symmetric_key_data_ptr, kFakeSymmetricKeyData.data(), |
| kFakeSymmetricKeyData.size()); |
| TPM_SYMMETRIC_KEY fake_symmetric_key{ |
| .algId = kFakeSymetricKeyAlg, |
| .size = static_cast<UINT16>(kFakeSymmetricKeyData.size()), |
| .data = fake_symmetric_key_data_ptr, |
| }; |
| |
| const brillo::Blob kFakeProofSerial(kFakeSymBlob.size(), 'x'); |
| const brillo::Blob kFakeIdentityBinding = |
| BlobFromString("fake_identity_binding"); |
| |
| uint8_t* fake_identity_binding_ptr = |
| static_cast<uint8_t*>(malloc(kFakeIdentityBinding.size())); |
| memcpy(fake_symmetric_key_data_ptr, kFakeIdentityBinding.data(), |
| kFakeIdentityBinding.size()); |
| TPM_IDENTITY_PROOF fake_identity_proof{ |
| .identityBindingSize = static_cast<UINT32>(kFakeIdentityBinding.size()), |
| .identityBinding = fake_identity_binding_ptr, |
| }; |
| |
| SetupSrk(); |
| SetupOwner(); |
| |
| // Setup CreateRsaPublicKeyObject for fake PCA key. |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_Context_CreateObject(kDefaultContext, TSS_OBJECT_TYPE_RSAKEY, |
| Not(HasBits(TSS_KEY_TYPE_IDENTITY)), _)) |
| .WillOnce( |
| DoAll(SetArgPointee<3>(kFakePcaKeyHandle), Return(TPM_SUCCESS))); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_SetAttribData(kFakePcaKeyHandle, TSS_TSPATTRIB_RSAKEY_INFO, |
| TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, _, _)) |
| .WillOnce([&](auto&&, auto&&, auto&&, unsigned int size, BYTE* data) { |
| // Create the encrypted asym_blob for the future decryption. |
| brillo::Blob modulus(data, data + size); |
| crypto::ScopedRSA rsa = hwsec_foundation::CreateRSAFromNumber( |
| modulus, hwsec_foundation::kWellKnownExponent); |
| const brillo::SecureBlob random_text = |
| hwsec_foundation::CreateSecureRandomBlob(32); |
| int ret = RSA_public_encrypt(random_text.size(), random_text.data(), |
| fake_asym_blob_ptr, rsa.get(), |
| RSA_PKCS1_PADDING); |
| EXPECT_NE(ret, -1); |
| return TPM_SUCCESS; |
| }); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_SetAttribUint32(kFakePcaKeyHandle, TSS_TSPATTRIB_KEY_INFO, |
| TSS_TSPATTRIB_KEYINFO_ENCSCHEME, _)) |
| .WillOnce(Return(TPM_SUCCESS)); |
| |
| brillo::Blob fake_pca_pubkey = kFakePcaPubkey; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_GetAttribData(kFakePcaKeyHandle, TSS_TSPATTRIB_KEY_BLOB, |
| TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_pca_pubkey.size()), |
| SetArgPointee<4>(fake_pca_pubkey.data()), |
| Return(TPM_SUCCESS))); |
| |
| // Setup for creating identity key |
| unsigned char* fake_identity_label_ptr = |
| static_cast<uint8_t*>(malloc(kFakeIdentityLabel.size())); |
| memcpy(fake_identity_label_ptr, kFakeIdentityLabel.data(), |
| kFakeIdentityLabel.size()); |
| EXPECT_CALL(proxy_->GetMockOveralls(), Orspi_Native_To_UNICODE(_, _)) |
| .WillOnce(DoAll(SetArgPointee<1>(kFakeIdentityLabel.size()), |
| Return(fake_identity_label_ptr))); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_Context_CreateObject(kDefaultContext, TSS_OBJECT_TYPE_RSAKEY, |
| HasBits(TSS_KEY_TYPE_IDENTITY), _)) |
| .WillOnce( |
| DoAll(SetArgPointee<3>(kFakeIdentityKeyHandle), Return(TPM_SUCCESS))); |
| |
| brillo::Blob fake_request = kFakeRequest; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_TPM_CollateIdentityRequest( |
| kDefaultTpm, kDefaultSrkHandle, kFakePcaKeyHandle, |
| kFakeIdentityLabel.size(), fake_identity_label_ptr, |
| kFakeIdentityKeyHandle, TSS_ALG_3DES, _, _)) |
| .WillOnce(DoAll(SetArgPointee<7>(fake_request.size()), |
| SetArgPointee<8>(fake_request.data()), |
| Return(TPM_SUCCESS))); |
| |
| // Setup DecryptIdentityRequest |
| EXPECT_CALL(proxy_->GetMockOveralls(), Orspi_UnloadBlob_IDENTITY_REQ(_, _, _)) |
| .WillOnce( |
| DoAll(SetArgPointee<2>(fake_identity_req), Return(TPM_SUCCESS))); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Orspi_UnloadBlob_SYMMETRIC_KEY(_, _, _)) |
| .WillOnce( |
| DoAll(SetArgPointee<2>(fake_symmetric_key), Return(TPM_SUCCESS))); |
| brillo::Blob fake_proof_serial = kFakeProofSerial; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Orspi_SymDecrypt(kFakeSymetricKeyAlg, _, _, _, fake_sym_blob_ptr, |
| kFakeSymBlob.size(), _, _)) |
| .WillOnce(DoAll(SetArrayArgument<6>(fake_proof_serial.begin(), |
| fake_proof_serial.end()), |
| SetArgPointee<7>(fake_proof_serial.size()), |
| Return(TPM_SUCCESS))); |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Orspi_UnloadBlob_IDENTITY_PROOF(_, _, _)) |
| .WillOnce( |
| DoAll(SetArgPointee<2>(fake_identity_proof), Return(TPM_SUCCESS))); |
| |
| // Get the AIK public key. |
| brillo::Blob fake_identity_pubkey = kFakeIdentityPubkey; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_GetAttribData(kFakeIdentityKeyHandle, TSS_TSPATTRIB_KEY_BLOB, |
| TSS_TSPATTRIB_KEYBLOB_PUBLIC_KEY, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_identity_pubkey.size()), |
| SetArgPointee<4>(fake_identity_pubkey.data()), |
| Return(TPM_SUCCESS))); |
| // Setup GetPublicKeyDer |
| brillo::Blob fake_public_key_der = SetupGetPublicKeyDer(fake_identity_pubkey); |
| // Get the AIK blob so we can load it later. |
| brillo::Blob fake_identity_key_blob = kFakeIdentityKeyBlob; |
| EXPECT_CALL(proxy_->GetMockOveralls(), |
| Ospi_GetAttribData(kFakeIdentityKeyHandle, TSS_TSPATTRIB_KEY_BLOB, |
| TSS_TSPATTRIB_KEYBLOB_BLOB, _, _)) |
| .WillOnce(DoAll(SetArgPointee<3>(fake_identity_key_blob.size()), |
| SetArgPointee<4>(fake_identity_key_blob.data()), |
| Return(TPM_SUCCESS))); |
| |
| auto result = backend_->GetAttestationTpm1().CreateIdentity(kFakeKeyType); |
| ASSERT_OK(result); |
| ASSERT_TRUE(result->identity_key.has_identity_public_key_der()); |
| EXPECT_EQ(result->identity_key.identity_public_key_der(), |
| BlobToString(fake_public_key_der)); |
| } |
| |
| TEST_F(BackendAttestationTpm1Test, FinalizeEnrollmentPreparation) { |
| tpm_manager::RemoveOwnerDependencyReply remove_reply; |
| remove_reply.set_status(tpm_manager::TpmManagerStatus::STATUS_SUCCESS); |
| EXPECT_CALL(proxy_->GetMockTpmManagerProxy(), |
| RemoveOwnerDependency(_, _, _, _)) |
| .WillOnce(DoAll(SetArgPointee<1>(remove_reply), Return(true))); |
| ASSERT_OK(backend_->GetAttestationTpm1().FinalizeEnrollmentPreparation()); |
| } |
| |
| } // namespace hwsec |