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 TpmUtility()45 TpmUtility() {} ~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