1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project 3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License. 6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at 7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and 14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License. 15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 162be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/trunks_client_test.h" 182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <algorithm> 204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <map> 214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <memory> 224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <string> 234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include <vector> 244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <base/logging.h> 262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <base/stl_util.h> 27ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn#include <crypto/openssl_util.h> 282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <crypto/scoped_openssl_types.h> 29e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi#include <crypto/sha2.h> 302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <openssl/bn.h> 316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi#include <openssl/err.h> 322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include <openssl/rsa.h> 332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn#include "trunks/authorization_delegate.h" 352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/error_codes.h" 362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/hmac_session.h" 372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/policy_session.h" 382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/scoped_key_handle.h" 392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_generated.h" 402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_state.h" 412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/tpm_utility.h" 422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi#include "trunks/trunks_factory_impl.h" 432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 44ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahnnamespace { 45ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn 46ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahnstd::string GetOpenSSLError() { 47ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn BIO* bio = BIO_new(BIO_s_mem()); 48ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn ERR_print_errors(bio); 49ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn char* data = nullptr; 50ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn int data_len = BIO_get_mem_data(bio, &data); 51ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn std::string error_string(data, data_len); 52ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn BIO_free(bio); 53ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn return error_string; 54ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn} 55ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn 56ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn} // namespace 57ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn 582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghinamespace trunks { 592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 609caf492818a4cc51ba471534d3fcaa84c9ce0278Darren KrahnTrunksClientTest::TrunksClientTest() 619caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn : factory_(new TrunksFactoryImpl(true /* failure_is_fatal */)) { 62ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn crypto::EnsureOpenSSLInit(); 63ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn} 642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 652be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::TrunksClientTest(scoped_ptr<TrunksFactory> factory) 667e763a9434e12c7980529980de5f8eced22b310aAlex Vakulenko : factory_(std::move(factory)) {} 672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 682be346182387c502f65c65ea4da49707026ce8f9Utkarsh SanghiTrunksClientTest::~TrunksClientTest() {} 692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::RNGTest() { 712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 73a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 74a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 75a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 76a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string entropy_data("entropy_data"); 782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string random_data; 792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi size_t num_bytes = 70; 80a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->StirRandom(entropy_data, session->GetDelegate()); 812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error stirring TPM RNG: " << GetErrorString(result); 832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->GenerateRandom(num_bytes, session->GetDelegate(), 862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &random_data); 872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error getting random bytes from TPM: " 892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi << GetErrorString(result); 902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (num_bytes != random_data.size()) { 932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error not enough random bytes received."; 942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return true; 972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::SignTest() { 1002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 1012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 102a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 103a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 1042be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string key_authorization("sign"); 1076f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi std::string key_blob; 108a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->CreateRSAKeyPair( 109a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kSignKey, 2048, 0x10001, 110a5a2f2ea49e0085bf8d7f6f2b6e7cd624d710c01Utkarsh Sanghi key_authorization, "", false, // use_only_policy_authorization 1110ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr); 1122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error creating signing key: " << GetErrorString(result); 1142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1152be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1166f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi TPM_HANDLE signing_key; 1176f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi result = utility->LoadKey(key_blob, session->GetDelegate(), &signing_key); 1186f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1196f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi LOG(ERROR) << "Error loading signing key: " << GetErrorString(result); 1206f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi } 1212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), signing_key); 1224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn session->SetEntityAuthorizationValue(key_authorization); 1234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string signature; 1244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = utility->Sign(signing_key, TPM_ALG_NULL, TPM_ALG_NULL, 1254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string(32, 'a'), session->GetDelegate(), 1264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &signature); 1274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 1284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 1294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 1304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = utility->Verify(signing_key, TPM_ALG_NULL, TPM_ALG_NULL, 1324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string(32, 'a'), signature, nullptr); 1334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 1344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error using key to verify: " << GetErrorString(result); 1354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 1364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 1374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 1382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 1392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 1402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::DecryptTest() { 1412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 1422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 143a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 144a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 1452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string key_authorization("decrypt"); 1486f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi std::string key_blob; 149a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->CreateRSAKeyPair( 1506f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, 1516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi key_authorization, "", false, // use_only_policy_authorization 1520ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr); 1532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1546f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi LOG(ERROR) << "Error creating decrypt key: " << GetErrorString(result); 1552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1562be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1576f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi TPM_HANDLE decrypt_key; 1586f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi result = utility->LoadKey(key_blob, session->GetDelegate(), &decrypt_key); 1596f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1606f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi LOG(ERROR) << "Error loading decrypt key: " << GetErrorString(result); 1616f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi } 1622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), decrypt_key); 1632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), 1642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi key_authorization, 1652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session.get()); 1662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 1672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 1682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::ImportTest() { 1692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 1702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 171a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 172a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 1732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1754ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string modulus; 1764ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string prime_factor; 1774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn GenerateRSAKeyPair(&modulus, &prime_factor, nullptr); 1782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string key_blob; 1792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string key_authorization("import"); 180a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->ImportRSAKey( 1812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, modulus, 0x10001, 1822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi prime_factor, key_authorization, session->GetDelegate(), &key_blob); 1832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error importing key into TPM: " << GetErrorString(result); 1852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_HANDLE key_handle; 1882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 1892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 1902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error loading key into TPM: " << GetErrorString(result); 1912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 1922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 1932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), key_handle); 1942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization, 1952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session.get()); 1962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 1972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 1982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::AuthChangeTest() { 1992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 2002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 201a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 202a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 2032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 2042be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 2052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string key_authorization("new_pass"); 2066f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi std::string key_blob; 207a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->CreateRSAKeyPair( 2086f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, 2096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi "old_pass", "", false, // use_only_policy_authorization 2100ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi kNoCreationPCR, session->GetDelegate(), &key_blob, nullptr); 2112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 2126f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi LOG(ERROR) << "Error creating change auth key: " << GetErrorString(result); 2132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 2142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 2156f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi TPM_HANDLE key_handle; 2166f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 2176f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 2186f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi LOG(ERROR) << "Error loading change auth key: " << GetErrorString(result); 2196f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi } 2202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), key_handle); 2212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue("old_pass"); 2222be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->ChangeKeyAuthorizationData(key_handle, key_authorization, 2232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->GetDelegate(), 2242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &key_blob); 2252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 2262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error changing auth data: " << GetErrorString(result); 2272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 2282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 2292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(""); 2302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 2312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 2322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error reloading key: " << GetErrorString(result); 2332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 2342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 2352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_key.reset(key_handle); 2362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return PerformRSAEncrpytAndDecrpyt(scoped_key.get(), key_authorization, 2372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session.get()); 2382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 2392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 240fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghibool TrunksClientTest::VerifyKeyCreationTest() { 241fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 242fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 243a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 244a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 245fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 246fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 247fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi std::string key_blob; 248fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi std::string creation_blob; 249fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi session->SetEntityAuthorizationValue(""); 250a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->CreateRSAKeyPair( 251fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, 252fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi "", "", false, // use_only_policy_authorization 253fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi kNoCreationPCR, session->GetDelegate(), &key_blob, &creation_blob); 254fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 255fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi LOG(ERROR) << "Error creating certify key: " << GetErrorString(result); 256fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 257fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 258fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi std::string alternate_key_blob; 259fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi result = utility->CreateRSAKeyPair( 260fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptKey, 2048, 0x10001, 261fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi "", "", false, // use_only_policy_authorization 262fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi kNoCreationPCR, session->GetDelegate(), &alternate_key_blob, 263fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi nullptr); 264fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 265fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi LOG(ERROR) << "Error creating alternate key: " << GetErrorString(result); 266fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 267fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 268fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPM_HANDLE key_handle; 269fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi result = utility->LoadKey(key_blob, session->GetDelegate(), &key_handle); 270fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 271fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi LOG(ERROR) << "Error loading certify key: " << GetErrorString(result); 272fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 273fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 274fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi TPM_HANDLE alternate_key_handle; 275fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi result = utility->LoadKey(alternate_key_blob, 276fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi session->GetDelegate(), 277fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi &alternate_key_handle); 278fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 279fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi LOG(ERROR) << "Error loading alternate key: " << GetErrorString(result); 280fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 281fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 282fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi ScopedKeyHandle certify_key(*factory_.get(), key_handle); 283fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi ScopedKeyHandle alternate_key(*factory_.get(), alternate_key_handle); 284fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi result = utility->CertifyCreation(certify_key.get(), creation_blob); 285fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 286fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi LOG(ERROR) << "Error certifying key: " << GetErrorString(result); 287fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 288fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 289fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi result = utility->CertifyCreation(alternate_key.get(), creation_blob); 290fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi if (result == TPM_RC_SUCCESS) { 291fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi LOG(ERROR) << "Error alternate key certified with wrong creation data."; 292fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return false; 293fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi } 294fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi return true; 295fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi} 296fded77411da5ef66dff7389e49f40900c19d510cUtkarsh Sanghi 297a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghibool TrunksClientTest::SealedDataTest() { 2986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 2996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 300a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 301a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 302a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 303a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 304a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi int pcr_index = 5; 305a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string policy_digest; 306a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->GetPolicyDigestForPcrValue(pcr_index, "", 307a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi &policy_digest); 308a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 309a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error getting policy_digest: " << GetErrorString(result); 310a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 311a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 312a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string data_to_seal("seal_data"); 313a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string sealed_data; 314a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = utility->SealData(data_to_seal, policy_digest, 315a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi session->GetDelegate(), &sealed_data); 316a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 317a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error creating Sealed Object: " << GetErrorString(result); 318a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 319a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 320a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession(); 321a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = policy_session->StartUnboundSession(false); 3226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 323a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 324a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 325a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 326a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = policy_session->PolicyPCR(pcr_index, ""); 327a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 328a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error restricting policy to pcr value: " 329a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 330a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 331a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 332a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi std::string unsealed_data; 333a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = utility->UnsealData(sealed_data, policy_session->GetDelegate(), 334a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi &unsealed_data); 335a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 336a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error unsealing object: " << GetErrorString(result); 337a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 338a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 339a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (data_to_seal != unsealed_data) { 340a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error unsealed data from TPM does not match original data."; 341a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 342a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 343a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = utility->ExtendPCR(pcr_index, "extend", session->GetDelegate()); 344a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 345a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error extending pcr: " << GetErrorString(result); 346a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 347a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 348a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = policy_session->PolicyPCR(pcr_index, ""); 349a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 350a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error restricting policy to pcr value: " 351a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi << GetErrorString(result); 352a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 353a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 354a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi result = utility->UnsealData(sealed_data, policy_session->GetDelegate(), 355a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi &unsealed_data); 356a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (result == TPM_RC_SUCCESS) { 357a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error object was unsealed with wrong policy_digest."; 358a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return false; 359a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi } 360a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi return true; 361a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi} 362a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi 363a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghibool TrunksClientTest::PCRTest() { 364a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 365a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 366a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi if (utility->StartSession(session.get()) != TPM_RC_SUCCESS) { 367a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session."; 3686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 3696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 3706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // We are using PCR 2 because it is currently not used by ChromeOS. 3716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi uint32_t pcr_index = 2; 3726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string extend_data("data"); 3736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string old_data; 374a6e332ee7f5fe52c1291d961dbeda975c8272044Utkarsh Sanghi TPM_RC result = utility->ReadPCR(pcr_index, &old_data); 3756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 3766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result); 3776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 3786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 3796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->ExtendPCR(pcr_index, extend_data, session->GetDelegate()); 3806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 3816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error extending PCR value: " << GetErrorString(result); 3826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 3836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 3846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string pcr_data; 3856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->ReadPCR(pcr_index, &pcr_data); 3866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 3876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error reading from PCR: " << GetErrorString(result); 3886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 3896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 3906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string hashed_extend_data = crypto::SHA256HashString(extend_data); 3916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string expected_pcr_data = 3926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi crypto::SHA256HashString(old_data + hashed_extend_data); 3936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (pcr_data.compare(expected_pcr_data) != 0) { 3946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "PCR data does not match expected value."; 3956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 3966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 3976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return true; 3986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi} 3992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 4006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyAuthValueTest() { 4012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 4026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession(); 4032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_RC result; 4046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->StartUnboundSession(true); 4052be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4062be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 4072be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4082be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->PolicyAuthValue(); 4102be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4112be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error restricting policy to auth value knowledge: " 4122be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi << GetErrorString(result); 4132be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4142be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string policy_digest; 4166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->GetDigest(&policy_digest); 4172be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 4192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Now that we have the digest, we can close the trial session and use hmac. 4226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi trial_session.reset(); 4232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 4242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession(); 4256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = hmac_session->StartUnboundSession(true); 4262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 4282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 4312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string key_blob; 4322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->CreateRSAKeyPair( 4336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, 4346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi "password", policy_digest, true, // use_only_policy_authorization 4350ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr); 4362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result); 4382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 4412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_HANDLE key_handle; 4422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle); 4432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result); 4452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4472be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), key_handle); 4482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 4492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi // Now we can reset the hmac_session. 4502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi hmac_session.reset(); 4512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 4526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession(); 4536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->StartUnboundSession(false); 4542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 4562be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = policy_session->PolicyAuthValue(); 4592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error restricting policy to auth value knowledge: " 4612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi << GetErrorString(result); 4622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string signature; 4652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi policy_session->SetEntityAuthorizationValue("password"); 4662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 4672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string(32, 0), policy_session->GetDelegate(), 4682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &signature); 4692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error signing using RSA key: " << GetErrorString(result); 4712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 4746f68562edf5f66006c08de24d558732d6a389631Utkarsh Sanghi std::string(32, 0), signature, nullptr); 4752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error verifying using RSA key: " << GetErrorString(result); 4772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string ciphertext; 4802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->AsymmetricEncrypt(scoped_key.get(), TPM_ALG_NULL, 4812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_ALG_NULL, "plaintext", 4826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi nullptr, 4832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &ciphertext); 4842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result); 4862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4882be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = policy_session->PolicyAuthValue(); 4892be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 4902be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error restricting policy to auth value knowledge: " 4912be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi << GetErrorString(result); 4922be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 4932be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 4942be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string plaintext; 4952be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi policy_session->SetEntityAuthorizationValue("password"); 4962be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->AsymmetricDecrypt(scoped_key.get(), TPM_ALG_NULL, 4972be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_ALG_NULL, ciphertext, 4982be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi policy_session->GetDelegate(), 4992be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &plaintext); 5002be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5012be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error encrypting using RSA key: " << GetErrorString(result); 5022be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 5032be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 504e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (plaintext.compare("plaintext") != 0) { 505e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi LOG(ERROR) << "Plaintext changed after encrypt + decrypt."; 506e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return false; 507e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 508e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return true; 509e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi} 510e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi 5116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyAndTest() { 512e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 5136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession(); 5146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TPM_RC result; 5156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->StartUnboundSession(true); 516e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 5186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->PolicyCommandCode(TPM_CC_Sign); 5216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 523e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return false; 524e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 525e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi uint32_t pcr_index = 2; 5266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string pcr_value; 5276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->ReadPCR(pcr_index, &pcr_value); 528e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error reading pcr: " << GetErrorString(result); 530e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return false; 531e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 5326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string pcr_extend_data("extend"); 5336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string next_pcr_value; 5346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string hashed_extend_data = crypto::SHA256HashString(pcr_extend_data); 5356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi next_pcr_value = crypto::SHA256HashString(pcr_value + hashed_extend_data); 5366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 5376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->PolicyPCR(pcr_index, next_pcr_value); 538e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 540e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return false; 541e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 5426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string policy_digest; 5436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->GetDigest(&policy_digest); 544e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 546e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return false; 547e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 5486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Now that we have the digest, we can close the trial session and use hmac. 5496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi trial_session.reset(); 5506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 5516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession(); 5526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = hmac_session->StartUnboundSession(true); 5536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 5556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string key_authorization("password"); 5586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string key_blob; 5596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // This key is created with a policy that dictates it can only be used 5606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // when pcr 2 remains unchanged, and when the command is TPM2_Sign. 5616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->CreateRSAKeyPair( 5626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, 5636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi key_authorization, policy_digest, true, // use_only_policy_authorization 5640ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr); 5656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result); 5676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TPM_HANDLE key_handle; 5706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle); 5716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result); 5736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), key_handle); 5766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 5776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Now we can reset the hmac_session. 5786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi hmac_session.reset(); 5796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 5806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession(); 5816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->StartUnboundSession(false); 5826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 5846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyCommandCode(TPM_CC_Sign); 5876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 5896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyPCR(pcr_index, ""); 5926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 5936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 5946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 5956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 5966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string signature; 5976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi policy_session->SetEntityAuthorizationValue(key_authorization); 5986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Signing with this key when pcr 2 is unchanged fails. 5996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 6006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string(32, 'a'), policy_session->GetDelegate(), 6016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi &signature); 6026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (GetFormatOneError(result) != TPM_RC_POLICY_FAIL) { 6036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 6046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<AuthorizationDelegate> delegate = 6076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi factory_->GetPasswordAuthorization(""); 6086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->ExtendPCR(pcr_index, pcr_extend_data, delegate.get()); 6096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error extending pcr: " << GetErrorString(result); 6116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // we have to restart the session because we changed the pcr values. 6146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->StartUnboundSession(false); 6156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 6176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyCommandCode(TPM_CC_Sign); 6206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 6226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyPCR(pcr_index, ""); 6256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 6276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi policy_session->SetEntityAuthorizationValue(key_authorization); 6306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Signing with this key when pcr 2 is changed succeeds. 6316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 6326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string(32, 'a'), policy_session->GetDelegate(), 6336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi &signature); 6346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 6366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->Verify(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 6396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string(32, 'a'), signature, nullptr); 6406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to verify: " << GetErrorString(result); 6426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6446ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string ciphertext; 6456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 6466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi "plaintext", nullptr, &ciphertext); 6476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result); 6496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyCommandCode(TPM_CC_Sign); 6526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 6546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyPCR(pcr_index, ""); 6576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 6596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string plaintext; 6626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi policy_session->SetEntityAuthorizationValue(key_authorization); 6636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // This call is not authorized with the policy, because its command code 6646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // is not TPM_CC_SIGN. It should fail with TPM_RC_POLICY_CC. 6656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 6666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi ciphertext, policy_session->GetDelegate(), 6676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi &plaintext); 6686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (GetFormatOneError(result) != TPM_RC_POLICY_CC) { 6696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error: " << GetErrorString(result); 6706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return true; 6736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi} 6746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 6756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghibool TrunksClientTest::PolicyOrTest() { 6766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 6776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<PolicySession> trial_session = factory_->GetTrialSession(); 6786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TPM_RC result; 6796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Specify a policy that asserts either TPM_CC_RSA_Encrypt or 6806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // TPM_CC_RSA_Decrypt. A key created under this policy can only be used 6816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // to encrypt or decrypt. 6826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->StartUnboundSession(true); 6836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 6856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->PolicyCommandCode(TPM_CC_Sign); 6886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 6906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string sign_digest; 6936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->GetDigest(&sign_digest); 6946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 6956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 6966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 6976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 6986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->StartUnboundSession(true); 6996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 7016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->PolicyCommandCode(TPM_CC_RSA_Decrypt); 7046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 7066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string decrypt_digest; 7096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->GetDigest(&decrypt_digest); 7106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 7126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::vector<std::string> digests; 7156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi digests.push_back(sign_digest); 7166ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi digests.push_back(decrypt_digest); 7176ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->PolicyOR(digests); 7186ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7196ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 7206ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7216ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7226ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string policy_digest; 7236ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = trial_session->GetDigest(&policy_digest); 7246ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7256ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result); 7266ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7276ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7286ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Now that we have the digest, we can close the trial session and use hmac. 7296ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi trial_session.reset(); 7306ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 7316ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<HmacSession> hmac_session = factory_->GetHmacSession(); 7326ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = hmac_session->StartUnboundSession(true); 7336ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7346ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 7356ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7366ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7376ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string key_authorization("password"); 7386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string key_blob; 7396ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // This key is created with a policy that specifies that it can only be used 7406ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // for encrypt and decrypt operations. 7416ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->CreateRSAKeyPair( 7426ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TpmUtility::AsymmetricKeyUsage::kDecryptAndSignKey, 2048, 0x10001, 7436ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi key_authorization, policy_digest, true, // use_only_policy_authorization 7440ebbc58fe6d45378a5b502c33eb1c4289fd8b05bUtkarsh Sanghi kNoCreationPCR, hmac_session->GetDelegate(), &key_blob, nullptr); 7456ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7466ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result); 7476ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7486ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7496ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi TPM_HANDLE key_handle; 7506ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->LoadKey(key_blob, hmac_session->GetDelegate(), &key_handle); 7516ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7526ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error loading RSA key: " << GetErrorString(result); 7536ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7546ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7556ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi ScopedKeyHandle scoped_key(*factory_.get(), key_handle); 7566ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 7576ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // Now we can reset the hmac_session. 7586ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi hmac_session.reset(); 7596ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 7606ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<PolicySession> policy_session = factory_->GetPolicySession(); 7616ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->StartUnboundSession(false); 7626ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7636ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error starting policy session: " << GetErrorString(result); 7646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7656ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7666ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string ciphertext; 7676ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 7686ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi "plaintext", nullptr, &ciphertext); 7696ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7706ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result); 7716ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyCommandCode(TPM_CC_RSA_Decrypt); 7746ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 7766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7776ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7786ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyOR(digests); 7796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 7816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string plaintext; 7846ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi policy_session->SetEntityAuthorizationValue(key_authorization); 7856ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // We can freely use the key for decryption. 7866ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, TPM_ALG_NULL, 7876ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi ciphertext, policy_session->GetDelegate(), 7886ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi &plaintext); 7896ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7906ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result); 7916ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7926ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7936ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (plaintext.compare("plaintext") != 0) { 7946ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Plaintext changed after encrypt + decrypt."; 7956ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 7966ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 7976ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyCommandCode(TPM_CC_Sign); 7986ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 7996ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 8006ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 8016ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 8026ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = policy_session->PolicyOR(digests); 8036ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8046ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error restricting policy: " << GetErrorString(result); 8056ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 8066ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 8076ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string signature; 8086ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi policy_session->SetEntityAuthorizationValue(key_authorization); 8096ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // However signing with a key only authorized for encrypt/decrypt should 8106ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi // fail with TPM_RC_POLICY_CC. 8116ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi result = utility->Sign(scoped_key.get(), TPM_ALG_NULL, TPM_ALG_NULL, 8126ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string(32, 'a'), policy_session->GetDelegate(), 8136ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi &signature); 8146ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8156ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi LOG(ERROR) << "Error using key to sign: " << GetErrorString(result); 816e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi return false; 817e7eb2bf306af6e8408cd77125861542d19e5ec6dUtkarsh Sanghi } 8182be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return true; 8192be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 8202be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 8212be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::NvramTest(const std::string& owner_password) { 8222be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 8232be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<HmacSession> session = factory_->GetHmacSession(); 8242be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_RC result = session->StartUnboundSession(true /* enable encryption */); 8252be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8262be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error starting hmac session: " << GetErrorString(result); 8272be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8282be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8292be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi uint32_t index = 1; 8302be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(owner_password); 8312be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string nv_data("nv_data"); 8322be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->DefineNVSpace(index, nv_data.size(), 8332be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->GetDelegate()); 8342be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8352be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error defining nvram: " << GetErrorString(result); 8362be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8372be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8382be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(owner_password); 8392be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate()); 8402be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8412be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error writing nvram: " << GetErrorString(result); 8422be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8432be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8442be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string new_nvdata; 8452be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(""); 8462be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->ReadNVSpace(index, 0, nv_data.size(), 847707e3e1ac5185eac0c992fb6fbcae574fde9c4bbUtkarsh Sanghi &new_nvdata, session->GetDelegate()); 8482be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8492be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error reading nvram: " << GetErrorString(result); 8502be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8512be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8522be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (nv_data.compare(new_nvdata) != 0) { 8532be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "NV space had different data than was written."; 8542be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8552be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 85638e6ef38e5ee4c7f735366a26111e97a7759f26eUtkarsh Sanghi session->SetEntityAuthorizationValue(owner_password); 8572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->LockNVSpace(index, session->GetDelegate()); 8582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error locking nvram: " << GetErrorString(result); 8602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 86238e6ef38e5ee4c7f735366a26111e97a7759f26eUtkarsh Sanghi session->SetEntityAuthorizationValue(""); 8632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->ReadNVSpace(index, 0, nv_data.size(), 8642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &new_nvdata, session->GetDelegate()); 8652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error reading nvram: " << GetErrorString(result); 8672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (nv_data.compare(new_nvdata) != 0) { 8702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "NV space had different data than was written."; 8712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(owner_password); 8742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->WriteNVSpace(index, 0, nv_data, session->GetDelegate()); 8752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result == TPM_RC_SUCCESS) { 8762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Wrote nvram after locking: " << GetErrorString(result); 8772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(owner_password); 8802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->DestroyNVSpace(index, session->GetDelegate()); 8812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 8822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error destroying nvram: " << GetErrorString(result); 8832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 8842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 8852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return true; 8862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 8872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 8884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::ManyKeysTest() { 8894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const size_t kNumKeys = 20; 8904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<std::unique_ptr<ScopedKeyHandle>> key_handles; 8914ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::map<TPM_HANDLE, std::string> public_key_map; 8924ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < kNumKeys; ++i) { 8934ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::unique_ptr<ScopedKeyHandle> key_handle(new ScopedKeyHandle(*factory_)); 8944ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string public_key; 8954ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!LoadSigningKey(key_handle.get(), &public_key)) { 8964ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error loading key " << i << " into TPM."; 8974ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 8984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn public_key_map[key_handle->get()] = public_key; 8994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn key_handles.push_back(std::move(key_handle)); 9004ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_EQ(key_handles.size(), kNumKeys); 9024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_EQ(public_key_map.size(), kNumKeys); 9034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn scoped_ptr<AuthorizationDelegate> delegate = 9044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn factory_->GetPasswordAuthorization(""); 9054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < kNumKeys; ++i) { 9064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const ScopedKeyHandle& key_handle = *key_handles[i]; 9074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& public_key = public_key_map[key_handle.get()]; 9084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!SignAndVerify(key_handle, public_key, delegate.get())) { 9094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error signing with key " << i; 9104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::random_shuffle(key_handles.begin(), key_handles.end()); 9134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < kNumKeys; ++i) { 9144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const ScopedKeyHandle& key_handle = *key_handles[i]; 9154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& public_key = public_key_map[key_handle.get()]; 9164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!SignAndVerify(key_handle, public_key, delegate.get())) { 9174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error signing with shuffled key " << i; 9184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 9214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 9224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 9234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::ManySessionsTest() { 9244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const size_t kNumSessions = 20; 9254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 9264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::vector<std::unique_ptr<HmacSession>> sessions; 9274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < kNumSessions; ++i) { 9284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::unique_ptr<HmacSession> session(factory_->GetHmacSession().release()); 9294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = session->StartUnboundSession(true /* enable encryption */); 9304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 9314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error starting hmac session " << i << ": " 9324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn << GetErrorString(result); 9334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 9344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn sessions.push_back(std::move(session)); 9364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_EQ(sessions.size(), kNumSessions); 9384ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn ScopedKeyHandle key_handle(*factory_); 9394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string public_key; 9404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!LoadSigningKey(&key_handle, &public_key)) { 9414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 9424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < kNumSessions; ++i) { 9444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) { 9454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error signing with hmac session " << i; 9464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::random_shuffle(sessions.begin(), sessions.end()); 9494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn for (size_t i = 0; i < kNumSessions; ++i) { 9504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!SignAndVerify(key_handle, public_key, sessions[i]->GetDelegate())) { 9514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Error signing with shuffled hmac session " << i; 9524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 9544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 9554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 9564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 9572be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghibool TrunksClientTest::PerformRSAEncrpytAndDecrpyt( 9582be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_HANDLE key_handle, 9592be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi const std::string& key_authorization, 9602be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi HmacSession* session) { 9612be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 9622be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string ciphertext; 9632be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(""); 9642be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_RC result = utility->AsymmetricEncrypt(key_handle, TPM_ALG_NULL, 9652be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_ALG_NULL, "plaintext", 9662be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->GetDelegate(), 9672be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi &ciphertext); 9682be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 9692be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error using key to encrypt: " << GetErrorString(result); 9702be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 9712be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 9722be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi std::string plaintext; 9732be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->SetEntityAuthorizationValue(key_authorization); 9742be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi result = utility->AsymmetricDecrypt(key_handle, TPM_ALG_NULL, 9752be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi TPM_ALG_NULL, ciphertext, 9762be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi session->GetDelegate(), &plaintext); 9772be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 9782be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Error using key to decrypt: " << GetErrorString(result); 9792be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 9802be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 9812be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi if (plaintext.compare("plaintext") != 0) { 9822be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi LOG(ERROR) << "Plaintext changed after encrypt + decrypt."; 9832be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return false; 9842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi } 9852be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi return true; 9862be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} 9872be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi 9884ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnvoid TrunksClientTest::GenerateRSAKeyPair(std::string* modulus, 9894ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string* prime_factor, 9904ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string* public_key) { 9919caf492818a4cc51ba471534d3fcaa84c9ce0278Darren Krahn#if defined(OPENSSL_IS_BORINGSSL) 992ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn crypto::ScopedRSA rsa(RSA_new()); 993ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn crypto::ScopedBIGNUM exponent(BN_new()); 994ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn CHECK(BN_set_word(exponent.get(), RSA_F4)); 995ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn CHECK(RSA_generate_key_ex(rsa.get(), 2048, exponent.get(), nullptr)) 996ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn << "Failed to generate RSA key: " << GetOpenSSLError(); 997ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn#else 9984ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn crypto::ScopedRSA rsa(RSA_generate_key(2048, 0x10001, nullptr, nullptr)); 9994ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK(rsa.get()); 1000ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn#endif 10014ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn modulus->resize(BN_num_bytes(rsa.get()->n), 0); 10024ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn BN_bn2bin(rsa.get()->n, 10034ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn reinterpret_cast<unsigned char*>(string_as_array(modulus))); 10044ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn prime_factor->resize(BN_num_bytes(rsa.get()->p), 0); 10054ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn BN_bn2bin(rsa.get()->p, 10064ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn reinterpret_cast<unsigned char*>(string_as_array(prime_factor))); 10074ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (public_key) { 10084ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn unsigned char* buffer = NULL; 10094ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn int length = i2d_RSAPublicKey(rsa.get(), &buffer); 10104ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK_GT(length, 0); 10114ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn crypto::ScopedOpenSSLBytes scoped_buffer(buffer); 10124ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn public_key->assign(reinterpret_cast<char*>(buffer), length); 10134ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 10144ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 10154ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 10164ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::VerifyRSASignature(const std::string& public_key, 10174ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& data, 10184ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& signature) { 10194ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto asn1_ptr = reinterpret_cast<const unsigned char*>(public_key.data()); 10204ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn crypto::ScopedRSA rsa(d2i_RSAPublicKey(nullptr, &asn1_ptr, 10214ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn public_key.size())); 10224ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn CHECK(rsa.get()); 10234ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string digest = crypto::SHA256HashString(data); 10244ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn auto digest_buffer = reinterpret_cast<const unsigned char*>(digest.data()); 10254ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string mutable_signature(signature); 10264ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn unsigned char* signature_buffer = 10274ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn reinterpret_cast<unsigned char*>(string_as_array(&mutable_signature)); 10284ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return (RSA_verify(NID_sha256, digest_buffer, digest.size(), 10294ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn signature_buffer, signature.size(), rsa.get()) == 1); 10304ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 10314ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 10324ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::LoadSigningKey(ScopedKeyHandle* key_handle, 10334ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string* public_key) { 10344ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string modulus; 10354ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string prime_factor; 10364ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn GenerateRSAKeyPair(&modulus, &prime_factor, public_key); 10374ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string key_blob; 10386ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 10394ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = utility->ImportRSAKey( 10404ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TpmUtility::AsymmetricKeyUsage::kSignKey, 10414ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn modulus, 0x10001, prime_factor, 10424ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn "", // password 10434ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn factory_->GetPasswordAuthorization("").get(), 10444ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &key_blob); 10454ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 10464ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "ImportRSAKey: " << GetErrorString(result); 10474ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 10484ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 10494ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_HANDLE raw_key_handle; 10504ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn result = utility->LoadKey(key_blob, 10514ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn factory_->GetPasswordAuthorization("").get(), 10524ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn &raw_key_handle); 10534ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (result != TPM_RC_SUCCESS) { 10544ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "LoadKey: " << GetErrorString(result); 10554ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return false; 10564ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn } 10574ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn key_handle->reset(raw_key_handle); 10584ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn return true; 10594ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn} 10604ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn 10614ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahnbool TrunksClientTest::SignAndVerify(const ScopedKeyHandle& key_handle, 10624ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn const std::string& public_key, 10634ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn AuthorizationDelegate* delegate) { 10646ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi std::string signature; 10654ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn std::string data_to_sign("sign_this"); 10664ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn scoped_ptr<TpmUtility> utility = factory_->GetTpmUtility(); 10674ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_RC result = utility->Sign(key_handle.get(), 10684ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_ALG_RSASSA, 10694ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn TPM_ALG_SHA256, 10704ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn data_to_sign, 10714ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn delegate, 10726ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi &signature); 10736ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi if (result != TPM_RC_SUCCESS) { 10744ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn LOG(ERROR) << "Sign: " << GetErrorString(result); 10756ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 10766ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 10774ede7fcc1571b23867536b2506900fc3987c2dd5Darren Krahn if (!VerifyRSASignature(public_key, data_to_sign, signature)) { 1078ee93b5e81e62fdc0053c74ad565957354e540a99Darren Krahn LOG(ERROR) << "Signature verification failed: " << GetOpenSSLError(); 10796ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return false; 10806ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi } 10816ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi return true; 10826ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi} 10836ea135676cf391fac45b0051242ccac935c8bc62Utkarsh Sanghi 10842be346182387c502f65c65ea4da49707026ce8f9Utkarsh Sanghi} // namespace trunks 1085