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