Home | History | Annotate | Download | only in trunks
      1 //
      2 // Copyright (C) 2014 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef TRUNKS_TPM_UTILITY_H_
     18 #define TRUNKS_TPM_UTILITY_H_
     19 
     20 #include <string>
     21 #include <vector>
     22 
     23 #include <base/macros.h>
     24 
     25 #include "trunks/hmac_session.h"
     26 #include "trunks/tpm_generated.h"
     27 #include "trunks/trunks_export.h"
     28 
     29 namespace trunks {
     30 
     31 // These handles will be used by TpmUtility to create storage root keys.
     32 const TPMI_DH_PERSISTENT kRSAStorageRootKey = PERSISTENT_FIRST;
     33 const TPMI_DH_PERSISTENT kECCStorageRootKey = PERSISTENT_FIRST + 1;
     34 const TPMI_DH_PERSISTENT kSaltingKey = PERSISTENT_FIRST + 2;
     35 
     36 // This value to used to specify that no pcr are needed in the creation data
     37 // for a key.
     38 const int kNoCreationPCR = -1;
     39 
     40 // An interface which provides convenient methods for common TPM operations.
     41 class TRUNKS_EXPORT TpmUtility {
     42  public:
     43   enum AsymmetricKeyUsage { kDecryptKey, kSignKey, kDecryptAndSignKey };
     44 
     45   TpmUtility() {}
     46   virtual ~TpmUtility() {}
     47 
     48   // Synchronously performs a TPM startup sequence and self tests. Typically
     49   // this is done by the platform firmware. Returns the result of the startup
     50   // and self-tests or, if already started, just the result of the self-tests.
     51   virtual TPM_RC Startup() = 0;
     52 
     53   // This method removes all TPM context associated with a specific Owner.
     54   // As part of this process, it resets the SPS to a new random value, and
     55   // clears ownerAuth, endorsementAuth and lockoutAuth.
     56   // NOTE: This method needs to be called before InitializeTPM.
     57   virtual TPM_RC Clear() = 0;
     58 
     59   // Synchronously performs a TPM shutdown operation. It should always be
     60   // successful.
     61   virtual void Shutdown() = 0;
     62 
     63   // Synchronously prepares a TPM for use by Chromium OS. Typically this is done
     64   // by the platform firmware and, in that case, this method has no effect.
     65   virtual TPM_RC InitializeTpm() = 0;
     66 
     67   // Synchronously allocates the PCRs in the TPM. Currently we allocate
     68   // the first 16 PCRs to use the SHA-256 hash algorithm.
     69   // NOTE: PCR allocation only takes place at the next TPM_Startup call.
     70   // NOTE: This command needs platform authorization and PP assertion.
     71   virtual TPM_RC AllocatePCR(const std::string& platform_password) = 0;
     72 
     73   // Synchronously takes ownership of the TPM with the given passwords as
     74   // authorization values.
     75   virtual TPM_RC TakeOwnership(const std::string& owner_password,
     76                                const std::string& endorsement_password,
     77                                const std::string& lockout_password) = 0;
     78 
     79   // Stir the tpm random generation module with some random entropy data.
     80   // |delegate| specifies an optional authorization delegate to be used.
     81   virtual TPM_RC StirRandom(const std::string& entropy_data,
     82                             AuthorizationDelegate* delegate) = 0;
     83 
     84   // This method returns |num_bytes| of random data generated by the tpm.
     85   // |delegate| specifies an optional authorization delegate to be used.
     86   virtual TPM_RC GenerateRandom(size_t num_bytes,
     87                                 AuthorizationDelegate* delegate,
     88                                 std::string* random_data) = 0;
     89 
     90   // This method extends the pcr specified by |pcr_index| with the SHA256
     91   // hash of |extend_data|. The exact action performed is
     92   // TPM2_PCR_Extend(Sha256(extend_data));
     93   // |delegate| specifies an optional authorization delegate to be used.
     94   virtual TPM_RC ExtendPCR(int pcr_index,
     95                            const std::string& extend_data,
     96                            AuthorizationDelegate* delegate) = 0;
     97 
     98   // This method reads the pcr specified by |pcr_index| and returns its value
     99   // in |pcr_value|. NOTE: it assumes we are using SHA256 as our hash alg.
    100   virtual TPM_RC ReadPCR(int pcr_index, std::string* pcr_value) = 0;
    101 
    102   // This method performs an encryption operation using a LOADED RSA key
    103   // referrenced by its handle |key_handle|. The |plaintext| is then encrypted
    104   // to give us the |ciphertext|. |scheme| refers to the encryption scheme
    105   // to be used. By default keys use OAEP, but can also use TPM_ALG_RSAES.
    106   // |delegate| specifies an optional authorization delegate to be used.
    107   virtual TPM_RC AsymmetricEncrypt(TPM_HANDLE key_handle,
    108                                    TPM_ALG_ID scheme,
    109                                    TPM_ALG_ID hash_alg,
    110                                    const std::string& plaintext,
    111                                    AuthorizationDelegate* delegate,
    112                                    std::string* ciphertext) = 0;
    113 
    114   // This method performs a decryption operating using a loaded RSA key
    115   // referenced by its handle |key_handle|. The |ciphertext| is then decrypted
    116   // to give us the |plaintext|. |scheme| refers to the decryption scheme
    117   // used. By default it is OAEP, but TPM_ALG_RSAES can be specified.
    118   // |delegate| is an AuthorizationDelegate used to authorize this command.
    119   virtual TPM_RC AsymmetricDecrypt(TPM_HANDLE key_handle,
    120                                    TPM_ALG_ID scheme,
    121                                    TPM_ALG_ID hash_alg,
    122                                    const std::string& ciphertext,
    123                                    AuthorizationDelegate* delegate,
    124                                    std::string* plaintext) = 0;
    125 
    126   // This method takes an unrestricted signing key referenced by |key_handle|
    127   // and uses it to sign the hash of |plaintext|. The signature produced is
    128   // returned using the |signature| argument. |scheme| is used to specify the
    129   // signature scheme used. By default it is TPM_ALG_RSASSA, but TPM_ALG_RSAPPS
    130   // can be specified. |hash_alg| is the algorithm used in the signing
    131   // operation. It is by default TPM_ALG_SHA256.
    132   // |delegate| is an AuthorizationDelegate used to authorize this command.
    133   virtual TPM_RC Sign(TPM_HANDLE key_handle,
    134                       TPM_ALG_ID scheme,
    135                       TPM_ALG_ID hash_alg,
    136                       const std::string& plaintext,
    137                       AuthorizationDelegate* delegate,
    138                       std::string* signature) = 0;
    139 
    140   // This method verifies that the signature produced on the plaintext was
    141   // performed by |key_handle|. |scheme| and |hash| refer to the signature
    142   // scheme used to sign the hash of |plaintext| and produce the signature.
    143   // This value is by default TPM_ALG_RSASSA with TPM_ALG_SHA256 but can take
    144   // the value of TPM_ALG_RSAPPS with other hash algorithms supported by the
    145   // tpm. Returns TPM_RC_SUCCESS when the signature is correct.
    146   // |delegate| specifies an optional authorization delegate to be used.
    147   virtual TPM_RC Verify(TPM_HANDLE key_handle,
    148                         TPM_ALG_ID scheme,
    149                         TPM_ALG_ID hash_alg,
    150                         const std::string& plaintext,
    151                         const std::string& signature,
    152                         AuthorizationDelegate* delegate) = 0;
    153 
    154   // This method is used to check if a key was created in the TPM. |key_handle|
    155   // refers to a loaded Tpm2.0 object, and |creation_blob| is the blob
    156   // generated when the object was created. Returns TPM_RC_SUCCESS iff the
    157   // object was created in the TPM.
    158   virtual TPM_RC CertifyCreation(TPM_HANDLE key_handle,
    159                                  const std::string& creation_blob) = 0;
    160 
    161   // This method is used to change the authorization value associated with a
    162   // |key_handle| to |new_password|. |delegate| is an AuthorizationDelegate
    163   // that is loaded with the old authorization value of |key_handle|.
    164   // When |key_blob| is not null, it is populated with the new encrypted key
    165   // blob. Note: the key must be unloaded and reloaded to use the
    166   // new authorization value.
    167   virtual TPM_RC ChangeKeyAuthorizationData(TPM_HANDLE key_handle,
    168                                             const std::string& new_password,
    169                                             AuthorizationDelegate* delegate,
    170                                             std::string* key_blob) = 0;
    171 
    172   // This method imports an external RSA key of |key_type| into the TPM.
    173   // |modulus| and |prime_factor| are interpreted as raw bytes in big-endian
    174   // order. If the out argument |key_blob| is not null, it is populated with
    175   // the imported key, which can then be loaded into the TPM.
    176   virtual TPM_RC ImportRSAKey(AsymmetricKeyUsage key_type,
    177                               const std::string& modulus,
    178                               uint32_t public_exponent,
    179                               const std::string& prime_factor,
    180                               const std::string& password,
    181                               AuthorizationDelegate* delegate,
    182                               std::string* key_blob) = 0;
    183 
    184   // This method uses the TPM to generates an RSA key of type |key_type|.
    185   // |modulus_bits| is used to specify the size of the modulus, and
    186   // |public_exponent| specifies the exponent of the key. After this function
    187   // terminates, |key_blob| contains a key blob that can be loaded into the TPM.
    188   // |policy_digest| specifies an optional policy to use to authorize this key.
    189   // |use_only_policy_authorization| specifies if we can use HmacSession in
    190   // addition to PolicySession to authorize use of this key.
    191   // |creation_pcr_index| allows the caller to specify a pcr value to include
    192   // in the creation data. If no pcr are needed in the creation data, this
    193   // argument can take the value of kNoCreationPCR.
    194   // If the |creation_blob| out param is defined, it will contain the
    195   // serialized creation structures generated by the TPM.
    196   // This can be used to verify the state of the TPM during key creation.
    197   // NOTE: if |use_only_policy_authorization| is set to true,
    198   // parameter_encryption must be disabled when the key is used.
    199   virtual TPM_RC CreateRSAKeyPair(AsymmetricKeyUsage key_type,
    200                                   int modulus_bits,
    201                                   uint32_t public_exponent,
    202                                   const std::string& password,
    203                                   const std::string& policy_digest,
    204                                   bool use_only_policy_authorization,
    205                                   int creation_pcr_index,
    206                                   AuthorizationDelegate* delegate,
    207                                   std::string* key_blob,
    208                                   std::string* creation_blob) = 0;
    209 
    210   // This method loads a pregenerated TPM key into the TPM. |key_blob| contains
    211   // the blob returned by a key creation function. The loaded key's handle is
    212   // returned using |key_handle|.
    213   virtual TPM_RC LoadKey(const std::string& key_blob,
    214                          AuthorizationDelegate* delegate,
    215                          TPM_HANDLE* key_handle) = 0;
    216 
    217   // This function sets |name| to the name of the object referenced by
    218   // |handle|. This function only works on Transient and Permanent objects.
    219   virtual TPM_RC GetKeyName(TPM_HANDLE handle, std::string* name) = 0;
    220 
    221   // This function returns the public area of a handle in the tpm.
    222   virtual TPM_RC GetKeyPublicArea(TPM_HANDLE handle,
    223                                   TPMT_PUBLIC* public_data) = 0;
    224 
    225   // This method seals |data_to_seal| to the TPM. The |sealed_data| can be
    226   // retreived by fulfilling the policy represented by |policy_digest|.
    227   virtual TPM_RC SealData(const std::string& data_to_seal,
    228                           const std::string& policy_digest,
    229                           AuthorizationDelegate* delegate,
    230                           std::string* sealed_data) = 0;
    231 
    232   // This method is used to retrieve data that was sealed to the TPM.
    233   // |sealed_data| refers to sealed data returned from SealData.
    234   virtual TPM_RC UnsealData(const std::string& sealed_data,
    235                             AuthorizationDelegate* delegate,
    236                             std::string* unsealed_data) = 0;
    237 
    238   // This method sets up a given HmacSession with parameter encryption set to
    239   // true. Returns an TPM_RC_SUCCESS on success.
    240   virtual TPM_RC StartSession(HmacSession* session) = 0;
    241 
    242   // This method uses a trial session to compute the |policy_digest| when
    243   // the policy is bound to a given |pcr_value| at |pcr_index|. If |pcr_value|
    244   // is the empty string, this method uses the currect value of the pcr.
    245   virtual TPM_RC GetPolicyDigestForPcrValue(int pcr_index,
    246                                             const std::string& pcr_value,
    247                                             std::string* policy_digest) = 0;
    248 
    249   // This method defines a non-volatile storage area in the TPM, referenced
    250   // by |index| of size |num_bytes|. This command needs owner authorization.
    251   // The |attributes| of the space must be specified as a combination of
    252   // TPMA_NV_* values. Optionally, an |authorization_value| and / or
    253   // |policy_digest| can be specified which will be associated with the space.
    254   // These values must either be a valid SHA256 digest (or empty).
    255   virtual TPM_RC DefineNVSpace(uint32_t index,
    256                                size_t num_bytes,
    257                                TPMA_NV attributes,
    258                                const std::string& authorization_value,
    259                                const std::string& policy_digest,
    260                                AuthorizationDelegate* delegate) = 0;
    261 
    262   // This method destroys the non-volatile space referred to by |index|.
    263   // This command needs owner authorization.
    264   virtual TPM_RC DestroyNVSpace(uint32_t index,
    265                                 AuthorizationDelegate* delegate) = 0;
    266 
    267   // This method locks the non-volatile space referred to by |index|. The caller
    268   // needs indicate whether they want to |lock_read| and / or |lock_write|. They
    269   // also need to indicate if they are |using_owner_authorization|.
    270   virtual TPM_RC LockNVSpace(uint32_t index,
    271                              bool lock_read,
    272                              bool lock_write,
    273                              bool using_owner_authorization,
    274                              AuthorizationDelegate* delegate) = 0;
    275 
    276   // This method writes |nvram_data| to the non-volatile space referenced by
    277   // |index|, at |offset| bytes from the start of the non-volatile space. The
    278   // caller needs to indicate if they are |using_owner_authorization|. If
    279   // |extend| is set, the value will be extended and offset ignored.
    280   virtual TPM_RC WriteNVSpace(uint32_t index,
    281                               uint32_t offset,
    282                               const std::string& nvram_data,
    283                               bool using_owner_authorization,
    284                               bool extend,
    285                               AuthorizationDelegate* delegate) = 0;
    286 
    287   // This method reads |num_bytes| of data from the |offset| located at the
    288   // non-volatile space defined by |index|. This method returns an error if
    289   // |length| + |offset| is larger than the size of the defined non-volatile
    290   // space. The caller needs to indicate if they are |using_owner_authorization|
    291   virtual TPM_RC ReadNVSpace(uint32_t index,
    292                              uint32_t offset,
    293                              size_t num_bytes,
    294                              bool using_owner_authorization,
    295                              std::string* nvram_data,
    296                              AuthorizationDelegate* delegate) = 0;
    297 
    298   // This function sets |name| to the name of the non-volatile space referenced
    299   // by |index|.
    300   virtual TPM_RC GetNVSpaceName(uint32_t index, std::string* name) = 0;
    301 
    302   // This function returns the public area of an non-volatile space defined in
    303   // the TPM.
    304   virtual TPM_RC GetNVSpacePublicArea(uint32_t index,
    305                                       TPMS_NV_PUBLIC* public_data) = 0;
    306 
    307   // Lists all defined NV indexes.
    308   virtual TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) = 0;
    309 
    310   // Sets dictionary attack parameters. Requires lockout authorization.
    311   // Parameters map directly to TPM2_DictionaryAttackParameters in the TPM 2.0
    312   // specification.
    313   virtual TPM_RC SetDictionaryAttackParameters(
    314       uint32_t max_tries,
    315       uint32_t recovery_time,
    316       uint32_t lockout_recovery,
    317       AuthorizationDelegate* delegate) = 0;
    318 
    319   // Reset dictionary attack lockout. Requires lockout authorization.
    320   virtual TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) = 0;
    321 
    322  private:
    323   DISALLOW_COPY_AND_ASSIGN(TpmUtility);
    324 };
    325 
    326 }  // namespace trunks
    327 
    328 #endif  // TRUNKS_TPM_UTILITY_H_
    329