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// 16c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 17c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi#include "tpm_manager/server/tpm_status_impl.h" 18c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 19c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi#include <vector> 20c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 2150e52ff6bcc478118a1cdec27903a5af5061d77bUtkarsh Sanghi#include <base/logging.h> 22c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi#include <trousers/tss.h> 23c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi#include <trousers/trousers.h> // NOLINT(build/include_alpha) 24c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 25c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghinamespace tpm_manager { 26c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 27c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi// Minimum size of TPM_DA_INFO struct. 28c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghiconst size_t kMinimumDaInfoSize = 21; 29c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 30c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghibool TpmStatusImpl::IsTpmEnabled() { 31c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (!is_enable_initialized_) { 32c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi RefreshOwnedEnabledInfo(); 33c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 34c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return is_enabled_; 35c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi} 36c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 37c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghibool TpmStatusImpl::IsTpmOwned() { 38c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (!is_owned_) { 39c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi RefreshOwnedEnabledInfo(); 40c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 41c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return is_owned_; 42c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi} 43c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 44c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghibool TpmStatusImpl::GetDictionaryAttackInfo(int* counter, 45c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi int* threshold, 46c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi bool* lockout, 47c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi int* seconds_remaining) { 48c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi std::string capability_data; 494dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (!GetCapability(TSS_TPMCAP_DA_LOGIC, TPM_ET_KEYHANDLE, &capability_data, 504dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn nullptr) || 51c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi capability_data.size() < kMinimumDaInfoSize) { 52c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi LOG(ERROR) << "Error getting tpm capability data."; 53c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return false; 54c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 55c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (static_cast<uint16_t>(capability_data[1]) == TPM_TAG_DA_INFO) { 56c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi TPM_DA_INFO da_info; 57c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi uint64_t offset = 0; 58c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi std::vector<BYTE> bytes(capability_data.begin(), capability_data.end()); 59c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi Trspi_UnloadBlob_DA_INFO(&offset, bytes.data(), &da_info); 604dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (counter) { 614dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn *counter = da_info.currentCount; 624dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn } 634dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (threshold) { 644dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn *threshold = da_info.thresholdCount; 654dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn } 664dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (lockout) { 674dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn *lockout = (da_info.state == TPM_DA_STATE_ACTIVE); 684dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn } 694dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn if (seconds_remaining) { 704dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn *seconds_remaining = da_info.actionDependValue; 714dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn } 72c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 73c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return true; 74c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi} 75c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 76c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghivoid TpmStatusImpl::RefreshOwnedEnabledInfo() { 77c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi TSS_RESULT result; 78c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi std::string capability_data; 79c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (!GetCapability(TSS_TPMCAP_PROPERTY, TSS_TPMCAP_PROP_OWNER, 80c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi &capability_data, &result)) { 81c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (ERROR_CODE(result) == TPM_E_DISABLED) { 82c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi is_enable_initialized_ = true; 83c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi is_enabled_ = false; 84c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 85c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } else { 86c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi is_enable_initialized_ = true; 87c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi is_enabled_ = true; 88c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi // |capability_data| should be populated with a TSS_BOOL which is true iff 89c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi // the Tpm is owned. 90c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (capability_data.size() != sizeof(TSS_BOOL)) { 91c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi LOG(ERROR) << "Error refreshing Tpm ownership information."; 92c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return; 93c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 94c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi is_owned_ = (capability_data[0] != 0); 95c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 96c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi} 97c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 98c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghibool TpmStatusImpl::GetCapability(uint32_t capability, 99c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi uint32_t sub_capability, 100c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi std::string* data, 101c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi TSS_RESULT* tpm_result) { 102c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi CHECK(data); 103565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi TSS_HTPM tpm_handle = tpm_connection_.GetTpm(); 104c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (tpm_handle == 0) { 105c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return false; 106c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 107c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi uint32_t length = 0; 108565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi trousers::ScopedTssMemory buf(tpm_connection_.GetContext()); 109c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi TSS_RESULT result = Tspi_TPM_GetCapability( 110c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi tpm_handle, capability, sizeof(uint32_t), 1114dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn reinterpret_cast<BYTE*>(&sub_capability), &length, buf.ptr()); 112c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (tpm_result) { 113c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi *tpm_result = result; 114c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 115c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi if (TPM_ERROR(result)) { 116565f88fe8ebdabefe07e5d5cb65ae9bcab509368Utkarsh Sanghi LOG(ERROR) << "Error getting TPM capability data."; 117c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return false; 118c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi } 119c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi data->assign(buf.value(), buf.value() + length); 120c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi return true; 121c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi} 122c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi 123c8573194d35f6b6c5033aedbef1ef5b07771792bUtkarsh Sanghi} // namespace tpm_manager 124