blob: 5eacebf3c18395a7aa2e390fe5e3ed8cabc9206e [file] [log] [blame]
// Copyright 2014 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 TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_
#define TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_
#include <string>
#include <base/gtest_prod_util.h>
#include <chromeos/chromeos_export.h>
#include <crypto/secure_hash.h>
#include "trunks/authorization_delegate.h"
#include "trunks/tpm_generated.h"
namespace trunks {
const uint8_t kContinueSession = 1;
const uint16_t kAesKeySize = 16; // 128 bits is minimum AES key size.
const uint32_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);
* NullAuthorizationDelegate null;
* tpm.StartAuthSession(..., &null);
* HmacAuthorizationDelegate hmac(false);
* hmac.InitSession(...);
* tpm.Create(..., &hmac);
* hmac.set_entity_auth_value(...);
* tpm.Load(..., &hmac);
*/
class CHROMEOS_EXPORT HmacAuthorizationDelegate: public AuthorizationDelegate {
public:
// This constructor for the HmacAuthorizationDelegate takes a boolean value
// which specifies if parameter encryption/decryption is enabled in this
// delegate.
explicit HmacAuthorizationDelegate(bool parameter_encryption);
virtual ~HmacAuthorizationDelegate();
// AuthorizationDelegate methods.
virtual bool GetCommandAuthorization(const std::string& command_hash,
std::string* authorization);
virtual bool CheckResponseAuthorization(const std::string& response_hash,
const std::string& authorization);
virtual bool EncryptCommandParameter(std::string* parameter);
virtual bool DecryptResponseParameter(std::string* parameter);
// 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.
virtual 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);
// This method is used to inject an auth_value associated with an entity.
// This auth_value is then used when generating HMACs.
// Note: after providing authorization for an entity this needs to be,
// explicitly reset to the null string.
virtual void set_entity_auth_value(const std::string& auth_value);
protected:
FRIEND_TEST(HmacAuthorizationDelegateTest, SessionKeyTest);
private:
// This method implements the key derivation function used in the TPM.
// NOTE: It only returns 32 byte keys.
virtual 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|
virtual 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.
virtual 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.
virtual void RegenerateCallerNonce();
TPM_HANDLE session_handle_;
TPM2B_NONCE caller_nonce_;
TPM2B_NONCE tpm_nonce_;
TPMA_SESSION attributes_;
std::string session_key_;
std::string entity_auth_value_;
DISALLOW_COPY_AND_ASSIGN(HmacAuthorizationDelegate);
};
} // namespace trunks
#endif // TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_