161 lines
6.6 KiB
C++
161 lines
6.6 KiB
C++
//
|
|
// Copyright (C) 2014 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#ifndef TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_
|
|
#define TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_
|
|
|
|
#include <string>
|
|
|
|
#include <base/gtest_prod_util.h>
|
|
#include <crypto/secure_hash.h>
|
|
#include <gtest/gtest_prod.h>
|
|
|
|
#include "trunks/authorization_delegate.h"
|
|
#include "trunks/tpm_generated.h"
|
|
#include "trunks/trunks_export.h"
|
|
|
|
namespace trunks {
|
|
|
|
const uint8_t kContinueSession = 1;
|
|
const size_t kAesKeySize = 16; // 128 bits is minimum AES key size.
|
|
const size_t kHashDigestSize = 32; // 256 bits is SHA256 digest size.
|
|
|
|
// HmacAuthorizationDelegate is an implementation of the AuthorizationDelegate
|
|
// interface. It provides the necessary Auth data for HMAC sessions.
|
|
// This delegate also does parameter encryption on sessions that support it.
|
|
|
|
// Usage:
|
|
// 1) After running the StartAuthSession command on the TPM2.0, we declare this
|
|
// delegate using the constructor. We can specify if we want parameter
|
|
// obfuscation enabled or not.
|
|
// 2) We initialize the session using |InitSession|. We feed in the handle and
|
|
// tpm_nonce returned by StartAuthSession. Additionally we inject the
|
|
// caller_nonce, salt and auth_value of the bound entity we fed into
|
|
// StartAuthSession.
|
|
// 3) Pass a pointer to this delegate to any TPM command that needs
|
|
// authorization using this delegate.
|
|
|
|
// Sample control flow:
|
|
// TrunksProxy proxy;
|
|
// proxy.Init();
|
|
// Tpm tpm(&proxy);
|
|
// tpm.StartAuthSession(...);
|
|
// HmacAuthorizationDelegate hmac();
|
|
// hmac.InitSession(...);
|
|
// tpm.Create(..., &hmac);
|
|
// hmac.set_entity_authorization_value(...);
|
|
// tpm.Load(..., &hmac);
|
|
class TRUNKS_EXPORT HmacAuthorizationDelegate : public AuthorizationDelegate {
|
|
public:
|
|
HmacAuthorizationDelegate();
|
|
~HmacAuthorizationDelegate() override;
|
|
|
|
// AuthorizationDelegate methods.
|
|
bool GetCommandAuthorization(const std::string& command_hash,
|
|
bool is_command_parameter_encryption_possible,
|
|
bool is_response_parameter_encryption_possible,
|
|
std::string* authorization) override;
|
|
bool CheckResponseAuthorization(const std::string& response_hash,
|
|
const std::string& authorization) override;
|
|
bool EncryptCommandParameter(std::string* parameter) override;
|
|
bool DecryptResponseParameter(std::string* parameter) override;
|
|
|
|
// This function is called with the return data of |StartAuthSession|. It
|
|
// will initialize the session to start providing auth information. It can
|
|
// only be called once per delegate, and must be called before the delegate
|
|
// is used for any operation. The boolean arg |enable_parameter_encryption|
|
|
// specifies if parameter encryption should be enabled for this delegate.
|
|
// |salt| and |bind_auth_value| specify the injected auth values into this
|
|
// delegate.
|
|
bool InitSession(TPM_HANDLE session_handle,
|
|
const TPM2B_NONCE& tpm_nonce,
|
|
const TPM2B_NONCE& caller_nonce,
|
|
const std::string& salt,
|
|
const std::string& bind_auth_value,
|
|
bool enable_parameter_encryption);
|
|
|
|
// This method sets the FutureAuthorizationValue. This value is used in
|
|
// computing the HMAC response of TPM2_HierarchyChangeAuth.
|
|
void set_future_authorization_value(const std::string& auth_value);
|
|
|
|
std::string future_authorization_value() {
|
|
return future_authorization_value_;
|
|
}
|
|
|
|
// This method is used to inject an auth_value associated with an entity.
|
|
// This auth_value is then used when generating HMACs and encryption keys.
|
|
// Note: This value will be used for all commands until explicitly reset.
|
|
void set_entity_authorization_value(const std::string& auth_value) {
|
|
entity_authorization_value_ = auth_value;
|
|
}
|
|
|
|
std::string entity_authorization_value() const {
|
|
return entity_authorization_value_;
|
|
}
|
|
|
|
TPM_HANDLE session_handle() const { return session_handle_; }
|
|
|
|
void set_use_entity_authorization_for_encryption_only(bool value) {
|
|
use_entity_authorization_for_encryption_only_ = value;
|
|
}
|
|
|
|
protected:
|
|
FRIEND_TEST(HmacAuthorizationDelegateFixture, NonceRegenerationTest);
|
|
FRIEND_TEST(HmacAuthorizationDelegateTest, EncryptDecryptTest);
|
|
FRIEND_TEST(HmacAuthorizationDelegateTest, SessionKeyTest);
|
|
|
|
private:
|
|
// This method implements the key derivation function used in the TPM.
|
|
// NOTE: It only returns 32 byte keys.
|
|
std::string CreateKey(const std::string& hmac_key,
|
|
const std::string& label,
|
|
const TPM2B_NONCE& nonce_newer,
|
|
const TPM2B_NONCE& nonce_older);
|
|
// This method performs a FIPS198 HMAC operation on |data| using |key|
|
|
std::string HmacSha256(const std::string& key, const std::string& data);
|
|
// This method performs an AES operation using a 128 bit key.
|
|
// |operation_type| can be either AES_ENCRYPT or AES_DECRYPT and it
|
|
// determines if the operation is an encryption or decryption.
|
|
void AesOperation(std::string* parameter,
|
|
const TPM2B_NONCE& nonce_newer,
|
|
const TPM2B_NONCE& nonce_older,
|
|
int operation_type);
|
|
// This method regenerates the caller nonce. The new nonce is the same
|
|
// length as the previous nonce. The buffer is filled with random data using
|
|
// openssl's |RAND_bytes| function.
|
|
// NOTE: This operation is DESTRUCTIVE, and rewrites the caller_nonce_ field.
|
|
void RegenerateCallerNonce();
|
|
|
|
TPM_HANDLE session_handle_;
|
|
TPM2B_NONCE caller_nonce_;
|
|
TPM2B_NONCE tpm_nonce_;
|
|
bool is_parameter_encryption_enabled_;
|
|
bool nonce_generated_;
|
|
std::string session_key_;
|
|
std::string entity_authorization_value_;
|
|
bool future_authorization_value_set_;
|
|
std::string future_authorization_value_;
|
|
// This boolean flag determines if the entity_authorization_value_ is needed
|
|
// when computing the hmac_key to create the authorization hmac. Defaults
|
|
// to false, but policy sessions may set this flag to true.
|
|
bool use_entity_authorization_for_encryption_only_;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(HmacAuthorizationDelegate);
|
|
};
|
|
|
|
} // namespace trunks
|
|
|
|
#endif // TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_
|