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