Home | History | Annotate | Download | only in trunks
      1 //
      2 // Copyright (C) 2015 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #include "trunks/policy_session_impl.h"
     18 
     19 #include <string>
     20 #include <vector>
     21 
     22 #include <base/logging.h>
     23 #include <base/macros.h>
     24 #include <base/stl_util.h>
     25 #include <crypto/sha2.h>
     26 #include <openssl/rand.h>
     27 
     28 #include "trunks/error_codes.h"
     29 #include "trunks/tpm_generated.h"
     30 
     31 namespace trunks {
     32 
     33 PolicySessionImpl::PolicySessionImpl(const TrunksFactory& factory)
     34     : factory_(factory), session_type_(TPM_SE_POLICY) {
     35   session_manager_ = factory_.GetSessionManager();
     36 }
     37 
     38 PolicySessionImpl::PolicySessionImpl(const TrunksFactory& factory,
     39                                      TPM_SE session_type)
     40     : factory_(factory), session_type_(session_type) {
     41   session_manager_ = factory_.GetSessionManager();
     42 }
     43 
     44 PolicySessionImpl::~PolicySessionImpl() {
     45   session_manager_->CloseSession();
     46 }
     47 
     48 AuthorizationDelegate* PolicySessionImpl::GetDelegate() {
     49   if (session_manager_->GetSessionHandle() == kUninitializedHandle) {
     50     return nullptr;
     51   }
     52   return &hmac_delegate_;
     53 }
     54 
     55 TPM_RC PolicySessionImpl::StartBoundSession(
     56     TPMI_DH_ENTITY bind_entity,
     57     const std::string& bind_authorization_value,
     58     bool enable_encryption) {
     59   hmac_delegate_.set_use_entity_authorization_for_encryption_only(true);
     60   if (session_type_ != TPM_SE_POLICY && session_type_ != TPM_SE_TRIAL) {
     61     LOG(ERROR) << "Cannot start a session of that type.";
     62     return SAPI_RC_INVALID_SESSIONS;
     63   }
     64   return session_manager_->StartSession(session_type_, bind_entity,
     65                                         bind_authorization_value,
     66                                         enable_encryption, &hmac_delegate_);
     67 }
     68 
     69 TPM_RC PolicySessionImpl::StartUnboundSession(bool enable_encryption) {
     70   // Just like a HmacAuthorizationSession, an unbound policy session is just
     71   // a session bound to TPM_RH_NULL.
     72   return StartBoundSession(TPM_RH_NULL, "", enable_encryption);
     73 }
     74 
     75 TPM_RC PolicySessionImpl::GetDigest(std::string* digest) {
     76   CHECK(digest);
     77   TPM2B_DIGEST policy_digest;
     78   TPM_RC result = factory_.GetTpm()->PolicyGetDigestSync(
     79       session_manager_->GetSessionHandle(),
     80       "",  // No name is needed for this command, as it does no authorization.
     81       &policy_digest, nullptr);
     82   if (result != TPM_RC_SUCCESS) {
     83     LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
     84     return result;
     85   }
     86   *digest = StringFrom_TPM2B_DIGEST(policy_digest);
     87   return TPM_RC_SUCCESS;
     88 }
     89 
     90 TPM_RC PolicySessionImpl::PolicyOR(const std::vector<std::string>& digests) {
     91   if (digests.size() >= arraysize(TPML_DIGEST::digests)) {
     92     LOG(ERROR) << "TPM2.0 Spec only allows for up to 8 digests.";
     93     return SAPI_RC_BAD_PARAMETER;
     94   }
     95   TPML_DIGEST tpm_digests;
     96   tpm_digests.count = digests.size();
     97   for (size_t i = 0; i < digests.size(); i++) {
     98     tpm_digests.digests[i] = Make_TPM2B_DIGEST(digests[i]);
     99   }
    100   TPM_RC result = factory_.GetTpm()->PolicyORSync(
    101       session_manager_->GetSessionHandle(),
    102       "",  // No policy name is needed as we do no authorization checks.
    103       tpm_digests, nullptr);
    104   if (result != TPM_RC_SUCCESS) {
    105     LOG(ERROR) << "Error performing PolicyOR: " << GetErrorString(result);
    106     return result;
    107   }
    108 
    109   return TPM_RC_SUCCESS;
    110 }
    111 
    112 TPM_RC PolicySessionImpl::PolicyPCR(uint32_t pcr_index,
    113                                     const std::string& pcr_value) {
    114   TPML_PCR_SELECTION pcr_select;
    115   memset(&pcr_select, 0, sizeof(TPML_PCR_SELECTION));
    116   // This process of selecting pcrs is highlighted in TPM 2.0 Library Spec
    117   // Part 2 (Section 10.5 - PCR structures).
    118   uint8_t pcr_select_index = pcr_index / 8;
    119   uint8_t pcr_select_byte = 1 << (pcr_index % 8);
    120   pcr_select.count = 1;
    121   pcr_select.pcr_selections[0].hash = TPM_ALG_SHA256;
    122   pcr_select.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
    123   pcr_select.pcr_selections[0].pcr_select[pcr_select_index] = pcr_select_byte;
    124   TPM2B_DIGEST pcr_digest;
    125   if (pcr_value.empty()) {
    126     if (session_type_ == TPM_SE_TRIAL) {
    127       LOG(ERROR) << "Trial sessions have to define a PCR value.";
    128       return SAPI_RC_BAD_PARAMETER;
    129     }
    130     pcr_digest = Make_TPM2B_DIGEST("");
    131   } else {
    132     pcr_digest = Make_TPM2B_DIGEST(crypto::SHA256HashString(pcr_value));
    133   }
    134 
    135   TPM_RC result = factory_.GetTpm()->PolicyPCRSync(
    136       session_manager_->GetSessionHandle(),
    137       "",  // No policy name is needed as we do no authorization checks.
    138       pcr_digest, pcr_select, nullptr);
    139   if (result != TPM_RC_SUCCESS) {
    140     LOG(ERROR) << "Error performing PolicyPCR: " << GetErrorString(result);
    141     return result;
    142   }
    143   return TPM_RC_SUCCESS;
    144 }
    145 
    146 TPM_RC PolicySessionImpl::PolicyCommandCode(TPM_CC command_code) {
    147   TPM_RC result = factory_.GetTpm()->PolicyCommandCodeSync(
    148       session_manager_->GetSessionHandle(),
    149       "",  // No policy name is needed as we do no authorization checks.
    150       command_code, nullptr);
    151   if (result != TPM_RC_SUCCESS) {
    152     LOG(ERROR) << "Error performing PolicyCommandCode: "
    153                << GetErrorString(result);
    154     return result;
    155   }
    156   return TPM_RC_SUCCESS;
    157 }
    158 
    159 TPM_RC PolicySessionImpl::PolicyAuthValue() {
    160   TPM_RC result = factory_.GetTpm()->PolicyAuthValueSync(
    161       session_manager_->GetSessionHandle(),
    162       "",  // No policy name is needed as we do no authorization checks.
    163       nullptr);
    164   if (result != TPM_RC_SUCCESS) {
    165     LOG(ERROR) << "Error performing PolicyAuthValue: "
    166                << GetErrorString(result);
    167     return result;
    168   }
    169   hmac_delegate_.set_use_entity_authorization_for_encryption_only(false);
    170   return TPM_RC_SUCCESS;
    171 }
    172 
    173 TPM_RC PolicySessionImpl::PolicyRestart() {
    174   TPM_RC result = factory_.GetTpm()->PolicyAuthValueSync(
    175       session_manager_->GetSessionHandle(),
    176       "",  // No policy name is needed as we do no authorization checks.
    177       nullptr);
    178   if (result != TPM_RC_SUCCESS) {
    179     LOG(ERROR) << "Error performing PolicyRestart: " << GetErrorString(result);
    180     return result;
    181   }
    182   return TPM_RC_SUCCESS;
    183 }
    184 
    185 void PolicySessionImpl::SetEntityAuthorizationValue(const std::string& value) {
    186   hmac_delegate_.set_entity_authorization_value(value);
    187 }
    188 
    189 }  // namespace trunks
    190