| // |
| // Copyright (C) 2014 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #ifndef TRUNKS_TPM_UTILITY_H_ |
| #define TRUNKS_TPM_UTILITY_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include <base/macros.h> |
| |
| #include "trunks/hmac_session.h" |
| #include "trunks/tpm_generated.h" |
| #include "trunks/trunks_export.h" |
| |
| namespace trunks { |
| |
| // These handles will be used by TpmUtility to create storage root keys. |
| const TPMI_DH_PERSISTENT kRSAStorageRootKey = PERSISTENT_FIRST; |
| const TPMI_DH_PERSISTENT kECCStorageRootKey = PERSISTENT_FIRST + 1; |
| const TPMI_DH_PERSISTENT kSaltingKey = PERSISTENT_FIRST + 2; |
| |
| // This value to used to specify that no pcr are needed in the creation data |
| // for a key. |
| const int kNoCreationPCR = -1; |
| |
| // An interface which provides convenient methods for common TPM operations. |
| class TRUNKS_EXPORT TpmUtility { |
| public: |
| enum AsymmetricKeyUsage { kDecryptKey, kSignKey, kDecryptAndSignKey }; |
| |
| TpmUtility() {} |
| virtual ~TpmUtility() {} |
| |
| // Synchronously performs a TPM startup sequence and self tests. Typically |
| // this is done by the platform firmware. Returns the result of the startup |
| // and self-tests or, if already started, just the result of the self-tests. |
| virtual TPM_RC Startup() = 0; |
| |
| // This method removes all TPM context associated with a specific Owner. |
| // As part of this process, it resets the SPS to a new random value, and |
| // clears ownerAuth, endorsementAuth and lockoutAuth. |
| // NOTE: This method needs to be called before InitializeTPM. |
| virtual TPM_RC Clear() = 0; |
| |
| // Synchronously performs a TPM shutdown operation. It should always be |
| // successful. |
| virtual void Shutdown() = 0; |
| |
| // Synchronously prepares a TPM for use by Chromium OS. Typically this is done |
| // by the platform firmware and, in that case, this method has no effect. |
| virtual TPM_RC InitializeTpm() = 0; |
| |
| // Synchronously allocates the PCRs in the TPM. Currently we allocate |
| // the first 16 PCRs to use the SHA-256 hash algorithm. |
| // NOTE: PCR allocation only takes place at the next TPM_Startup call. |
| // NOTE: This command needs platform authorization and PP assertion. |
| virtual TPM_RC AllocatePCR(const std::string& platform_password) = 0; |
| |
| // Synchronously takes ownership of the TPM with the given passwords as |
| // authorization values. |
| virtual TPM_RC TakeOwnership(const std::string& owner_password, |
| const std::string& endorsement_password, |
| const std::string& lockout_password) = 0; |
| |
| // Stir the tpm random generation module with some random entropy data. |
| // |delegate| specifies an optional authorization delegate to be used. |
| virtual TPM_RC StirRandom(const std::string& entropy_data, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method returns |num_bytes| of random data generated by the tpm. |
| // |delegate| specifies an optional authorization delegate to be used. |
| virtual TPM_RC GenerateRandom(size_t num_bytes, |
| AuthorizationDelegate* delegate, |
| std::string* random_data) = 0; |
| |
| // This method extends the pcr specified by |pcr_index| with the SHA256 |
| // hash of |extend_data|. The exact action performed is |
| // TPM2_PCR_Extend(Sha256(extend_data)); |
| // |delegate| specifies an optional authorization delegate to be used. |
| virtual TPM_RC ExtendPCR(int pcr_index, |
| const std::string& extend_data, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method reads the pcr specified by |pcr_index| and returns its value |
| // in |pcr_value|. NOTE: it assumes we are using SHA256 as our hash alg. |
| virtual TPM_RC ReadPCR(int pcr_index, std::string* pcr_value) = 0; |
| |
| // This method performs an encryption operation using a LOADED RSA key |
| // referrenced by its handle |key_handle|. The |plaintext| is then encrypted |
| // to give us the |ciphertext|. |scheme| refers to the encryption scheme |
| // to be used. By default keys use OAEP, but can also use TPM_ALG_RSAES. |
| // |delegate| specifies an optional authorization delegate to be used. |
| virtual TPM_RC AsymmetricEncrypt(TPM_HANDLE key_handle, |
| TPM_ALG_ID scheme, |
| TPM_ALG_ID hash_alg, |
| const std::string& plaintext, |
| AuthorizationDelegate* delegate, |
| std::string* ciphertext) = 0; |
| |
| // This method performs a decryption operating using a loaded RSA key |
| // referenced by its handle |key_handle|. The |ciphertext| is then decrypted |
| // to give us the |plaintext|. |scheme| refers to the decryption scheme |
| // used. By default it is OAEP, but TPM_ALG_RSAES can be specified. |
| // |delegate| is an AuthorizationDelegate used to authorize this command. |
| virtual TPM_RC AsymmetricDecrypt(TPM_HANDLE key_handle, |
| TPM_ALG_ID scheme, |
| TPM_ALG_ID hash_alg, |
| const std::string& ciphertext, |
| AuthorizationDelegate* delegate, |
| std::string* plaintext) = 0; |
| |
| // This method takes an unrestricted signing key referenced by |key_handle| |
| // and uses it to sign the hash of |plaintext|. The signature produced is |
| // returned using the |signature| argument. |scheme| is used to specify the |
| // signature scheme used. By default it is TPM_ALG_RSASSA, but TPM_ALG_RSAPPS |
| // can be specified. |hash_alg| is the algorithm used in the signing |
| // operation. It is by default TPM_ALG_SHA256. |
| // |delegate| is an AuthorizationDelegate used to authorize this command. |
| virtual TPM_RC Sign(TPM_HANDLE key_handle, |
| TPM_ALG_ID scheme, |
| TPM_ALG_ID hash_alg, |
| const std::string& plaintext, |
| AuthorizationDelegate* delegate, |
| std::string* signature) = 0; |
| |
| // This method verifies that the signature produced on the plaintext was |
| // performed by |key_handle|. |scheme| and |hash| refer to the signature |
| // scheme used to sign the hash of |plaintext| and produce the signature. |
| // This value is by default TPM_ALG_RSASSA with TPM_ALG_SHA256 but can take |
| // the value of TPM_ALG_RSAPPS with other hash algorithms supported by the |
| // tpm. Returns TPM_RC_SUCCESS when the signature is correct. |
| // |delegate| specifies an optional authorization delegate to be used. |
| virtual TPM_RC Verify(TPM_HANDLE key_handle, |
| TPM_ALG_ID scheme, |
| TPM_ALG_ID hash_alg, |
| const std::string& plaintext, |
| const std::string& signature, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method is used to check if a key was created in the TPM. |key_handle| |
| // refers to a loaded Tpm2.0 object, and |creation_blob| is the blob |
| // generated when the object was created. Returns TPM_RC_SUCCESS iff the |
| // object was created in the TPM. |
| virtual TPM_RC CertifyCreation(TPM_HANDLE key_handle, |
| const std::string& creation_blob) = 0; |
| |
| // This method is used to change the authorization value associated with a |
| // |key_handle| to |new_password|. |delegate| is an AuthorizationDelegate |
| // that is loaded with the old authorization value of |key_handle|. |
| // When |key_blob| is not null, it is populated with the new encrypted key |
| // blob. Note: the key must be unloaded and reloaded to use the |
| // new authorization value. |
| virtual TPM_RC ChangeKeyAuthorizationData(TPM_HANDLE key_handle, |
| const std::string& new_password, |
| AuthorizationDelegate* delegate, |
| std::string* key_blob) = 0; |
| |
| // This method imports an external RSA key of |key_type| into the TPM. |
| // |modulus| and |prime_factor| are interpreted as raw bytes in big-endian |
| // order. If the out argument |key_blob| is not null, it is populated with |
| // the imported key, which can then be loaded into the TPM. |
| virtual TPM_RC ImportRSAKey(AsymmetricKeyUsage key_type, |
| const std::string& modulus, |
| uint32_t public_exponent, |
| const std::string& prime_factor, |
| const std::string& password, |
| AuthorizationDelegate* delegate, |
| std::string* key_blob) = 0; |
| |
| // This method uses the TPM to generates an RSA key of type |key_type|. |
| // |modulus_bits| is used to specify the size of the modulus, and |
| // |public_exponent| specifies the exponent of the key. After this function |
| // terminates, |key_blob| contains a key blob that can be loaded into the TPM. |
| // |policy_digest| specifies an optional policy to use to authorize this key. |
| // |use_only_policy_authorization| specifies if we can use HmacSession in |
| // addition to PolicySession to authorize use of this key. |
| // |creation_pcr_index| allows the caller to specify a pcr value to include |
| // in the creation data. If no pcr are needed in the creation data, this |
| // argument can take the value of kNoCreationPCR. |
| // If the |creation_blob| out param is defined, it will contain the |
| // serialized creation structures generated by the TPM. |
| // This can be used to verify the state of the TPM during key creation. |
| // NOTE: if |use_only_policy_authorization| is set to true, |
| // parameter_encryption must be disabled when the key is used. |
| virtual TPM_RC CreateRSAKeyPair(AsymmetricKeyUsage key_type, |
| int modulus_bits, |
| uint32_t public_exponent, |
| const std::string& password, |
| const std::string& policy_digest, |
| bool use_only_policy_authorization, |
| int creation_pcr_index, |
| AuthorizationDelegate* delegate, |
| std::string* key_blob, |
| std::string* creation_blob) = 0; |
| |
| // This method loads a pregenerated TPM key into the TPM. |key_blob| contains |
| // the blob returned by a key creation function. The loaded key's handle is |
| // returned using |key_handle|. |
| virtual TPM_RC LoadKey(const std::string& key_blob, |
| AuthorizationDelegate* delegate, |
| TPM_HANDLE* key_handle) = 0; |
| |
| // This function sets |name| to the name of the object referenced by |
| // |handle|. This function only works on Transient and Permanent objects. |
| virtual TPM_RC GetKeyName(TPM_HANDLE handle, std::string* name) = 0; |
| |
| // This function returns the public area of a handle in the tpm. |
| virtual TPM_RC GetKeyPublicArea(TPM_HANDLE handle, |
| TPMT_PUBLIC* public_data) = 0; |
| |
| // This method seals |data_to_seal| to the TPM. The |sealed_data| can be |
| // retreived by fulfilling the policy represented by |policy_digest|. |
| virtual TPM_RC SealData(const std::string& data_to_seal, |
| const std::string& policy_digest, |
| AuthorizationDelegate* delegate, |
| std::string* sealed_data) = 0; |
| |
| // This method is used to retrieve data that was sealed to the TPM. |
| // |sealed_data| refers to sealed data returned from SealData. |
| virtual TPM_RC UnsealData(const std::string& sealed_data, |
| AuthorizationDelegate* delegate, |
| std::string* unsealed_data) = 0; |
| |
| // This method sets up a given HmacSession with parameter encryption set to |
| // true. Returns an TPM_RC_SUCCESS on success. |
| virtual TPM_RC StartSession(HmacSession* session) = 0; |
| |
| // This method uses a trial session to compute the |policy_digest| when |
| // the policy is bound to a given |pcr_value| at |pcr_index|. If |pcr_value| |
| // is the empty string, this method uses the currect value of the pcr. |
| virtual TPM_RC GetPolicyDigestForPcrValue(int pcr_index, |
| const std::string& pcr_value, |
| std::string* policy_digest) = 0; |
| |
| // This method defines a non-volatile storage area in the TPM, referenced |
| // by |index| of size |num_bytes|. This command needs owner authorization. |
| // The |attributes| of the space must be specified as a combination of |
| // TPMA_NV_* values. Optionally, an |authorization_value| and / or |
| // |policy_digest| can be specified which will be associated with the space. |
| // These values must either be a valid SHA256 digest (or empty). |
| virtual TPM_RC DefineNVSpace(uint32_t index, |
| size_t num_bytes, |
| TPMA_NV attributes, |
| const std::string& authorization_value, |
| const std::string& policy_digest, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method destroys the non-volatile space referred to by |index|. |
| // This command needs owner authorization. |
| virtual TPM_RC DestroyNVSpace(uint32_t index, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method locks the non-volatile space referred to by |index|. The caller |
| // needs indicate whether they want to |lock_read| and / or |lock_write|. They |
| // also need to indicate if they are |using_owner_authorization|. |
| virtual TPM_RC LockNVSpace(uint32_t index, |
| bool lock_read, |
| bool lock_write, |
| bool using_owner_authorization, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method writes |nvram_data| to the non-volatile space referenced by |
| // |index|, at |offset| bytes from the start of the non-volatile space. The |
| // caller needs to indicate if they are |using_owner_authorization|. If |
| // |extend| is set, the value will be extended and offset ignored. |
| virtual TPM_RC WriteNVSpace(uint32_t index, |
| uint32_t offset, |
| const std::string& nvram_data, |
| bool using_owner_authorization, |
| bool extend, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This method reads |num_bytes| of data from the |offset| located at the |
| // non-volatile space defined by |index|. This method returns an error if |
| // |length| + |offset| is larger than the size of the defined non-volatile |
| // space. The caller needs to indicate if they are |using_owner_authorization| |
| virtual TPM_RC ReadNVSpace(uint32_t index, |
| uint32_t offset, |
| size_t num_bytes, |
| bool using_owner_authorization, |
| std::string* nvram_data, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // This function sets |name| to the name of the non-volatile space referenced |
| // by |index|. |
| virtual TPM_RC GetNVSpaceName(uint32_t index, std::string* name) = 0; |
| |
| // This function returns the public area of an non-volatile space defined in |
| // the TPM. |
| virtual TPM_RC GetNVSpacePublicArea(uint32_t index, |
| TPMS_NV_PUBLIC* public_data) = 0; |
| |
| // Lists all defined NV indexes. |
| virtual TPM_RC ListNVSpaces(std::vector<uint32_t>* index_list) = 0; |
| |
| // Sets dictionary attack parameters. Requires lockout authorization. |
| // Parameters map directly to TPM2_DictionaryAttackParameters in the TPM 2.0 |
| // specification. |
| virtual TPM_RC SetDictionaryAttackParameters( |
| uint32_t max_tries, |
| uint32_t recovery_time, |
| uint32_t lockout_recovery, |
| AuthorizationDelegate* delegate) = 0; |
| |
| // Reset dictionary attack lockout. Requires lockout authorization. |
| virtual TPM_RC ResetDictionaryAttackLock(AuthorizationDelegate* delegate) = 0; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(TpmUtility); |
| }; |
| |
| } // namespace trunks |
| |
| #endif // TRUNKS_TPM_UTILITY_H_ |