blob: 945ddc0d4daf5eed4d0dd46ef3b676b658829ba4 [file] [log] [blame]
// Copyright 2016 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <vector>
#include <base/stl_util.h>
#include <base/strings/string_number_conversions.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <tpm_manager-client/tpm_manager/dbus-constants.h>
#include "attestation/common/tpm_utility_v2.h"
#include <tpm_manager/client/mock_tpm_manager_utility.h>
#include "tpm_manager/common/mock_tpm_nvram_interface.h"
#include "tpm_manager/common/mock_tpm_ownership_interface.h"
#include "trunks/mock_blob_parser.h"
#include "trunks/mock_tpm.h"
#include "trunks/mock_tpm_utility.h"
#include "trunks/trunks_factory_for_test.h"
namespace {
using ::testing::_;
using ::testing::DoAll;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;
using ::testing::WithArg;
using ::trunks::TPM_RC_FAILURE;
using ::trunks::TPM_RC_SUCCESS;
const char kDefaultPassword[] = "password";
std::string HexDecode(const std::string hex) {
std::vector<uint8_t> output;
CHECK(base::HexStringToBytes(hex, &output));
return std::string(reinterpret_cast<char*>(output.data()), output.size());
}
} // namespace
namespace attestation {
class TpmUtilityTest : public testing::Test {
public:
~TpmUtilityTest() override = default;
void SetUp() override {
// Setup default status data.
tpm_status_.set_status(tpm_manager::STATUS_SUCCESS);
tpm_status_.set_enabled(true);
tpm_status_.set_owned(true);
tpm_status_.mutable_local_data()->set_endorsement_password(
kDefaultPassword);
ON_CALL(mock_tpm_utility_, GetKeyPublicArea(_, _))
.WillByDefault(DoAll(SetArgPointee<1>(GetValidRsaPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
// Setup trunks factory with mocks.
trunks_factory_for_test_.set_tpm(&mock_tpm_);
trunks_factory_for_test_.set_tpm_utility(&mock_tpm_utility_);
trunks_factory_for_test_.set_blob_parser(&mock_blob_parser_);
tpm_utility_.reset(new TpmUtilityV2(&mock_tpm_manager_utility_,
&trunks_factory_for_test_));
tpm_utility_->Initialize();
}
protected:
trunks::TPMT_PUBLIC GetValidRsaPublicKey(
std::string* serialized_public_area) {
constexpr char kValidModulusHex[] =
"961037BC12D2A298BEBF06B2D5F8C9B64B832A2237F8CF27D5F96407A6041A4D"
"AD383CB5F88E625F412E8ACD5E9D69DF0F4FA81FCE7955829A38366CBBA5A2B1"
"CE3B48C14B59E9F094B51F0A39155874C8DE18A0C299EBF7A88114F806BE4F25"
"3C29A509B10E4B19E31675AFE3B2DA77077D94F43D8CE61C205781ED04D183B4"
"C349F61B1956C64B5398A3A98FAFF17D1B3D9120C832763EDFC8F4137F6EFBEF"
"46D8F6DE03BD00E49DEF987C10BDD5B6F8758B6A855C23C982DDA14D8F0F2B74"
"E6DEFA7EEE5A6FC717EB0FF103CB8049F693A2C8A5039EF1F5C025DC44BD8435"
"E8D8375DADE00E0C0F5C196E04B8483CC98B1D5B03DCD7E0048B2AB343FFC11F";
trunks::TPMT_PUBLIC public_area = {};
public_area.type = trunks::TPM_ALG_RSA;
public_area.name_alg = trunks::TPM_ALG_SHA256;
public_area.parameters.rsa_detail.key_bits = 2048;
public_area.unique.rsa =
trunks::Make_TPM2B_PUBLIC_KEY_RSA(HexDecode(kValidModulusHex));
if (serialized_public_area) {
Serialize_TPMT_PUBLIC(public_area, serialized_public_area);
}
return public_area;
}
trunks::TPMT_PUBLIC GetValidEccPublicKey(
std::string* serialized_public_area) {
constexpr char kValidECPointX[] =
"06845c8f3ac8b98d0e8163d0475ad4c8be1710c9f2d39965719e3684a7b3f40b";
constexpr char kValidECPointY[] =
"0400e219928d45093b3d7ff3cae43468e24684454f318b83b12304d1194a3286";
trunks::TPMT_PUBLIC public_area = {};
std::vector<uint8_t> point_tmp_buffer;
CHECK(base::HexStringToBytes(kValidECPointX, &point_tmp_buffer));
CHECK_EQ(point_tmp_buffer.size(), base::size(kValidECPointX) / 2);
public_area.unique.ecc.x.size = point_tmp_buffer.size();
memcpy(public_area.unique.ecc.x.buffer, point_tmp_buffer.data(),
point_tmp_buffer.size());
point_tmp_buffer.clear();
CHECK(base::HexStringToBytes(kValidECPointY, &point_tmp_buffer));
CHECK_EQ(point_tmp_buffer.size(), base::size(kValidECPointY) / 2);
public_area.unique.ecc.y.size = point_tmp_buffer.size();
memcpy(public_area.unique.ecc.y.buffer, point_tmp_buffer.data(),
point_tmp_buffer.size());
public_area.type = trunks::TPM_ALG_ECC;
public_area.name_alg = trunks::TPM_ALG_SHA256;
public_area.parameters.ecc_detail.curve_id = trunks::TPM_ECC_NIST_P256;
public_area.parameters.ecc_detail.kdf.scheme = trunks::TPM_ALG_NULL;
public_area.parameters.ecc_detail.scheme.scheme = trunks::TPM_ALG_NULL;
if (serialized_public_area) {
Serialize_TPMT_PUBLIC(public_area, serialized_public_area);
}
return public_area;
}
void ExpectGetTpmStatus() {
tpm_manager::LocalData local_data;
local_data.set_owner_password("password");
local_data.set_endorsement_password("endorsement_password");
EXPECT_CALL(mock_tpm_manager_utility_, GetTpmStatus(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(local_data), Return(true)));
}
tpm_manager::GetTpmStatusReply tpm_status_;
NiceMock<tpm_manager::MockTpmManagerUtility> mock_tpm_manager_utility_;
NiceMock<trunks::MockTpm> mock_tpm_;
NiceMock<trunks::MockTpmUtility> mock_tpm_utility_;
NiceMock<trunks::MockBlobParser> mock_blob_parser_;
trunks::TrunksFactoryForTest trunks_factory_for_test_;
std::unique_ptr<TpmUtilityV2> tpm_utility_;
};
TEST_F(TpmUtilityTest, ActivateIdentity) {
ExpectGetTpmStatus();
trunks::TPM2B_DIGEST fake_credential =
trunks::Make_TPM2B_DIGEST("fake_credential");
EXPECT_CALL(mock_tpm_, ActivateCredentialSync(_, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<6>(fake_credential), Return(TPM_RC_SUCCESS)));
std::string credential;
EXPECT_TRUE(tpm_utility_->ActivateIdentityForTpm2(
KEY_TYPE_RSA, "fake_identity_blob", "seed", "mac", "wrapped",
&credential));
EXPECT_EQ("fake_credential", credential);
}
TEST_F(TpmUtilityTest, ActivateIdentityFailLoadIdentityKey) {
EXPECT_CALL(mock_tpm_utility_, LoadKey(_, _, _))
.WillRepeatedly(Return(TPM_RC_SUCCESS));
EXPECT_CALL(mock_tpm_utility_, LoadKey("fake_identity_blob", _, _))
.WillOnce(Return(TPM_RC_FAILURE));
std::string credential;
EXPECT_FALSE(tpm_utility_->ActivateIdentityForTpm2(
KEY_TYPE_RSA, "fake_identity_blob", "seed", "mac", "wrapped",
&credential));
EXPECT_TRUE(credential.empty());
}
TEST_F(TpmUtilityTest, ActivateIdentityFailLoadEndorsementKey) {
ExpectGetTpmStatus();
EXPECT_CALL(mock_tpm_utility_, GetEndorsementKey(_, _, _, _))
.WillOnce(Return(TPM_RC_FAILURE));
std::string credential;
EXPECT_FALSE(tpm_utility_->ActivateIdentityForTpm2(
KEY_TYPE_RSA, "fake_identity_blob", "seed", "mac", "wrapped",
&credential));
EXPECT_TRUE(credential.empty());
}
TEST_F(TpmUtilityTest, ActivateIdentityNoEndorsementPassword) {
tpm_status_.mutable_local_data()->clear_endorsement_password();
std::string credential;
EXPECT_FALSE(tpm_utility_->ActivateIdentityForTpm2(
KEY_TYPE_RSA, "fake_identity_blob", "seed", "mac", "wrapped",
&credential));
EXPECT_TRUE(credential.empty());
}
TEST_F(TpmUtilityTest, ActivateIdentityError) {
ExpectGetTpmStatus();
EXPECT_CALL(mock_tpm_, ActivateCredentialSync(_, _, _, _, _, _, _, _))
.WillOnce(Return(TPM_RC_FAILURE));
std::string credential;
EXPECT_FALSE(tpm_utility_->ActivateIdentityForTpm2(
KEY_TYPE_RSA, "fake_identity_blob", "seed", "mac", "wrapped",
&credential));
EXPECT_TRUE(credential.empty());
}
TEST_F(TpmUtilityTest, CreateCertifiedKeyWithRsaKey) {
EXPECT_CALL(mock_tpm_utility_, CreateRSAKeyPair(_, _, _, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<8>("fake_key_blob"), Return(TPM_RC_SUCCESS)));
trunks::TPM2B_DATA external_data;
trunks::TPMT_SIG_SCHEME scheme;
trunks::TPM2B_ATTEST fake_certify_info =
trunks::Make_TPM2B_ATTEST("fake_attest");
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_RSASSA;
fake_signature.signature.rsassa.sig =
trunks::Make_TPM2B_PUBLIC_KEY_RSA("fake_proof");
EXPECT_CALL(mock_tpm_, CertifySync(_, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&external_data), SaveArg<5>(&scheme),
SetArgPointee<6>(fake_certify_info),
SetArgPointee<7>(fake_signature),
Return(TPM_RC_SUCCESS)));
std::string key_blob;
std::string public_key_der;
std::string public_key_tpm_format;
std::string key_info;
std::string proof;
EXPECT_TRUE(tpm_utility_->CreateCertifiedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, "fake_identity_blob", "fake_external_data",
&key_blob, &public_key_der, &public_key_tpm_format, &key_info, &proof));
EXPECT_EQ("fake_key_blob", key_blob);
EXPECT_NE("", public_key_der);
EXPECT_NE("", public_key_tpm_format);
EXPECT_EQ("fake_attest", key_info);
EXPECT_NE(std::string::npos, proof.find("fake_proof"));
EXPECT_EQ("fake_external_data", trunks::StringFrom_TPM2B_DATA(external_data));
EXPECT_EQ(trunks::TPM_ALG_RSASSA, scheme.scheme);
EXPECT_EQ(trunks::TPM_ALG_SHA256, scheme.details.rsassa.hash_alg);
}
TEST_F(TpmUtilityTest, CreateCertifiedKeyWithEccKey) {
const std::string kFakeKeyBlob = "fake_key_blob";
EXPECT_CALL(mock_tpm_utility_, CreateECCKeyPair(_, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SetArgPointee<7>(kFakeKeyBlob), Return(TPM_RC_SUCCESS)));
// make sure LoadKey(created key) return ECC, RSA for AIK
EXPECT_CALL(mock_tpm_utility_, LoadKey(_, _, _))
.WillRepeatedly(Return(TPM_RC_SUCCESS));
constexpr trunks::TPM_HANDLE kFakeKeyHandle = 0x12345678;
EXPECT_CALL(mock_tpm_utility_, LoadKey(kFakeKeyBlob, _, _))
.WillOnce(
DoAll(SetArgPointee<2>(kFakeKeyHandle), Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(_, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidRsaPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(kFakeKeyHandle, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidEccPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
// Still use RSA AIK to certified, so return the RSA signature.
trunks::TPM2B_DATA external_data;
trunks::TPMT_SIG_SCHEME scheme;
trunks::TPM2B_ATTEST fake_certify_info =
trunks::Make_TPM2B_ATTEST("fake_attest");
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_RSASSA;
fake_signature.signature.rsassa.sig =
trunks::Make_TPM2B_PUBLIC_KEY_RSA("fake_proof");
EXPECT_CALL(mock_tpm_, CertifySync(_, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&external_data), SaveArg<5>(&scheme),
SetArgPointee<6>(fake_certify_info),
SetArgPointee<7>(fake_signature),
Return(TPM_RC_SUCCESS)));
std::string key_blob;
std::string public_key_der;
std::string public_key_tpm_format;
std::string key_info;
std::string proof;
EXPECT_TRUE(tpm_utility_->CreateCertifiedKey(
KEY_TYPE_ECC, KEY_USAGE_SIGN, "fake_identity_blob", "fake_external_data",
&key_blob, &public_key_der, &public_key_tpm_format, &key_info, &proof));
EXPECT_EQ(key_blob, kFakeKeyBlob);
EXPECT_NE(public_key_der, "");
EXPECT_NE(public_key_tpm_format, "");
EXPECT_EQ(key_info, "fake_attest");
EXPECT_NE(proof.find("fake_proof"), std::string::npos);
EXPECT_EQ(trunks::StringFrom_TPM2B_DATA(external_data), "fake_external_data");
EXPECT_EQ(scheme.scheme, trunks::TPM_ALG_RSASSA);
EXPECT_EQ(scheme.details.rsassa.hash_alg, trunks::TPM_ALG_SHA256);
}
TEST_F(TpmUtilityTest, CreateCertifiedKeyWithEccCertified) {
EXPECT_CALL(mock_tpm_utility_, CreateRSAKeyPair(_, _, _, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<8>("fake_key_blob"), Return(TPM_RC_SUCCESS)));
// make sure LoadKey(created key) return RSA, but ECC for AIK
constexpr trunks::TPM_HANDLE kFakeKeyHandle = 0x87654321;
EXPECT_CALL(mock_tpm_utility_, LoadKey("fake_key_blob", _, _))
.WillOnce(
DoAll(SetArgPointee<2>(kFakeKeyHandle), Return(TPM_RC_SUCCESS)));
constexpr trunks::TPM_HANDLE kFakeIdentityHandle = 0x12345678;
EXPECT_CALL(mock_tpm_utility_, LoadKey("fake_identity_blob", _, _))
.WillOnce(
DoAll(SetArgPointee<2>(kFakeIdentityHandle), Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(kFakeKeyHandle, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidRsaPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(kFakeIdentityHandle, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidEccPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
trunks::TPM2B_DATA external_data;
trunks::TPMT_SIG_SCHEME scheme;
trunks::TPM2B_ATTEST fake_certify_info =
trunks::Make_TPM2B_ATTEST("fake_attest");
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_ECDSA;
fake_signature.signature.ecdsa.signature_r =
trunks::Make_TPM2B_ECC_PARAMETER("fake_proof_r");
fake_signature.signature.ecdsa.signature_s =
trunks::Make_TPM2B_ECC_PARAMETER("fake_proof_s");
EXPECT_CALL(mock_tpm_, CertifySync(_, _, _, _, _, _, _, _, _))
.WillOnce(DoAll(SaveArg<4>(&external_data), SaveArg<5>(&scheme),
SetArgPointee<6>(fake_certify_info),
SetArgPointee<7>(fake_signature),
Return(TPM_RC_SUCCESS)));
std::string key_blob;
std::string public_key_der;
std::string public_key_tpm_format;
std::string key_info;
std::string proof;
EXPECT_TRUE(tpm_utility_->CreateCertifiedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, "fake_identity_blob", "fake_external_data",
&key_blob, &public_key_der, &public_key_tpm_format, &key_info, &proof));
EXPECT_EQ("fake_key_blob", key_blob);
EXPECT_NE("", public_key_der);
EXPECT_NE("", public_key_tpm_format);
EXPECT_EQ("fake_attest", key_info);
EXPECT_NE(proof.find("fake_proof_r"), std::string::npos);
EXPECT_NE(proof.find("fake_proof_s"), std::string::npos);
EXPECT_EQ("fake_external_data", trunks::StringFrom_TPM2B_DATA(external_data));
EXPECT_EQ(trunks::TPM_ALG_ECDSA, scheme.scheme);
EXPECT_EQ(trunks::TPM_ALG_SHA256, scheme.details.rsassa.hash_alg);
}
TEST_F(TpmUtilityTest, CreateCertifiedKeyFailCreate) {
EXPECT_CALL(mock_tpm_utility_, CreateRSAKeyPair(_, _, _, _, _, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string key_blob;
std::string public_key_der;
std::string public_key_tpm_format;
std::string key_info;
std::string proof;
EXPECT_FALSE(tpm_utility_->CreateCertifiedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, "fake_identity_blob", "fake_external_data",
&key_blob, &public_key_der, &public_key_tpm_format, &key_info, &proof));
EXPECT_EQ("", key_blob);
EXPECT_EQ("", public_key_der);
EXPECT_EQ("", public_key_tpm_format);
}
TEST_F(TpmUtilityTest, CreateCertifiedKeyFailCertify) {
EXPECT_CALL(mock_tpm_utility_, CreateRSAKeyPair(_, _, _, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<8>("fake_key_blob"), Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_, CertifySync(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string key_blob;
std::string public_key_der;
std::string public_key_tpm_format;
std::string key_info;
std::string proof;
EXPECT_FALSE(tpm_utility_->CreateCertifiedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, "fake_identity_blob", "fake_external_data",
&key_blob, &public_key_der, &public_key_tpm_format, &key_info, &proof));
}
TEST_F(TpmUtilityTest, SealToPCR0) {
EXPECT_CALL(mock_tpm_utility_, SealData("fake_data", _, "", _, _))
.WillOnce(DoAll(SetArgPointee<4>("fake_sealed"), Return(TPM_RC_SUCCESS)));
std::string sealed_data;
EXPECT_TRUE(tpm_utility_->SealToPCR0("fake_data", &sealed_data));
EXPECT_EQ("fake_sealed", sealed_data);
}
TEST_F(TpmUtilityTest, SealToPCR0Fail) {
EXPECT_CALL(mock_tpm_utility_, SealData("fake_data", _, "", _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string sealed_data;
EXPECT_FALSE(tpm_utility_->SealToPCR0("fake_data", &sealed_data));
EXPECT_EQ("", sealed_data);
}
TEST_F(TpmUtilityTest, Unseal) {
EXPECT_CALL(mock_tpm_utility_, UnsealData("fake_sealed", _, _))
.WillOnce(DoAll(SetArgPointee<2>("fake_data"), Return(TPM_RC_SUCCESS)));
std::string data;
EXPECT_TRUE(tpm_utility_->Unseal("fake_sealed", &data));
EXPECT_EQ("fake_data", data);
}
TEST_F(TpmUtilityTest, UnsealFail) {
EXPECT_CALL(mock_tpm_utility_, UnsealData("fake_sealed", _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string data;
EXPECT_FALSE(tpm_utility_->Unseal("fake_sealed", &data));
EXPECT_EQ("", data);
}
TEST_F(TpmUtilityTest, GetEndorsementPublicKey) {
ExpectGetTpmStatus();
std::string key;
EXPECT_TRUE(tpm_utility_->GetEndorsementPublicKey(KEY_TYPE_RSA, &key));
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(_, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidEccPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
EXPECT_TRUE(tpm_utility_->GetEndorsementPublicKey(KEY_TYPE_ECC, &key));
}
TEST_F(TpmUtilityTest, GetEndorsementPublicKeyModulusSuccess) {
EXPECT_CALL(mock_tpm_utility_, GetPublicRSAEndorsementKeyModulus(_))
.WillRepeatedly(Return(TPM_RC_SUCCESS));
std::string key;
EXPECT_TRUE(tpm_utility_->GetEndorsementPublicKeyModulus(KEY_TYPE_RSA, &key));
// The key type ECC is not implemented yet.
EXPECT_FALSE(
tpm_utility_->GetEndorsementPublicKeyModulus(KEY_TYPE_ECC, &key));
}
TEST_F(TpmUtilityTest, GetEndorsementPublicKeyModulusNoKey) {
EXPECT_CALL(mock_tpm_utility_, GetPublicRSAEndorsementKeyModulus(_))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string key;
EXPECT_FALSE(
tpm_utility_->GetEndorsementPublicKeyModulus(KEY_TYPE_RSA, &key));
EXPECT_TRUE(key.empty());
EXPECT_FALSE(
tpm_utility_->GetEndorsementPublicKeyModulus(KEY_TYPE_ECC, &key));
EXPECT_TRUE(key.empty());
}
TEST_F(TpmUtilityTest, GetEndorsementCertificateRsa) {
EXPECT_CALL(
mock_tpm_manager_utility_,
ReadSpace(trunks::kRsaEndorsementCertificateNonRealIndex, false, _))
.WillOnce(DoAll(SetArgPointee<2>("rsa_cert"), Return(true)));
std::string certificate;
EXPECT_TRUE(
tpm_utility_->GetEndorsementCertificate(KEY_TYPE_RSA, &certificate));
EXPECT_EQ("rsa_cert", certificate);
}
TEST_F(TpmUtilityTest, GetEndorsementCertificateEcc) {
EXPECT_CALL(
mock_tpm_manager_utility_,
ReadSpace(trunks::kEccEndorsementCertificateNonRealIndex, false, _))
.WillOnce(DoAll(SetArgPointee<2>("ecc_cert"), Return(true)));
std::string certificate;
EXPECT_TRUE(
tpm_utility_->GetEndorsementCertificate(KEY_TYPE_ECC, &certificate));
EXPECT_EQ("ecc_cert", certificate);
}
TEST_F(TpmUtilityTest, GetEndorsementCertificateNoCert) {
EXPECT_CALL(
mock_tpm_manager_utility_,
ReadSpace(trunks::kRsaEndorsementCertificateNonRealIndex, false, _))
.WillOnce(Return(false));
std::string certificate;
EXPECT_FALSE(
tpm_utility_->GetEndorsementCertificate(KEY_TYPE_RSA, &certificate));
}
TEST_F(TpmUtilityTest, Unbind) {
EXPECT_CALL(mock_tpm_utility_,
AsymmetricDecrypt(_, _, _, "fake_encrypted", _, _))
.WillOnce(DoAll(SetArgPointee<5>("fake_data"), Return(TPM_RC_SUCCESS)));
std::string data;
EXPECT_TRUE(tpm_utility_->Unbind("fake_key_blob", "fake_encrypted", &data));
EXPECT_EQ("fake_data", data);
}
TEST_F(TpmUtilityTest, UnbindFail) {
EXPECT_CALL(mock_tpm_utility_,
AsymmetricDecrypt(_, _, _, "fake_encrypted", _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string data;
EXPECT_FALSE(tpm_utility_->Unbind("fake_key_blob", "fake_encrypted", &data));
EXPECT_EQ("", data);
}
TEST_F(TpmUtilityTest, SignWithRsa) {
EXPECT_CALL(mock_tpm_utility_,
Sign(_, trunks::TPM_ALG_RSASSA, _, "fake_to_sign", true, _, _))
.WillOnce(
DoAll(SetArgPointee<6>("fake_signature"), Return(TPM_RC_SUCCESS)));
std::string signature;
EXPECT_TRUE(tpm_utility_->Sign("fake_key_blob", "fake_to_sign", &signature));
EXPECT_EQ("fake_signature", signature);
}
TEST_F(TpmUtilityTest, SignWithEcc) {
// Sign() have to return a Serialized TPMT_SIGNATURE string for ECDSA
trunks::TPMT_SIGNATURE fake_signature = {};
fake_signature.sig_alg = trunks::TPM_ALG_ECDSA;
fake_signature.signature.ecdsa.signature_r =
trunks::Make_TPM2B_ECC_PARAMETER("fake_signature_r");
fake_signature.signature.ecdsa.signature_s =
trunks::Make_TPM2B_ECC_PARAMETER("fake_signature_s");
std::string fake_signature_string;
trunks::Serialize_TPMT_SIGNATURE(fake_signature, &fake_signature_string);
EXPECT_CALL(mock_tpm_utility_,
Sign(_, trunks::TPM_ALG_ECDSA, _, "fake_to_sign", true, _, _))
.WillOnce(DoAll(SetArgPointee<6>(fake_signature_string),
Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(_, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidEccPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
std::string signature;
EXPECT_TRUE(tpm_utility_->Sign("fake_key_blob", "fake_to_sign", &signature));
EXPECT_NE(signature.find("fake_signature_r"), std::string::npos);
EXPECT_NE(signature.find("fake_signature_s"), std::string::npos);
}
TEST_F(TpmUtilityTest, SignFail) {
EXPECT_CALL(mock_tpm_utility_, Sign(_, _, _, "fake_to_sign", true, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string signature;
EXPECT_FALSE(tpm_utility_->Sign("fake_key_blob", "fake_to_sign", &signature));
EXPECT_EQ("", signature);
}
TEST_F(TpmUtilityTest, CreateRestrictedKeySuccessWithRsa) {
EXPECT_CALL(mock_tpm_utility_, CreateIdentityKey(trunks::TPM_ALG_RSA, _, _))
.WillOnce(
DoAll(SetArgPointee<2>("fake_key_blob"), Return(TPM_RC_SUCCESS)));
std::string expected_public_key;
trunks::TPMT_PUBLIC public_area = GetValidRsaPublicKey(&expected_public_key);
EXPECT_CALL(mock_blob_parser_, ParseKeyBlob("fake_key_blob", _, _))
.WillRepeatedly(
DoAll(SetArgPointee<1>(trunks::Make_TPM2B_PUBLIC(public_area)),
Return(true)));
std::string public_key_der;
std::string public_key_tpm_format;
std::string private_key;
EXPECT_TRUE(tpm_utility_->CreateRestrictedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, &public_key_der, &public_key_tpm_format,
&private_key));
EXPECT_NE("", public_key_der);
EXPECT_EQ(expected_public_key, public_key_tpm_format);
EXPECT_EQ("fake_key_blob", private_key);
}
TEST_F(TpmUtilityTest, CreateRestrictedKeySuccessWithEcc) {
EXPECT_CALL(mock_tpm_utility_, CreateIdentityKey(trunks::TPM_ALG_ECC, _, _))
.WillOnce(
DoAll(SetArgPointee<2>("fake_key_blob"), Return(TPM_RC_SUCCESS)));
std::string expected_public_key;
trunks::TPMT_PUBLIC public_area = GetValidEccPublicKey(&expected_public_key);
EXPECT_CALL(mock_blob_parser_, ParseKeyBlob("fake_key_blob", _, _))
.WillRepeatedly(
DoAll(SetArgPointee<1>(trunks::Make_TPM2B_PUBLIC(public_area)),
Return(true)));
std::string public_key_der;
std::string public_key_tpm_format;
std::string private_key;
EXPECT_TRUE(tpm_utility_->CreateRestrictedKey(
KEY_TYPE_ECC, KEY_USAGE_SIGN, &public_key_der, &public_key_tpm_format,
&private_key));
EXPECT_NE("", public_key_der);
EXPECT_EQ(expected_public_key, public_key_tpm_format);
EXPECT_EQ("fake_key_blob", private_key);
}
TEST_F(TpmUtilityTest, CreateRestrictedKeyFail) {
EXPECT_CALL(mock_tpm_utility_, CreateIdentityKey(trunks::TPM_ALG_RSA, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string public_key_der;
std::string public_key_tpm_format;
std::string private_key;
EXPECT_FALSE(tpm_utility_->CreateRestrictedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, &public_key_der, &public_key_tpm_format,
&private_key));
EXPECT_EQ("", public_key_der);
EXPECT_EQ("", public_key_tpm_format);
EXPECT_EQ("", private_key);
}
TEST_F(TpmUtilityTest, CreateRestrictedKeyParserFail) {
EXPECT_CALL(mock_tpm_utility_, CreateIdentityKey(trunks::TPM_ALG_RSA, _, _))
.WillOnce(
DoAll(SetArgPointee<2>("fake_key_blob"), Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_blob_parser_, ParseKeyBlob("fake_key_blob", _, _))
.WillRepeatedly(Return(false));
std::string public_key_der;
std::string public_key_tpm_format;
std::string private_key;
EXPECT_FALSE(tpm_utility_->CreateRestrictedKey(
KEY_TYPE_RSA, KEY_USAGE_SIGN, &public_key_der, &public_key_tpm_format,
&private_key));
EXPECT_EQ("", public_key_der);
EXPECT_EQ("", public_key_tpm_format);
}
TEST_F(TpmUtilityTest, QuotePCRWithRsa) {
EXPECT_CALL(mock_tpm_utility_, ReadPCR(5, _))
.WillRepeatedly(
DoAll(SetArgPointee<1>("fake_pcr_value"), Return(TPM_RC_SUCCESS)));
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_RSASSA;
fake_signature.signature.rsassa.sig =
trunks::Make_TPM2B_PUBLIC_KEY_RSA("fake_quote");
EXPECT_CALL(mock_tpm_, QuoteSync(_, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<5>(trunks::Make_TPM2B_ATTEST("fake_quoted_data")),
SetArgPointee<6>(fake_signature), Return(TPM_RC_SUCCESS)));
std::string value;
std::string quoted_data;
std::string quote;
EXPECT_TRUE(
tpm_utility_->QuotePCR(5, "fake_key_blob", &value, &quoted_data, &quote));
EXPECT_EQ("fake_pcr_value", value);
EXPECT_EQ("fake_quoted_data", quoted_data);
EXPECT_NE(std::string::npos, quote.find("fake_quote"));
}
TEST_F(TpmUtilityTest, QuotePCRWithEcc) {
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(_, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidEccPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
EXPECT_CALL(mock_tpm_utility_, ReadPCR(5, _))
.WillRepeatedly(
DoAll(SetArgPointee<1>("fake_pcr_value"), Return(TPM_RC_SUCCESS)));
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_ECDSA;
fake_signature.signature.ecdsa.signature_r =
trunks::Make_TPM2B_ECC_PARAMETER("fake_quote_r");
fake_signature.signature.ecdsa.signature_s =
trunks::Make_TPM2B_ECC_PARAMETER("fake_quote_s");
EXPECT_CALL(mock_tpm_, QuoteSync(_, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<5>(trunks::Make_TPM2B_ATTEST("fake_quoted_data")),
SetArgPointee<6>(fake_signature), Return(TPM_RC_SUCCESS)));
std::string value;
std::string quoted_data;
std::string quote;
EXPECT_TRUE(
tpm_utility_->QuotePCR(5, "fake_key_blob", &value, &quoted_data, &quote));
EXPECT_EQ("fake_pcr_value", value);
EXPECT_EQ("fake_quoted_data", quoted_data);
EXPECT_NE(quote.find("fake_quote_r"), std::string::npos);
EXPECT_NE(quote.find("fake_quote_s"), std::string::npos);
}
TEST_F(TpmUtilityTest, QuotePCRFail) {
EXPECT_CALL(mock_tpm_utility_, ReadPCR(5, _))
.WillRepeatedly(
DoAll(SetArgPointee<1>("fake_pcr_value"), Return(TPM_RC_SUCCESS)));
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_RSASSA;
fake_signature.signature.rsassa.sig =
trunks::Make_TPM2B_PUBLIC_KEY_RSA("fake_quote");
EXPECT_CALL(mock_tpm_, QuoteSync(_, _, _, _, _, _, _, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string value;
std::string quoted_data;
std::string quote;
EXPECT_FALSE(
tpm_utility_->QuotePCR(5, "fake_key_blob", &value, &quoted_data, &quote));
EXPECT_EQ("", quoted_data);
EXPECT_EQ("", quote);
}
TEST_F(TpmUtilityTest, QuotePCRFailReadPCR) {
EXPECT_CALL(mock_tpm_utility_, ReadPCR(5, _))
.WillRepeatedly(Return(TPM_RC_FAILURE));
std::string value;
std::string quoted_data;
std::string quote;
EXPECT_FALSE(
tpm_utility_->QuotePCR(5, "fake_key_blob", &value, &quoted_data, &quote));
EXPECT_EQ("", value);
}
TEST_F(TpmUtilityTest, ReadPCR) {
EXPECT_CALL(mock_tpm_utility_, ReadPCR(5, _))
.WillOnce(
DoAll(SetArgPointee<1>("fake_pcr_value"), Return(TPM_RC_SUCCESS)));
std::string value;
EXPECT_TRUE(tpm_utility_->ReadPCR(5, &value));
EXPECT_EQ("fake_pcr_value", value);
}
TEST_F(TpmUtilityTest, ReadPCRFail) {
EXPECT_CALL(mock_tpm_utility_, ReadPCR(5, _))
.WillOnce(Return(TPM_RC_FAILURE));
std::string value;
EXPECT_FALSE(tpm_utility_->ReadPCR(5, &value));
EXPECT_EQ("", value);
}
TEST_F(TpmUtilityTest, CertifyNVWithRsa) {
constexpr int kFakeNvIndex = 0x123;
constexpr int kFakeNvSize = 0x456;
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_RSASSA;
fake_signature.signature.rsassa.sig =
trunks::Make_TPM2B_PUBLIC_KEY_RSA("fake_quote");
EXPECT_CALL(mock_tpm_, NV_CertifySyncShort(_, _, _, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<7>(trunks::Make_TPM2B_ATTEST("fake_quoted_data")),
SetArgPointee<8>(fake_signature), Return(TPM_RC_SUCCESS)));
std::string quoted_data;
std::string quote;
EXPECT_TRUE(tpm_utility_->CertifyNV(kFakeNvIndex, kFakeNvSize,
"fake_key_blob", &quoted_data, &quote));
EXPECT_EQ(quoted_data, "fake_quoted_data");
EXPECT_NE(quote.find("fake_quote"), std::string::npos);
}
TEST_F(TpmUtilityTest, CertifyNVWithEcc) {
constexpr int kFakeNvIndex = 0x123;
constexpr int kFakeNvSize = 0x456;
EXPECT_CALL(mock_tpm_utility_, GetKeyPublicArea(_, _))
.WillOnce(DoAll(SetArgPointee<1>(GetValidEccPublicKey(nullptr)),
Return(TPM_RC_SUCCESS)));
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_ECDSA;
fake_signature.signature.ecdsa.signature_r =
trunks::Make_TPM2B_ECC_PARAMETER("fake_quote_r");
fake_signature.signature.ecdsa.signature_s =
trunks::Make_TPM2B_ECC_PARAMETER("fake_quote_s");
EXPECT_CALL(mock_tpm_, NV_CertifySyncShort(_, _, _, _, _, _, _, _, _, _))
.WillOnce(
DoAll(SetArgPointee<7>(trunks::Make_TPM2B_ATTEST("fake_quoted_data")),
SetArgPointee<8>(fake_signature), Return(TPM_RC_SUCCESS)));
std::string quoted_data;
std::string quote;
EXPECT_TRUE(tpm_utility_->CertifyNV(kFakeNvIndex, kFakeNvSize,
"fake_key_blob", &quoted_data, &quote));
EXPECT_EQ(quoted_data, "fake_quoted_data");
EXPECT_NE(quote.find("fake_quote_r"), std::string::npos);
EXPECT_NE(quote.find("fake_quote_s"), std::string::npos);
}
TEST_F(TpmUtilityTest, CertifyNVFail) {
constexpr int kFakeNvIndex = 0x123;
constexpr int kFakeNvSize = 0x456;
trunks::TPMT_SIGNATURE fake_signature;
fake_signature.sig_alg = trunks::TPM_ALG_RSASSA;
fake_signature.signature.rsassa.sig =
trunks::Make_TPM2B_PUBLIC_KEY_RSA("fake_quote");
EXPECT_CALL(mock_tpm_, NV_CertifySyncShort(_, _, _, _, _, _, _, _, _, _))
.WillOnce(Return(TPM_RC_FAILURE));
std::string quoted_data;
std::string quote;
EXPECT_FALSE(tpm_utility_->CertifyNV(kFakeNvIndex, kFakeNvSize,
"fake_key_blob", &quoted_data, &quote));
EXPECT_EQ(quoted_data, "");
EXPECT_EQ(quote, "");
}
} // namespace attestation