hmac_authorization_delegate.h revision 887ccbcc4db5fa0b5221018296aa49b86a5ac26f
14261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi// Copyright 2014 The Chromium OS Authors. All rights reserved. 24261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi// Use of this source code is governed by a BSD-style license that can be 34261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi// found in the LICENSE file. 44261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 5a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#ifndef TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_ 6a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#define TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_ 74261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 84261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <string> 94261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 104261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <base/gtest_prod_util.h> 114261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <chromeos/chromeos_export.h> 124261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <crypto/secure_hash.h> 13e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi#include <gtest/gtest_prod.h> 144261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 154261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include "trunks/authorization_delegate.h" 164261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include "trunks/tpm_generated.h" 174261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 184261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghinamespace trunks { 194261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 204261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghiconst uint8_t kContinueSession = 1; 2135af244e7cf856a02e46ec8f186f36c53582757dUtkarsh Sanghiconst size_t kAesKeySize = 16; // 128 bits is minimum AES key size. 2235af244e7cf856a02e46ec8f186f36c53582757dUtkarsh Sanghiconst size_t kHashDigestSize = 32; // 256 bits is SHA256 digest size. 234261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 24a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn/* HmacAuthorizationDelegate is an implementation of the AuthorizationDelegate 254261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * interface. It provides the necessary Auth data for HMAC sessions. 264261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * This delegate also does parameter encryption on sessions that support it. 274261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 284261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * Usage: 294261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 1) After running the StartAuthSession command on the TPM2.0, we declare this 304261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * delegate using the constructor. We can specify if we want parameter 314261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * obfuscation enabled or not. 324261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 2) We initialize the session using |InitSession|. We feed in the handle and 334261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * tpm_nonce returned by StartAuthSession. Additionally we inject the 344261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * caller_nonce, salt and auth_value of the bound entity we fed into 354261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * StartAuthSession. 364261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 3) Pass a pointer to this delegate to any TPM command that needs 374261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * authorization using this delegate. 384261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 394261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * Sample control flow: 404261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * TrunksProxy proxy; 414261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * proxy.Init(); 424261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * Tpm tpm(&proxy); 436318d4413806a501783a003bf249e3ae627c73edUtkarsh Sanghi * tpm.StartAuthSession(...); 440adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi * HmacAuthorizationDelegate hmac(); 454261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * hmac.InitSession(...); 464261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * tpm.Create(..., &hmac); 474261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * hmac.set_entity_auth_value(...); 484261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * tpm.Load(..., &hmac); 494261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi */ 50a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahnclass CHROMEOS_EXPORT HmacAuthorizationDelegate: public AuthorizationDelegate { 514261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi public: 520adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi HmacAuthorizationDelegate(); 531aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn ~HmacAuthorizationDelegate() override; 541aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn 554261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // AuthorizationDelegate methods. 561aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool GetCommandAuthorization(const std::string& command_hash, 571aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool is_command_parameter_encryption_possible, 581aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool is_response_parameter_encryption_possible, 59887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi std::string* authorization) override; 601aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool CheckResponseAuthorization(const std::string& response_hash, 611aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& authorization) override; 621aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool EncryptCommandParameter(std::string* parameter) override; 631aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool DecryptResponseParameter(std::string* parameter) override; 644261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 654261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This function is called with the return data of |StartAuthSession|. It 664261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // will initialize the session to start providing auth information. It can 674261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // only be called once per delegate, and must be called before the delegate 681aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn // is used for any operation. The boolean arg |enable_parameter_encryption| 691aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn // specifies if parameter encryption should be enabled for this delegate. 700adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi // |salt| and |bind_auth_value| specify the injected auth values into this 710adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi // delegate. 721aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool InitSession(TPM_HANDLE session_handle, 731aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& tpm_nonce, 741aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& caller_nonce, 751aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& salt, 761aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& bind_auth_value, 771aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool enable_parameter_encryption); 78e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 79d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi // This method sets the FutureAuthorizationValue. This value is used in 80d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi // computing the HMAC response of TPM2_HierarchyChangeAuth. 81d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi void set_future_authorization_value(const std::string& auth_value); 82d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi 83db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi std::string future_authorization_value() { 84db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi return future_authorization_value_; 85db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi } 86db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi 874261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method is used to inject an auth_value associated with an entity. 88e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi // This auth_value is then used when generating HMACs and encryption keys. 89e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi // Note: This value will be used for all commands until explicitly reset. 90e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi void set_entity_auth_value(const std::string& auth_value) { 91e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi entity_auth_value_ = auth_value; 92e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 93e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 94d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi std::string entity_auth_value() const { 95e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi return entity_auth_value_; 96e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 97e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 98d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi TPM_HANDLE session_handle() const { 99e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi return session_handle_; 100e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 1014261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1024261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi protected: 103e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi FRIEND_TEST(HmacAuthorizationDelegateFixture, NonceRegenerationTest); 104e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi FRIEND_TEST(HmacAuthorizationDelegateTest, EncryptDecryptTest); 105a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn FRIEND_TEST(HmacAuthorizationDelegateTest, SessionKeyTest); 1064261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1074261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi private: 1084261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method implements the key derivation function used in the TPM. 1094261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // NOTE: It only returns 32 byte keys. 1101aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn std::string CreateKey(const std::string& hmac_key, 1111aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& label, 1121aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_newer, 1131aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_older); 1144261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method performs a FIPS198 HMAC operation on |data| using |key| 1151aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn std::string HmacSha256(const std::string& key, 1161aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& data); 11702135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi // This method performs an AES operation using a 128 bit key. 11802135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi // |operation_type| can be either AES_ENCRYPT or AES_DECRYPT and it 11902135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi // determines if the operation is an encryption or decryption. 1201aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn void AesOperation(std::string* parameter, 1211aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_newer, 1221aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_older, 1231aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn int operation_type); 1244261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method regenerates the caller nonce. The new nonce is the same 1254261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // length as the previous nonce. The buffer is filled with random data using 1264261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // openssl's |RAND_bytes| function. 1274261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // NOTE: This operation is DESTRUCTIVE, and rewrites the caller_nonce_ field. 1281aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn void RegenerateCallerNonce(); 1294261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1304261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi TPM_HANDLE session_handle_; 1314261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi TPM2B_NONCE caller_nonce_; 1324261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi TPM2B_NONCE tpm_nonce_; 1331aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool is_parameter_encryption_enabled_; 134d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi bool nonce_generated_; 1354261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi std::string session_key_; 1364261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi std::string entity_auth_value_; 137d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi bool future_authorization_value_set_; 138d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi std::string future_authorization_value_; 1394261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 140a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn DISALLOW_COPY_AND_ASSIGN(HmacAuthorizationDelegate); 1414261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi}; 1424261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1434261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi} // namespace trunks 1444261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 145a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#endif // TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_ 146