| // Copyright 2022 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include <memory> | |
| #include <utility> | |
| #include <base/strings/string_number_conversions.h> | |
| #include <cstdint> | |
| #include <gtest/gtest.h> | |
| #include <trunks/mock_tpm_utility.h> | |
| #include <libhwsec-foundation/crypto/sha.h> | |
| #include <libhwsec-foundation/error/testing_helper.h> | |
| #include "libhwsec/backend/tpm2/backend_test_base.h" | |
| // Prevent the conflict definition from tss.h | |
| #undef TPM_ALG_RSA | |
| using hwsec_foundation::Sha256; | |
| using hwsec_foundation::error::testing::IsOkAndHolds; | |
| using hwsec_foundation::error::testing::ReturnError; | |
| using hwsec_foundation::error::testing::ReturnValue; | |
| using testing::_; | |
| using testing::DoAll; | |
| using testing::NiceMock; | |
| using testing::Return; | |
| using testing::SaveArg; | |
| using testing::SetArgPointee; | |
| using tpm_manager::TpmManagerStatus; | |
| namespace hwsec { | |
| using BackendEncryptionTpm2Test = BackendTpm2TestBase; | |
| TEST_F(BackendEncryptionTpm2Test, Encrypt) { | |
| const OperationPolicy kFakePolicy{}; | |
| const std::string kFakeKeyBlob = "fake_key_blob"; | |
| const uint32_t kFakeKeyHandle = 0x1337; | |
| const std::string kFakeBlob = "fake_blob"; | |
| const std::string kFakeOutput = "fake_output"; | |
| const trunks::TPMT_PUBLIC kFakePublic = { | |
| .type = trunks::TPM_ALG_RSA, | |
| .name_alg = trunks::TPM_ALG_SHA256, | |
| .object_attributes = trunks::kFixedTPM | trunks::kFixedParent, | |
| .auth_policy = trunks::TPM2B_DIGEST{.size = 0}, | |
| }; | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), LoadKey(kFakeKeyBlob, _, _)) | |
| .WillOnce(DoAll(SetArgPointee<2>(kFakeKeyHandle), | |
| Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), GetKeyPublicArea(kFakeKeyHandle, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<1>(kFakePublic), Return(trunks::TPM_RC_SUCCESS))); | |
| auto key = backend_->GetKeyManagementTpm2().LoadKey( | |
| kFakePolicy, brillo::BlobFromString(kFakeKeyBlob), | |
| Backend::KeyManagement::LoadKeyOptions{}); | |
| ASSERT_OK(key); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), | |
| AsymmetricEncrypt(kFakeKeyHandle, trunks::TPM_ALG_OAEP, | |
| trunks::TPM_ALG_SHA256, _, _, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<5>(kFakeOutput), Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_THAT(backend_->GetEncryptionTpm2().Encrypt( | |
| key->GetKey(), brillo::SecureBlob(kFakeBlob), | |
| Backend::Encryption::EncryptionOptions{}), | |
| IsOkAndHolds(brillo::BlobFromString(kFakeOutput))); | |
| } | |
| TEST_F(BackendEncryptionTpm2Test, EncryptNullAlgo) { | |
| const OperationPolicy kFakePolicy{}; | |
| const std::string kFakeKeyBlob = "fake_key_blob"; | |
| const uint32_t kFakeKeyHandle = 0x1337; | |
| const std::string kFakeBlob = "fake_blob"; | |
| const std::string kFakeOutput = "fake_output"; | |
| const trunks::TPMT_PUBLIC kFakePublic = { | |
| .type = trunks::TPM_ALG_RSA, | |
| .name_alg = trunks::TPM_ALG_SHA256, | |
| .object_attributes = trunks::kFixedTPM | trunks::kFixedParent, | |
| .auth_policy = trunks::TPM2B_DIGEST{.size = 0}, | |
| }; | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), LoadKey(kFakeKeyBlob, _, _)) | |
| .WillOnce(DoAll(SetArgPointee<2>(kFakeKeyHandle), | |
| Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), GetKeyPublicArea(kFakeKeyHandle, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<1>(kFakePublic), Return(trunks::TPM_RC_SUCCESS))); | |
| auto key = backend_->GetKeyManagementTpm2().LoadKey( | |
| kFakePolicy, brillo::BlobFromString(kFakeKeyBlob), | |
| Backend::KeyManagement::LoadKeyOptions{}); | |
| ASSERT_OK(key); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), | |
| AsymmetricEncrypt(kFakeKeyHandle, trunks::TPM_ALG_NULL, | |
| trunks::TPM_ALG_NULL, _, _, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<5>(kFakeOutput), Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_THAT( | |
| backend_->GetEncryptionTpm2().Encrypt( | |
| key->GetKey(), brillo::SecureBlob(kFakeBlob), | |
| Backend::Encryption::EncryptionOptions{ | |
| .schema = Backend::Encryption::EncryptionOptions::Schema::kNull, | |
| }), | |
| IsOkAndHolds(brillo::BlobFromString(kFakeOutput))); | |
| } | |
| TEST_F(BackendEncryptionTpm2Test, EncryptRsaesSha1Algo) { | |
| const OperationPolicy kFakePolicy{}; | |
| const std::string kFakeKeyBlob = "fake_key_blob"; | |
| const uint32_t kFakeKeyHandle = 0x1337; | |
| const std::string kFakeBlob = "fake_blob"; | |
| const std::string kFakeOutput = "fake_output"; | |
| const trunks::TPMT_PUBLIC kFakePublic = { | |
| .type = trunks::TPM_ALG_RSA, | |
| .name_alg = trunks::TPM_ALG_SHA256, | |
| .object_attributes = trunks::kFixedTPM | trunks::kFixedParent, | |
| .auth_policy = trunks::TPM2B_DIGEST{.size = 0}, | |
| }; | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), LoadKey(kFakeKeyBlob, _, _)) | |
| .WillOnce(DoAll(SetArgPointee<2>(kFakeKeyHandle), | |
| Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), GetKeyPublicArea(kFakeKeyHandle, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<1>(kFakePublic), Return(trunks::TPM_RC_SUCCESS))); | |
| auto key = backend_->GetKeyManagementTpm2().LoadKey( | |
| kFakePolicy, brillo::BlobFromString(kFakeKeyBlob), | |
| Backend::KeyManagement::LoadKeyOptions{}); | |
| ASSERT_OK(key); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), | |
| AsymmetricEncrypt(kFakeKeyHandle, trunks::TPM_ALG_RSAES, | |
| trunks::TPM_ALG_SHA1, _, _, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<5>(kFakeOutput), Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_THAT( | |
| backend_->GetEncryptionTpm2().Encrypt( | |
| key->GetKey(), brillo::SecureBlob(kFakeBlob), | |
| Backend::Encryption::EncryptionOptions{ | |
| .schema = | |
| Backend::Encryption::EncryptionOptions::Schema::kRsaesSha1, | |
| }), | |
| IsOkAndHolds(brillo::BlobFromString(kFakeOutput))); | |
| } | |
| TEST_F(BackendEncryptionTpm2Test, Decrypt) { | |
| const OperationPolicy kFakePolicy{}; | |
| const std::string kFakeKeyBlob = "fake_key_blob"; | |
| const uint32_t kFakeKeyHandle = 0x1337; | |
| const std::string kFakeBlob = "fake_blob"; | |
| const std::string kFakeOutput = "fake_output"; | |
| const trunks::TPMT_PUBLIC kFakePublic = { | |
| .type = trunks::TPM_ALG_RSA, | |
| .name_alg = trunks::TPM_ALG_SHA256, | |
| .object_attributes = trunks::kFixedTPM | trunks::kFixedParent, | |
| .auth_policy = trunks::TPM2B_DIGEST{.size = 0}, | |
| }; | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), LoadKey(kFakeKeyBlob, _, _)) | |
| .WillOnce(DoAll(SetArgPointee<2>(kFakeKeyHandle), | |
| Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), GetKeyPublicArea(kFakeKeyHandle, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<1>(kFakePublic), Return(trunks::TPM_RC_SUCCESS))); | |
| auto key = backend_->GetKeyManagementTpm2().LoadKey( | |
| kFakePolicy, brillo::BlobFromString(kFakeKeyBlob), | |
| Backend::KeyManagement::LoadKeyOptions{}); | |
| ASSERT_OK(key); | |
| EXPECT_CALL(proxy_->GetMockTpmUtility(), | |
| AsymmetricDecrypt(kFakeKeyHandle, trunks::TPM_ALG_OAEP, | |
| trunks::TPM_ALG_SHA256, _, _, _)) | |
| .WillOnce( | |
| DoAll(SetArgPointee<5>(kFakeOutput), Return(trunks::TPM_RC_SUCCESS))); | |
| EXPECT_THAT(backend_->GetEncryptionTpm2().Decrypt( | |
| key->GetKey(), brillo::BlobFromString(kFakeBlob), | |
| Backend::Encryption::EncryptionOptions{}), | |
| IsOkAndHolds(brillo::SecureBlob(kFakeOutput))); | |
| } | |
| } // namespace hwsec |