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