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