hmac_authorization_delegate.h revision a19238f46d4341489fd1d3140df1bb09bdbd8f01
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>
134261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
144261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include "trunks/authorization_delegate.h"
154261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi#include "trunks/tpm_generated.h"
164261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
174261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghinamespace trunks {
184261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
194261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghiconst uint8_t kContinueSession = 1;
204261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghiconst uint16_t kAesKeySize = 16;      // 128 bits is minimum AES key size.
214261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghiconst uint32_t kHashDigestSize = 32;  // 256 bits is SHA256 digest size.
224261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
23a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn/* HmacAuthorizationDelegate is an implementation of the AuthorizationDelegate
244261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * interface. It provides the necessary Auth data for HMAC sessions.
254261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * This delegate also does parameter encryption on sessions that support it.
264261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi *
274261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * Usage:
284261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 1) After running the StartAuthSession command on the TPM2.0, we declare this
294261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * delegate using the constructor. We can specify if we want parameter
304261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * obfuscation enabled or not.
314261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 2) We initialize the session using |InitSession|. We feed in the handle and
324261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * tpm_nonce returned by StartAuthSession. Additionally we inject the
334261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * caller_nonce, salt and auth_value of the bound entity we fed into
344261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * StartAuthSession.
354261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * 3) Pass a pointer to this delegate to any TPM command that needs
364261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * authorization using this delegate.
374261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi *
384261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi * Sample control flow:
394261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi *  TrunksProxy proxy;
404261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi *  proxy.Init();
414261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi *  Tpm tpm(&proxy);
42a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn *  NullAuthorizationDelegate null;
434261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi *  tpm.StartAuthSession(..., &null);
44a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn *  HmacAuthorizationDelegate hmac(false);
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:
52a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  // This constructor for the HmacAuthorizationDelegate takes a boolean value
53a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  // which specifies if parameter encryption/decryption is enabled in this
54a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  // delegate.
55a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  explicit HmacAuthorizationDelegate(bool parameter_encryption);
56a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  virtual ~HmacAuthorizationDelegate();
574261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // AuthorizationDelegate methods.
584261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual bool GetCommandAuthorization(const std::string& command_hash,
594261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                                       std::string* authorization);
604261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual bool CheckResponseAuthorization(const std::string& response_hash,
614261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                                          const std::string& authorization);
624261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual bool EncryptCommandParameter(std::string* parameter);
634261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual bool DecryptResponseParameter(std::string* parameter);
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
684261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // is used for any operation.
694261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual bool InitSession(TPM_HANDLE session_handle,
704261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                           const TPM2B_NONCE& tpm_nonce,
714261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                           const TPM2B_NONCE& caller_nonce,
724261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                           const std::string& salt,
734261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                           const std::string& bind_auth_value);
744261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // This method is used to inject an auth_value associated with an entity.
754261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // This auth_value is then used when generating HMACs.
764261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // Note: after providing authorization for an entity this needs to be,
774261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // explicitly reset to the null string.
784261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual void set_entity_auth_value(const std::string& auth_value);
794261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
804261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi protected:
81a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  FRIEND_TEST(HmacAuthorizationDelegateTest, SessionKeyTest);
824261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
834261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi private:
844261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // This method implements the key derivation function used in the TPM.
854261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // NOTE: It only returns 32 byte keys.
864261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual std::string CreateKey(const std::string& hmac_key,
874261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                                const std::string& label,
884261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                                const TPM2B_NONCE& nonce_newer,
894261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                                const TPM2B_NONCE& nonce_older);
904261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // This method performs a FIPS198 HMAC operation on |data| using |key|
914261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual std::string HmacSha256(const std::string& key,
924261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi                                  const std::string& data);
9302135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi  // This method performs an AES operation using a 128 bit key.
9402135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi  // |operation_type| can be either AES_ENCRYPT or AES_DECRYPT and it
9502135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi  // determines if the operation is an encryption or decryption.
9602135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi  virtual void AesOperation(std::string* parameter,
9702135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi                            const TPM2B_NONCE& nonce_newer,
9802135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi                            const TPM2B_NONCE& nonce_older,
9902135c88d5400e674ba2835ac60a54ec01c5e90fUtkarsh Sanghi                            int operation_type);
1004261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // This method regenerates the caller nonce. The new nonce is the same
1014261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // length as the previous nonce. The buffer is filled with random data using
1024261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // openssl's |RAND_bytes| function.
1034261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  // NOTE: This operation is DESTRUCTIVE, and rewrites the caller_nonce_ field.
1044261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  virtual void RegenerateCallerNonce();
1054261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
1064261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  TPM_HANDLE session_handle_;
1074261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  TPM2B_NONCE caller_nonce_;
1084261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  TPM2B_NONCE tpm_nonce_;
1094261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  TPMA_SESSION attributes_;
1104261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  std::string session_key_;
1114261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi  std::string entity_auth_value_;
1124261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
113a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn  DISALLOW_COPY_AND_ASSIGN(HmacAuthorizationDelegate);
1144261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi};
1154261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
1164261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi}  // namespace trunks
1174261114797a2793bae83fbabe0459cc465203dd2Utkarsh Sanghi
118a19238f46d4341489fd1d3140df1bb09bdbd8f01Darren Krahn#endif  // TRUNKS_HMAC_AUTHORIZATION_DELEGATE_H_
119