1bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 2bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Copyright (C) 2014 The Android Open Source Project 3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Licensed under the Apache License, Version 2.0 (the "License"); 5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// you may not use this file except in compliance with the License. 6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// You may obtain a copy of the License at 7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// http://www.apache.org/licenses/LICENSE-2.0 9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// Unless required by applicable law or agreed to in writing, software 11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// distributed under the License is distributed on an "AS IS" BASIS, 12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// See the License for the specific language governing permissions and 14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// limitations under the License. 15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi// 164261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 17a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#ifndef TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_ 18a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#define TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_ 194261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 204261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <string> 214261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 224261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <base/gtest_prod_util.h> 234261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include <crypto/secure_hash.h> 24e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi#include <gtest/gtest_prod.h> 254261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 264261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include "trunks/authorization_delegate.h" 274261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include "trunks/tpm_generated.h" 28ef87f3e63b93ff722a8cbcee9c54d55d085221a3Darren Krahn#include "trunks/trunks_export.h" 294261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 304261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghinamespace trunks { 314261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 324261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghiconst uint8_t kContinueSession = 1; 3335af244e7cf856a02e46ec8f186f36c53582757dUtkarsh Sanghiconst size_t kAesKeySize = 16; // 128 bits is minimum AES key size. 3435af244e7cf856a02e46ec8f186f36c53582757dUtkarsh Sanghiconst size_t kHashDigestSize = 32; // 256 bits is SHA256 digest size. 354261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 36ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// HmacAuthorizationDelegate is an implementation of the AuthorizationDelegate 37ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// interface. It provides the necessary Auth data for HMAC sessions. 38ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// This delegate also does parameter encryption on sessions that support it. 39ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi 40ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// Usage: 41ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// 1) After running the StartAuthSession command on the TPM2.0, we declare this 42ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// delegate using the constructor. We can specify if we want parameter 43ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// obfuscation enabled or not. 44ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// 2) We initialize the session using |InitSession|. We feed in the handle and 45ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// tpm_nonce returned by StartAuthSession. Additionally we inject the 46ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// caller_nonce, salt and auth_value of the bound entity we fed into 47ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// StartAuthSession. 48ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// 3) Pass a pointer to this delegate to any TPM command that needs 49ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// authorization using this delegate. 50ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi 51ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// Sample control flow: 52ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// TrunksProxy proxy; 53ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// proxy.Init(); 54ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// Tpm tpm(&proxy); 55ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// tpm.StartAuthSession(...); 56ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// HmacAuthorizationDelegate hmac(); 57ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// hmac.InitSession(...); 58ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// tpm.Create(..., &hmac); 59fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi// hmac.set_entity_authorization_value(...); 60ff7f2da556b21253a52abbc82e7cf7bee54a850eUtkarsh Sanghi// tpm.Load(..., &hmac); 614dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahnclass TRUNKS_EXPORT HmacAuthorizationDelegate : public AuthorizationDelegate { 624261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi public: 630adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi HmacAuthorizationDelegate(); 641aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn ~HmacAuthorizationDelegate() override; 651aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn 664261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // AuthorizationDelegate methods. 671aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool GetCommandAuthorization(const std::string& command_hash, 681aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool is_command_parameter_encryption_possible, 691aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool is_response_parameter_encryption_possible, 70887ccbcc4db5fa0b5221018296aa49b86a5ac26fUtkarsh Sanghi std::string* authorization) override; 711aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool CheckResponseAuthorization(const std::string& response_hash, 721aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& authorization) override; 731aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool EncryptCommandParameter(std::string* parameter) override; 741aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool DecryptResponseParameter(std::string* parameter) override; 754261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 764261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This function is called with the return data of |StartAuthSession|. It 774261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // will initialize the session to start providing auth information. It can 784261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // only be called once per delegate, and must be called before the delegate 791aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn // is used for any operation. The boolean arg |enable_parameter_encryption| 801aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn // specifies if parameter encryption should be enabled for this delegate. 810adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi // |salt| and |bind_auth_value| specify the injected auth values into this 820adc864900a88490fe92897438e13f00940b69b0Utkarsh Sanghi // delegate. 831aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool InitSession(TPM_HANDLE session_handle, 841aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& tpm_nonce, 851aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& caller_nonce, 861aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& salt, 871aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& bind_auth_value, 881aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool enable_parameter_encryption); 89e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 90d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi // This method sets the FutureAuthorizationValue. This value is used in 91d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi // computing the HMAC response of TPM2_HierarchyChangeAuth. 92d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi void set_future_authorization_value(const std::string& auth_value); 93d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi 94db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi std::string future_authorization_value() { 95db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi return future_authorization_value_; 96db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi } 97db998f5fa0f203ee9e34f88821cbb51037206581Utkarsh Sanghi 984261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method is used to inject an auth_value associated with an entity. 99e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi // This auth_value is then used when generating HMACs and encryption keys. 100e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi // Note: This value will be used for all commands until explicitly reset. 101fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi void set_entity_authorization_value(const std::string& auth_value) { 102fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi entity_authorization_value_ = auth_value; 103e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 104e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 105fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi std::string entity_authorization_value() const { 106fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi return entity_authorization_value_; 107e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi } 108e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi 1094dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn TPM_HANDLE session_handle() const { return session_handle_; } 1104261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 111fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi void set_use_entity_authorization_for_encryption_only(bool value) { 112fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi use_entity_authorization_for_encryption_only_ = value; 113fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi } 114fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi 1154261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi protected: 116e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi FRIEND_TEST(HmacAuthorizationDelegateFixture, NonceRegenerationTest); 117e8b9a556d4561617747fed4ee5ced70fce9a4392Utkarsh Sanghi FRIEND_TEST(HmacAuthorizationDelegateTest, EncryptDecryptTest); 118a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn FRIEND_TEST(HmacAuthorizationDelegateTest, SessionKeyTest); 1194261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1204261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi private: 1214261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method implements the key derivation function used in the TPM. 1224261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // NOTE: It only returns 32 byte keys. 1231aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn std::string CreateKey(const std::string& hmac_key, 1241aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const std::string& label, 1251aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_newer, 1261aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_older); 1274261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method performs a FIPS198 HMAC operation on |data| using |key| 1284dc4629c415e7ca90ff146d7bb75b5646ecd8b17Darren Krahn std::string HmacSha256(const std::string& key, const std::string& data); 12902135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi // This method performs an AES operation using a 128 bit key. 13002135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi // |operation_type| can be either AES_ENCRYPT or AES_DECRYPT and it 13102135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi // determines if the operation is an encryption or decryption. 1321aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn void AesOperation(std::string* parameter, 1331aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_newer, 1341aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn const TPM2B_NONCE& nonce_older, 1351aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn int operation_type); 1364261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // This method regenerates the caller nonce. The new nonce is the same 1374261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // length as the previous nonce. The buffer is filled with random data using 1384261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // openssl's |RAND_bytes| function. 1394261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi // NOTE: This operation is DESTRUCTIVE, and rewrites the caller_nonce_ field. 1401aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn void RegenerateCallerNonce(); 1414261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1424261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi TPM_HANDLE session_handle_; 1434261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi TPM2B_NONCE caller_nonce_; 1444261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi TPM2B_NONCE tpm_nonce_; 1451aeb5969d4f286e36fe88152ad8c96cff668c25fDarren Krahn bool is_parameter_encryption_enabled_; 146d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi bool nonce_generated_; 1474261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi std::string session_key_; 148fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi std::string entity_authorization_value_; 149d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi bool future_authorization_value_set_; 150d89b4dc09f61e540caa077c6d53b9abf698e6d6fUtkarsh Sanghi std::string future_authorization_value_; 151fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi // This boolean flag determines if the entity_authorization_value_ is needed 152fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi // when computing the hmac_key to create the authorization hmac. Defaults 153fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi // to false, but policy sessions may set this flag to true. 154fc942a5ffc967b7b2b206aee8b91b3bae1933382Utkarsh Sanghi bool use_entity_authorization_for_encryption_only_; 1554261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 156a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn DISALLOW_COPY_AND_ASSIGN(HmacAuthorizationDelegate); 1574261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi}; 1584261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 1594261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi} // namespace trunks 1604261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi 161a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#endif // TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_ 162