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