1259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// 2259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// Copyright (C) 2015 The Android Open Source Project 3259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// 4259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 5259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// you may not use this file except in compliance with the License. 6259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// You may obtain a copy of the License at 7259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// 8259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 9259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// 10259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 11259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 12259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// See the License for the specific language governing permissions and 14259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// limitations under the License. 15259fa1be39c0a35ec374fe127ba49d1c5ed5eb18Utkarsh Sanghi// 16565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 17565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi#include "tpm_manager/server/tpm_connection.h" 18565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 19565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi#include <base/logging.h> 2050e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi#include <base/stl_util.h> 21565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi#include <base/threading/platform_thread.h> 22565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi#include <base/time/time.h> 23565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi#include <trousers/tss.h> 24565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi#include <trousers/trousers.h> // NOLINT(build/include_alpha) 25565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 2650e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi#include "tpm_manager/server/tpm_util.h" 2750e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi 28565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghinamespace { 29565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 30565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghiconst int kTpmConnectRetries = 10; 31565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghiconst int kTpmConnectIntervalMs = 100; 32565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 33565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi} // namespace 34565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 35565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghinamespace tpm_manager { 36565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 37a94133441da308b30c6fe18cc4e2b866498ee401Darren KrahnTpmConnection::TpmConnection(const std::string& authorization_value) 38a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn : authorization_value_(authorization_value) {} 39a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn 4050e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh SanghiTSS_HCONTEXT TpmConnection::GetContext() { 4150e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi if (!ConnectContextIfNeeded()) { 4250e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi return 0; 4350e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi } 4450e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi return context_.value(); 4550e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi} 46565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 47565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh SanghiTSS_HTPM TpmConnection::GetTpm() { 48565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi if (!ConnectContextIfNeeded()) { 49565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi return 0; 50565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 51565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TSS_RESULT result; 52565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TSS_HTPM tpm_handle; 534dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (TPM_ERROR(result = 544dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn Tspi_Context_GetTpmObject(context_.value(), &tpm_handle))) { 55565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TPM_LOG(ERROR, result) << "Error getting a handle to the TPM."; 56565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi return 0; 57565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 58565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi return tpm_handle; 59565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi} 60565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 61565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghibool TpmConnection::ConnectContextIfNeeded() { 62565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi if (context_.value() != 0) { 63565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi return true; 64565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 65565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TSS_RESULT result; 66565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi if (TPM_ERROR(result = Tspi_Context_Create(context_.ptr()))) { 67565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TPM_LOG(ERROR, result) << "Error connecting to TPM."; 68565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi return false; 69565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 70565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi // We retry on failure. It might be that tcsd is starting up. 71565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi for (int i = 0; i < kTpmConnectRetries; i++) { 72565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi if (TPM_ERROR(result = Tspi_Context_Connect(context_, nullptr))) { 73565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi if (ERROR_CODE(result) == TSS_E_COMM_FAILURE) { 74565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi base::PlatformThread::Sleep( 75565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi base::TimeDelta::FromMilliseconds(kTpmConnectIntervalMs)); 76565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } else { 77565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TPM_LOG(ERROR, result) << "Error connecting to TPM."; 78565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi return false; 79565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 80565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } else { 81565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi break; 82565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 83565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi } 84a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn if (context_.value() == 0) { 85a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn LOG(ERROR) << "Unexpected NULL context."; 86a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn return false; 87a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn } 88a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn // If we don't need to set an authorization value, we're done. 89a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn if (authorization_value_.empty()) { 90a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn return true; 91a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn } 92a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn 93a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn TSS_HTPM tpm_handle; 94a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn if (TPM_ERROR(result = 95a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn Tspi_Context_GetTpmObject(context_.value(), &tpm_handle))) { 96a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn TPM_LOG(ERROR, result) << "Error getting a handle to the TPM."; 97a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn context_.reset(); 98a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn return false; 99a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn } 100a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn TSS_HPOLICY tpm_usage_policy; 101a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn if (TPM_ERROR(result = Tspi_GetPolicyObject(tpm_handle, TSS_POLICY_USAGE, 102a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn &tpm_usage_policy))) { 103a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn TPM_LOG(ERROR, result) << "Error calling Tspi_GetPolicyObject"; 104a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn context_.reset(); 105a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn return false; 106a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn } 107a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn if (TPM_ERROR(result = Tspi_Policy_SetSecret( 108a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn tpm_usage_policy, TSS_SECRET_MODE_PLAIN, 109a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn authorization_value_.size(), 110a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn reinterpret_cast<BYTE*>( 111a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn const_cast<char*>(authorization_value_.data()))))) { 112a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn TPM_LOG(ERROR, result) << "Error calling Tspi_Policy_SetSecret"; 113a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn context_.reset(); 114a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn return false; 115a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn } 116a94133441da308b30c6fe18cc4e2b866498ee401Darren Krahn return true; 117565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi} 118565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi 119565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi} // namespace tpm_manager 120