| // |
| // Copyright (c) 2018 The Chromium OS Authors. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| #ifndef TPM_MANAGER_SERVER_NV_INDEX_AUTHENTICATOR_H_ |
| #define TPM_MANAGER_SERVER_NV_INDEX_AUTHENTICATOR_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include <trunks/scoped_global_session.h> |
| #include <trunks/tpm_utility_impl.h> |
| |
| #include "tpm_manager/server/tpm_status.h" |
| |
| namespace tpm_manager { |
| |
| // Enable salting for global session. |
| const bool kGlobalSessionSalted = true; |
| // Enable encryption for global session. |
| const bool kGlobalSessionEncryption = true; |
| |
| /* |
| * NvIndexAuthenticator is a helper class which hold the needed variable used |
| * for creating and holding the ownership of authorization session and |
| * released when desturcting. |
| * |
| * The usage: |
| * NvIndexAuthenticator nvindex_auth(tpm_status_, &trunks_session_, |
| * trunks_factory_); |
| * and then call the helper to initialize a session and get delegate when |
| * needed. |
| * |
| * It is used only in tpm2_nvram_impl.cc currently. |
| */ |
| class NvIndexAuthenticator { |
| public: |
| NvIndexAuthenticator(TpmStatus* tpm_status, |
| std::unique_ptr<trunks::HmacSession>* trunks_session, |
| const trunks::TrunksFactory& factory) |
| : tpm_status_(tpm_status), |
| trunks_factory_(factory), |
| trunks_session_(trunks_session), |
| password_delegate_(nullptr), |
| session_scope_(nullptr) { |
| CHECK(tpm_status_); |
| } |
| |
| trunks::AuthorizationDelegate* GetDirectAuthDelegate( |
| const std::string& authorization_value) { |
| if (authorization_value.empty() || |
| tpm_status_->CheckAndNotifyIfTpmOwned() != TpmStatus::kTpmOwned) { |
| password_delegate_ = |
| trunks_factory_.GetPasswordAuthorization(authorization_value); |
| return password_delegate_.get(); |
| } else { |
| return SetupHMACSession(authorization_value); |
| } |
| } |
| |
| trunks::AuthorizationDelegate* GetOwnerAuthDelegate( |
| const std::string& owner_password) { |
| switch (tpm_status_->CheckAndNotifyIfTpmOwned()) { |
| case TpmStatus::kTpmUnowned: |
| password_delegate_ = trunks_factory_.GetPasswordAuthorization(""); |
| return password_delegate_.get(); |
| case TpmStatus::kTpmPreOwned: |
| password_delegate_ = trunks_factory_.GetPasswordAuthorization( |
| trunks::kWellKnownPassword); |
| return password_delegate_.get(); |
| case TpmStatus::kTpmOwned: |
| // return error if TPM is owned but the owner_password is not availible |
| if (owner_password.empty()) { |
| // The owner password has been destroyed. |
| return nullptr; |
| } |
| return SetupHMACSession(owner_password); |
| } |
| } |
| |
| private: |
| /* |
| * helper to initialize the HMAC session |
| * return the delegate if initialize successfully. Otherwise, return nullptr. |
| */ |
| trunks::AuthorizationDelegate* SetupHMACSession( |
| const std::string& authorization_value) { |
| session_scope_ = std::make_unique<trunks::ScopedGlobalHmacSession>( |
| &trunks_factory_, kGlobalSessionSalted, kGlobalSessionEncryption, |
| trunks_session_); |
| if (!*trunks_session_) { |
| // Session failure |
| return nullptr; |
| } |
| (*trunks_session_)->SetEntityAuthorizationValue(authorization_value); |
| return (*trunks_session_)->GetDelegate(); |
| } |
| |
| TpmStatus* tpm_status_; |
| const trunks::TrunksFactory& trunks_factory_; |
| |
| std::unique_ptr<trunks::HmacSession>* trunks_session_; |
| std::unique_ptr<trunks::AuthorizationDelegate> password_delegate_; |
| std::unique_ptr<trunks::ScopedGlobalHmacSession> session_scope_; |
| }; |
| |
| } // namespace tpm_manager |
| |
| #endif // TPM_MANAGER_SERVER_NV_INDEX_AUTHENTICATOR_H_ |