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 #include "trunks/tpm_utility_impl.h"
18
19 #include <base/logging.h>
20 #include <base/memory/scoped_ptr.h>
21 #include <base/sha1.h>
22 #include <base/stl_util.h>
23 #include <crypto/openssl_util.h>
24 #include <crypto/secure_hash.h>
25 #include <crypto/sha2.h>
26 #include <openssl/aes.h>
27 #include <openssl/rand.h>
28
29 #include "trunks/authorization_delegate.h"
30 #include "trunks/blob_parser.h"
31 #include "trunks/error_codes.h"
32 #include "trunks/hmac_authorization_delegate.h"
33 #include "trunks/hmac_session.h"
34 #include "trunks/policy_session.h"
35 #include "trunks/scoped_key_handle.h"
36 #include "trunks/tpm_constants.h"
37 #include "trunks/tpm_state.h"
38 #include "trunks/trunks_factory.h"
39
40 namespace {
41
42 const char kPlatformPassword[] = "cros-platform";
43 const char kWellKnownPassword[] = "cros-password";
44 const size_t kMaxPasswordLength = 32;
45 // The below maximum is defined in TPM 2.0 Library Spec Part 2 Section 13.1
46 const uint32_t kMaxNVSpaceIndex = (1<<24) - 1;
47
48 // Returns a serialized representation of the unmodified handle. This is useful
49 // for predefined handle values, like TPM_RH_OWNER. For details on what types of
50 // handles use this name formula see Table 3 in the TPM 2.0 Library Spec Part 1
51 // (Section 16 - Names).
NameFromHandle(trunks::TPM_HANDLE handle)52 std::string NameFromHandle(trunks::TPM_HANDLE handle) {
53 std::string name;
54 trunks::Serialize_TPM_HANDLE(handle, &name);
55 return name;
56 }
57
HashString(const std::string & plaintext,trunks::TPM_ALG_ID hash_alg)58 std::string HashString(const std::string& plaintext,
59 trunks::TPM_ALG_ID hash_alg) {
60 switch (hash_alg) {
61 case trunks::TPM_ALG_SHA1:
62 return base::SHA1HashString(plaintext);
63 case trunks::TPM_ALG_SHA256:
64 return crypto::SHA256HashString(plaintext);
65 }
66 NOTREACHED();
67 return std::string();
68 }
69
70 } // namespace
71
72 namespace trunks {
73
TpmUtilityImpl(const TrunksFactory & factory)74 TpmUtilityImpl::TpmUtilityImpl(const TrunksFactory& factory)
75 : factory_(factory) {
76 crypto::EnsureOpenSSLInit();
77 }
78
~TpmUtilityImpl()79 TpmUtilityImpl::~TpmUtilityImpl() {
80 }
81
Startup()82 TPM_RC TpmUtilityImpl::Startup() {
83 TPM_RC result = TPM_RC_SUCCESS;
84 Tpm* tpm = factory_.GetTpm();
85 result = tpm->StartupSync(TPM_SU_CLEAR, nullptr);
86 // Ignore TPM_RC_INITIALIZE, that means it was already started.
87 if (result && result != TPM_RC_INITIALIZE) {
88 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
89 return result;
90 }
91 result = tpm->SelfTestSync(YES /* Full test. */, nullptr);
92 if (result) {
93 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
94 return result;
95 }
96 return TPM_RC_SUCCESS;
97 }
98
Clear()99 TPM_RC TpmUtilityImpl::Clear() {
100 TPM_RC result = TPM_RC_SUCCESS;
101 scoped_ptr<AuthorizationDelegate> password_delegate(
102 factory_.GetPasswordAuthorization(""));
103 result = factory_.GetTpm()->ClearSync(TPM_RH_PLATFORM,
104 NameFromHandle(TPM_RH_PLATFORM),
105 password_delegate.get());
106 // If there was an error in the initialization, platform auth is in a bad
107 // state.
108 if (result == TPM_RC_AUTH_MISSING) {
109 scoped_ptr<AuthorizationDelegate> authorization(
110 factory_.GetPasswordAuthorization(kPlatformPassword));
111 result = factory_.GetTpm()->ClearSync(TPM_RH_PLATFORM,
112 NameFromHandle(TPM_RH_PLATFORM),
113 authorization.get());
114 }
115 if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
116 LOG(INFO) << "Clear failed because of BAD_AUTH. This probably means "
117 << "that the TPM was already initialized.";
118 return result;
119 }
120 if (result) {
121 LOG(ERROR) << "Failed to clear the TPM: " << GetErrorString(result);
122 }
123 return result;
124 }
125
Shutdown()126 void TpmUtilityImpl::Shutdown() {
127 TPM_RC return_code = factory_.GetTpm()->ShutdownSync(TPM_SU_CLEAR, nullptr);
128 if (return_code && return_code != TPM_RC_INITIALIZE) {
129 // This should not happen, but if it does, there is nothing we can do.
130 LOG(ERROR) << "Error shutting down: " << GetErrorString(return_code);
131 }
132 }
133
InitializeTpm()134 TPM_RC TpmUtilityImpl::InitializeTpm() {
135 TPM_RC result = TPM_RC_SUCCESS;
136 scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
137 result = tpm_state->Initialize();
138 if (result) {
139 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
140 return result;
141 }
142 // Warn about various unexpected conditions.
143 if (!tpm_state->WasShutdownOrderly()) {
144 LOG(WARNING) << "WARNING: The last TPM shutdown was not orderly.";
145 }
146 if (tpm_state->IsInLockout()) {
147 LOG(WARNING) << "WARNING: The TPM is currently in lockout.";
148 }
149
150 // We expect the firmware has already locked down the platform hierarchy. If
151 // it hasn't, do it now.
152 if (tpm_state->IsPlatformHierarchyEnabled()) {
153 scoped_ptr<AuthorizationDelegate> empty_password(
154 factory_.GetPasswordAuthorization(""));
155 result = SetHierarchyAuthorization(TPM_RH_PLATFORM,
156 kPlatformPassword,
157 empty_password.get());
158 if (GetFormatOneError(result) == TPM_RC_BAD_AUTH) {
159 // Most likely the platform password has already been set.
160 result = TPM_RC_SUCCESS;
161 }
162 if (result != TPM_RC_SUCCESS) {
163 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
164 return result;
165 }
166 result = AllocatePCR(kPlatformPassword);
167 if (result != TPM_RC_SUCCESS) {
168 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
169 return result;
170 }
171 scoped_ptr<AuthorizationDelegate> authorization(
172 factory_.GetPasswordAuthorization(kPlatformPassword));
173 result = DisablePlatformHierarchy(authorization.get());
174 if (result != TPM_RC_SUCCESS) {
175 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
176 return result;
177 }
178 }
179 return TPM_RC_SUCCESS;
180 }
181
AllocatePCR(const std::string & platform_password)182 TPM_RC TpmUtilityImpl::AllocatePCR(const std::string& platform_password) {
183 TPM_RC result;
184 TPMI_YES_NO more_data = YES;
185 TPMS_CAPABILITY_DATA capability_data;
186 result = factory_.GetTpm()->GetCapabilitySync(
187 TPM_CAP_PCRS, 0 /*property (not used)*/, 1 /*property_count*/, &more_data,
188 &capability_data, nullptr /*authorization_delegate*/);
189 if (result != TPM_RC_SUCCESS) {
190 LOG(ERROR) << "Error querying PCRs: " << GetErrorString(result);
191 return result;
192 }
193 TPML_PCR_SELECTION& existing_pcrs = capability_data.data.assigned_pcr;
194 bool sha256_needed = true;
195 std::vector<TPMI_ALG_HASH> pcr_banks_to_remove;
196 for (uint32_t i = 0; i < existing_pcrs.count; ++i) {
197 if (existing_pcrs.pcr_selections[i].hash == TPM_ALG_SHA256) {
198 sha256_needed = false;
199 } else {
200 pcr_banks_to_remove.push_back(existing_pcrs.pcr_selections[i].hash);
201 }
202 }
203 if (!sha256_needed && pcr_banks_to_remove.empty()) {
204 return TPM_RC_SUCCESS;
205 }
206 TPML_PCR_SELECTION pcr_allocation;
207 memset(&pcr_allocation, 0, sizeof(pcr_allocation));
208 if (sha256_needed) {
209 pcr_allocation.pcr_selections[pcr_allocation.count].hash = TPM_ALG_SHA256;
210 pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
211 PCR_SELECT_MIN;
212 for (int i = 0; i < PCR_SELECT_MIN; ++i) {
213 pcr_allocation.pcr_selections[pcr_allocation.count].pcr_select[i] = 0xff;
214 }
215 ++pcr_allocation.count;
216 }
217 for (auto pcr_type : pcr_banks_to_remove) {
218 pcr_allocation.pcr_selections[pcr_allocation.count].hash = pcr_type;
219 pcr_allocation.pcr_selections[pcr_allocation.count].sizeof_select =
220 PCR_SELECT_MAX;
221 ++pcr_allocation.count;
222 }
223 scoped_ptr<AuthorizationDelegate> platform_delegate(
224 factory_.GetPasswordAuthorization(platform_password));
225 TPMI_YES_NO allocation_success;
226 uint32_t max_pcr;
227 uint32_t size_needed;
228 uint32_t size_available;
229 result = factory_.GetTpm()->PCR_AllocateSync(TPM_RH_PLATFORM,
230 NameFromHandle(TPM_RH_PLATFORM),
231 pcr_allocation,
232 &allocation_success,
233 &max_pcr,
234 &size_needed,
235 &size_available,
236 platform_delegate.get());
237 if (result != TPM_RC_SUCCESS) {
238 LOG(ERROR) << "Error allocating PCRs: " << GetErrorString(result);
239 return result;
240 }
241 if (allocation_success != YES) {
242 LOG(ERROR) << "PCR allocation unsuccessful.";
243 return TPM_RC_FAILURE;
244 }
245 return TPM_RC_SUCCESS;
246 }
247
TakeOwnership(const std::string & owner_password,const std::string & endorsement_password,const std::string & lockout_password)248 TPM_RC TpmUtilityImpl::TakeOwnership(const std::string& owner_password,
249 const std::string& endorsement_password,
250 const std::string& lockout_password) {
251 // First we set the storage hierarchy authorization to the well know default
252 // password.
253 TPM_RC result = TPM_RC_SUCCESS;
254 result = SetKnownOwnerPassword(kWellKnownPassword);
255 if (result != TPM_RC_SUCCESS) {
256 LOG(ERROR) << "Error injecting known password: " << GetErrorString(result);
257 return result;
258 }
259
260 result = CreateStorageRootKeys(kWellKnownPassword);
261 if (result) {
262 LOG(ERROR) << "Error creating SRKs: " << GetErrorString(result);
263 return result;
264 }
265 result = CreateSaltingKey(kWellKnownPassword);
266 if (result) {
267 LOG(ERROR) << "Error creating salting key: "
268 << GetErrorString(result);
269 return result;
270 }
271
272 scoped_ptr<HmacSession> session = factory_.GetHmacSession();
273 result = session->StartUnboundSession(true);
274 if (result != TPM_RC_SUCCESS) {
275 LOG(ERROR) << "Error initializing AuthorizationSession: "
276 << GetErrorString(result);
277 return result;
278 }
279 scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
280 result = tpm_state->Initialize();
281 session->SetEntityAuthorizationValue("");
282 session->SetFutureAuthorizationValue(endorsement_password);
283 if (!tpm_state->IsEndorsementPasswordSet()) {
284 result = SetHierarchyAuthorization(TPM_RH_ENDORSEMENT,
285 endorsement_password,
286 session->GetDelegate());
287 if (result) {
288 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
289 return result;
290 }
291 }
292 session->SetFutureAuthorizationValue(lockout_password);
293 if (!tpm_state->IsLockoutPasswordSet()) {
294 result = SetHierarchyAuthorization(TPM_RH_LOCKOUT,
295 lockout_password,
296 session->GetDelegate());
297 if (result) {
298 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
299 return result;
300 }
301 }
302 // We take ownership of owner hierarchy last.
303 session->SetEntityAuthorizationValue(kWellKnownPassword);
304 session->SetFutureAuthorizationValue(owner_password);
305 result = SetHierarchyAuthorization(TPM_RH_OWNER,
306 owner_password,
307 session->GetDelegate());
308 if ((GetFormatOneError(result) == TPM_RC_BAD_AUTH) &&
309 tpm_state->IsOwnerPasswordSet()) {
310 LOG(WARNING) << "Error changing owner password. This probably because "
311 << "ownership is already taken.";
312 return TPM_RC_SUCCESS;
313 } else if (result != TPM_RC_SUCCESS) {
314 LOG(ERROR) << "Error changing owner authorization: "
315 << GetErrorString(result);
316 return result;
317 }
318 return TPM_RC_SUCCESS;
319 }
320
StirRandom(const std::string & entropy_data,AuthorizationDelegate * delegate)321 TPM_RC TpmUtilityImpl::StirRandom(const std::string& entropy_data,
322 AuthorizationDelegate* delegate) {
323 std::string digest = crypto::SHA256HashString(entropy_data);
324 TPM2B_SENSITIVE_DATA random_bytes = Make_TPM2B_SENSITIVE_DATA(digest);
325 return factory_.GetTpm()->StirRandomSync(random_bytes, delegate);
326 }
327
GenerateRandom(size_t num_bytes,AuthorizationDelegate * delegate,std::string * random_data)328 TPM_RC TpmUtilityImpl::GenerateRandom(size_t num_bytes,
329 AuthorizationDelegate* delegate,
330 std::string* random_data) {
331 CHECK(random_data);
332 size_t bytes_left = num_bytes;
333 random_data->clear();
334 TPM_RC rc;
335 TPM2B_DIGEST digest;
336 while (bytes_left > 0) {
337 rc = factory_.GetTpm()->GetRandomSync(bytes_left,
338 &digest,
339 delegate);
340 if (rc) {
341 LOG(ERROR) << "Error getting random data from tpm.";
342 return rc;
343 }
344 random_data->append(StringFrom_TPM2B_DIGEST(digest));
345 bytes_left -= digest.size;
346 }
347 CHECK_EQ(random_data->size(), num_bytes);
348 return TPM_RC_SUCCESS;
349 }
350
ExtendPCR(int pcr_index,const std::string & extend_data,AuthorizationDelegate * delegate)351 TPM_RC TpmUtilityImpl::ExtendPCR(int pcr_index,
352 const std::string& extend_data,
353 AuthorizationDelegate* delegate) {
354 if (pcr_index < 0 || pcr_index >= IMPLEMENTATION_PCR) {
355 LOG(ERROR) << "Using a PCR index that isnt implemented.";
356 return TPM_RC_FAILURE;
357 }
358 TPM_HANDLE pcr_handle = HR_PCR + pcr_index;
359 std::string pcr_name = NameFromHandle(pcr_handle);
360 TPML_DIGEST_VALUES digests;
361 digests.count = 1;
362 digests.digests[0].hash_alg = TPM_ALG_SHA256;
363 crypto::SHA256HashString(extend_data,
364 digests.digests[0].digest.sha256,
365 crypto::kSHA256Length);
366 return factory_.GetTpm()->PCR_ExtendSync(pcr_handle,
367 pcr_name,
368 digests,
369 delegate);
370 }
371
ReadPCR(int pcr_index,std::string * pcr_value)372 TPM_RC TpmUtilityImpl::ReadPCR(int pcr_index, std::string* pcr_value) {
373 TPML_PCR_SELECTION pcr_select_in;
374 uint32_t pcr_update_counter;
375 TPML_PCR_SELECTION pcr_select_out;
376 TPML_DIGEST pcr_values;
377 // This process of selecting pcrs is highlighted in TPM 2.0 Library Spec
378 // Part 2 (Section 10.5 - PCR structures).
379 uint8_t pcr_select_index = pcr_index / 8;
380 uint8_t pcr_select_byte = 1 << (pcr_index % 8);
381 pcr_select_in.count = 1;
382 pcr_select_in.pcr_selections[0].hash = TPM_ALG_SHA256;
383 pcr_select_in.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
384 pcr_select_in.pcr_selections[0].pcr_select[pcr_select_index] =
385 pcr_select_byte;
386
387 TPM_RC rc = factory_.GetTpm()->PCR_ReadSync(pcr_select_in,
388 &pcr_update_counter,
389 &pcr_select_out,
390 &pcr_values,
391 nullptr);
392 if (rc) {
393 LOG(INFO) << "Error trying to read a pcr: " << GetErrorString(rc);
394 return rc;
395 }
396 if (pcr_select_out.count != 1 ||
397 pcr_select_out.pcr_selections[0].sizeof_select <
398 (pcr_select_index + 1) ||
399 pcr_select_out.pcr_selections[0].pcr_select[pcr_select_index] !=
400 pcr_select_byte) {
401 LOG(ERROR) << "TPM did not return the requested PCR";
402 return TPM_RC_FAILURE;
403 }
404 CHECK_GE(pcr_values.count, 1U);
405 pcr_value->assign(StringFrom_TPM2B_DIGEST(pcr_values.digests[0]));
406 return TPM_RC_SUCCESS;
407 }
408
AsymmetricEncrypt(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & plaintext,AuthorizationDelegate * delegate,std::string * ciphertext)409 TPM_RC TpmUtilityImpl::AsymmetricEncrypt(TPM_HANDLE key_handle,
410 TPM_ALG_ID scheme,
411 TPM_ALG_ID hash_alg,
412 const std::string& plaintext,
413 AuthorizationDelegate* delegate,
414 std::string* ciphertext) {
415 TPMT_RSA_DECRYPT in_scheme;
416 if (hash_alg == TPM_ALG_NULL) {
417 hash_alg = TPM_ALG_SHA256;
418 }
419 if (scheme == TPM_ALG_RSAES) {
420 in_scheme.scheme = TPM_ALG_RSAES;
421 } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) {
422 in_scheme.scheme = TPM_ALG_OAEP;
423 in_scheme.details.oaep.hash_alg = hash_alg;
424 } else {
425 LOG(ERROR) << "Invalid Signing scheme used.";
426 return SAPI_RC_BAD_PARAMETER;
427 }
428
429 TPMT_PUBLIC public_area;
430 TPM_RC result = GetKeyPublicArea(key_handle, &public_area);
431 if (result != TPM_RC_SUCCESS) {
432 LOG(ERROR) << "Error finding public area for: " << key_handle;
433 return result;
434 } else if (public_area.type != TPM_ALG_RSA) {
435 LOG(ERROR) << "Key handle given is not an RSA key";
436 return SAPI_RC_BAD_PARAMETER;
437 } else if ((public_area.object_attributes & kDecrypt) == 0) {
438 LOG(ERROR) << "Key handle given is not a decryption key";
439 return SAPI_RC_BAD_PARAMETER;
440 }
441 if ((public_area.object_attributes & kRestricted) != 0) {
442 LOG(ERROR) << "Cannot use RSAES for encryption with a restricted key";
443 return SAPI_RC_BAD_PARAMETER;
444 }
445 std::string key_name;
446 result = ComputeKeyName(public_area, &key_name);
447 if (result != TPM_RC_SUCCESS) {
448 LOG(ERROR) << "Error computing key name for: " << key_handle;
449 return result;
450 }
451
452 TPM2B_DATA label;
453 label.size = 0;
454 TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(plaintext);
455 TPM2B_PUBLIC_KEY_RSA out_message;
456 result = factory_.GetTpm()->RSA_EncryptSync(key_handle,
457 key_name,
458 in_message,
459 in_scheme,
460 label,
461 &out_message,
462 delegate);
463 if (result != TPM_RC_SUCCESS) {
464 LOG(ERROR) << "Error performing RSA encrypt: "
465 << GetErrorString(result);
466 return result;
467 }
468 ciphertext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
469 return TPM_RC_SUCCESS;
470 }
471
AsymmetricDecrypt(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & ciphertext,AuthorizationDelegate * delegate,std::string * plaintext)472 TPM_RC TpmUtilityImpl::AsymmetricDecrypt(TPM_HANDLE key_handle,
473 TPM_ALG_ID scheme,
474 TPM_ALG_ID hash_alg,
475 const std::string& ciphertext,
476 AuthorizationDelegate* delegate,
477 std::string* plaintext) {
478 TPMT_RSA_DECRYPT in_scheme;
479 if (hash_alg == TPM_ALG_NULL) {
480 hash_alg = TPM_ALG_SHA256;
481 }
482 if (scheme == TPM_ALG_RSAES) {
483 in_scheme.scheme = TPM_ALG_RSAES;
484 } else if (scheme == TPM_ALG_OAEP || scheme == TPM_ALG_NULL) {
485 in_scheme.scheme = TPM_ALG_OAEP;
486 in_scheme.details.oaep.hash_alg = hash_alg;
487 } else {
488 LOG(ERROR) << "Invalid Signing scheme used.";
489 return SAPI_RC_BAD_PARAMETER;
490 }
491 TPM_RC result;
492 if (delegate == nullptr) {
493 result = SAPI_RC_INVALID_SESSIONS;
494 LOG(ERROR) << "This method needs a valid authorization delegate: "
495 << GetErrorString(result);
496 return result;
497 }
498 TPMT_PUBLIC public_area;
499 result = GetKeyPublicArea(key_handle, &public_area);
500 if (result) {
501 LOG(ERROR) << "Error finding public area for: " << key_handle;
502 return result;
503 } else if (public_area.type != TPM_ALG_RSA) {
504 LOG(ERROR) << "Key handle given is not an RSA key";
505 return SAPI_RC_BAD_PARAMETER;
506 } else if ((public_area.object_attributes & kDecrypt) == 0) {
507 LOG(ERROR) << "Key handle given is not a decryption key";
508 return SAPI_RC_BAD_PARAMETER;
509 }
510 if ((public_area.object_attributes & kRestricted) != 0) {
511 LOG(ERROR) << "Cannot use RSAES for encryption with a restricted key";
512 return SAPI_RC_BAD_PARAMETER;
513 }
514 std::string key_name;
515 result = ComputeKeyName(public_area, &key_name);
516 if (result) {
517 LOG(ERROR) << "Error computing key name for: " << key_handle;
518 return result;
519 }
520
521 TPM2B_DATA label;
522 label.size = 0;
523 TPM2B_PUBLIC_KEY_RSA in_message = Make_TPM2B_PUBLIC_KEY_RSA(ciphertext);
524 TPM2B_PUBLIC_KEY_RSA out_message;
525 result = factory_.GetTpm()->RSA_DecryptSync(key_handle,
526 key_name,
527 in_message,
528 in_scheme,
529 label,
530 &out_message,
531 delegate);
532 if (result) {
533 LOG(ERROR) << "Error performing RSA decrypt: "
534 << GetErrorString(result);
535 return result;
536 }
537 plaintext->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(out_message));
538 return TPM_RC_SUCCESS;
539 }
540
Sign(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & plaintext,AuthorizationDelegate * delegate,std::string * signature)541 TPM_RC TpmUtilityImpl::Sign(TPM_HANDLE key_handle,
542 TPM_ALG_ID scheme,
543 TPM_ALG_ID hash_alg,
544 const std::string& plaintext,
545 AuthorizationDelegate* delegate,
546 std::string* signature) {
547 TPMT_SIG_SCHEME in_scheme;
548 if (hash_alg == TPM_ALG_NULL) {
549 hash_alg = TPM_ALG_SHA256;
550 }
551 if (scheme == TPM_ALG_RSAPSS) {
552 in_scheme.scheme = TPM_ALG_RSAPSS;
553 in_scheme.details.rsapss.hash_alg = hash_alg;
554 } else if (scheme == TPM_ALG_RSASSA || scheme == TPM_ALG_NULL) {
555 in_scheme.scheme = TPM_ALG_RSASSA;
556 in_scheme.details.rsassa.hash_alg = hash_alg;
557 } else {
558 LOG(ERROR) << "Invalid Signing scheme used.";
559 return SAPI_RC_BAD_PARAMETER;
560 }
561 TPM_RC result;
562 if (delegate == nullptr) {
563 result = SAPI_RC_INVALID_SESSIONS;
564 LOG(ERROR) << "This method needs a valid authorization delegate: "
565 << GetErrorString(result);
566 return result;
567 }
568 TPMT_PUBLIC public_area;
569 result = GetKeyPublicArea(key_handle, &public_area);
570 if (result) {
571 LOG(ERROR) << "Error finding public area for: " << key_handle;
572 return result;
573 } else if (public_area.type != TPM_ALG_RSA) {
574 LOG(ERROR) << "Key handle given is not an RSA key";
575 return SAPI_RC_BAD_PARAMETER;
576 } else if ((public_area.object_attributes & kSign) == 0) {
577 LOG(ERROR) << "Key handle given is not a signging key";
578 return SAPI_RC_BAD_PARAMETER;
579 } else if ((public_area.object_attributes & kRestricted) != 0) {
580 LOG(ERROR) << "Key handle references a restricted key";
581 return SAPI_RC_BAD_PARAMETER;
582 }
583
584 std::string key_name;
585 result = ComputeKeyName(public_area, &key_name);
586 if (result) {
587 LOG(ERROR) << "Error computing key name for: " << key_handle;
588 return result;
589 }
590 std::string digest = HashString(plaintext, hash_alg);
591 TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest);
592 TPMT_SIGNATURE signature_out;
593 TPMT_TK_HASHCHECK validation;
594 validation.tag = TPM_ST_HASHCHECK;
595 validation.hierarchy = TPM_RH_NULL;
596 validation.digest.size = 0;
597 result = factory_.GetTpm()->SignSync(key_handle,
598 key_name,
599 tpm_digest,
600 in_scheme,
601 validation,
602 &signature_out,
603 delegate);
604 if (result) {
605 LOG(ERROR) << "Error signing digest: " << GetErrorString(result);
606 return result;
607 }
608 if (scheme == TPM_ALG_RSAPSS) {
609 signature->resize(signature_out.signature.rsapss.sig.size);
610 signature->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(
611 signature_out.signature.rsapss.sig));
612 } else {
613 signature->resize(signature_out.signature.rsassa.sig.size);
614 signature->assign(StringFrom_TPM2B_PUBLIC_KEY_RSA(
615 signature_out.signature.rsassa.sig));
616 }
617 return TPM_RC_SUCCESS;
618 }
619
Verify(TPM_HANDLE key_handle,TPM_ALG_ID scheme,TPM_ALG_ID hash_alg,const std::string & plaintext,const std::string & signature,AuthorizationDelegate * delegate)620 TPM_RC TpmUtilityImpl::Verify(TPM_HANDLE key_handle,
621 TPM_ALG_ID scheme,
622 TPM_ALG_ID hash_alg,
623 const std::string& plaintext,
624 const std::string& signature,
625 AuthorizationDelegate* delegate) {
626 TPMT_PUBLIC public_area;
627 TPM_RC return_code = GetKeyPublicArea(key_handle, &public_area);
628 if (return_code) {
629 LOG(ERROR) << "Error finding public area for: " << key_handle;
630 return return_code;
631 } else if (public_area.type != TPM_ALG_RSA) {
632 LOG(ERROR) << "Key handle given is not an RSA key";
633 return SAPI_RC_BAD_PARAMETER;
634 } else if ((public_area.object_attributes & kSign) == 0) {
635 LOG(ERROR) << "Key handle given is not a signing key";
636 return SAPI_RC_BAD_PARAMETER;
637 } else if ((public_area.object_attributes & kRestricted) != 0) {
638 LOG(ERROR) << "Cannot use RSAPSS for signing with a restricted key";
639 return SAPI_RC_BAD_PARAMETER;
640 }
641 if (hash_alg == TPM_ALG_NULL) {
642 hash_alg = TPM_ALG_SHA256;
643 }
644
645 TPMT_SIGNATURE signature_in;
646 if (scheme == TPM_ALG_RSAPSS) {
647 signature_in.sig_alg = TPM_ALG_RSAPSS;
648 signature_in.signature.rsapss.hash = hash_alg;
649 signature_in.signature.rsapss.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature);
650 } else if (scheme == TPM_ALG_NULL || scheme == TPM_ALG_RSASSA) {
651 signature_in.sig_alg = TPM_ALG_RSASSA;
652 signature_in.signature.rsassa.hash = hash_alg;
653 signature_in.signature.rsassa.sig = Make_TPM2B_PUBLIC_KEY_RSA(signature);
654 } else {
655 LOG(ERROR) << "Invalid scheme used to verify signature.";
656 return SAPI_RC_BAD_PARAMETER;
657 }
658 std::string key_name;
659 TPMT_TK_VERIFIED verified;
660 std::string digest = HashString(plaintext, hash_alg);
661 TPM2B_DIGEST tpm_digest = Make_TPM2B_DIGEST(digest);
662 return_code = factory_.GetTpm()->VerifySignatureSync(key_handle,
663 key_name,
664 tpm_digest,
665 signature_in,
666 &verified,
667 delegate);
668 if (return_code == TPM_RC_SIGNATURE) {
669 LOG(WARNING) << "Incorrect signature for given digest.";
670 return TPM_RC_SIGNATURE;
671 } else if (return_code && return_code != TPM_RC_SIGNATURE) {
672 LOG(ERROR) << "Error verifying signature: " << GetErrorString(return_code);
673 return return_code;
674 }
675 return TPM_RC_SUCCESS;
676 }
677
CertifyCreation(TPM_HANDLE key_handle,const std::string & creation_blob)678 TPM_RC TpmUtilityImpl::CertifyCreation(TPM_HANDLE key_handle,
679 const std::string& creation_blob) {
680 TPM2B_CREATION_DATA creation_data;
681 TPM2B_DIGEST creation_hash;
682 TPMT_TK_CREATION creation_ticket;
683 if (!factory_.GetBlobParser()->ParseCreationBlob(creation_blob,
684 &creation_data,
685 &creation_hash,
686 &creation_ticket)) {
687 LOG(ERROR) << "Error parsing CreationBlob.";
688 return SAPI_RC_BAD_PARAMETER;
689 }
690 TPM2B_DATA qualifying_data;
691 qualifying_data.size = 0;
692 TPMT_SIG_SCHEME in_scheme;
693 in_scheme.scheme = TPM_ALG_NULL;
694 TPM2B_ATTEST certify_info;
695 TPMT_SIGNATURE signature;
696 scoped_ptr<AuthorizationDelegate> delegate =
697 factory_.GetPasswordAuthorization("");
698 TPM_RC result = factory_.GetTpm()->CertifyCreationSync(TPM_RH_NULL,
699 "",
700 key_handle,
701 "",
702 qualifying_data,
703 creation_hash,
704 in_scheme,
705 creation_ticket,
706 &certify_info,
707 &signature,
708 delegate.get());
709 if (result != TPM_RC_SUCCESS) {
710 LOG(ERROR) << "Error certifying key creation: " << GetErrorString(result);
711 return result;
712 }
713 return TPM_RC_SUCCESS;
714 }
715
ChangeKeyAuthorizationData(TPM_HANDLE key_handle,const std::string & new_password,AuthorizationDelegate * delegate,std::string * key_blob)716 TPM_RC TpmUtilityImpl::ChangeKeyAuthorizationData(
717 TPM_HANDLE key_handle,
718 const std::string& new_password,
719 AuthorizationDelegate* delegate,
720 std::string* key_blob) {
721 TPM_RC result;
722 if (delegate == nullptr) {
723 result = SAPI_RC_INVALID_SESSIONS;
724 LOG(ERROR) << "This method needs a valid authorization delegate: "
725 << GetErrorString(result);
726 return result;
727 }
728 std::string key_name;
729 std::string parent_name;
730 result = GetKeyName(key_handle, &key_name);
731 if (result != TPM_RC_SUCCESS) {
732 LOG(ERROR) << "Error getting Key name for key_handle: "
733 << GetErrorString(result);
734 return result;
735 }
736 result = GetKeyName(kRSAStorageRootKey, &parent_name);
737 if (result != TPM_RC_SUCCESS) {
738 LOG(ERROR) << "Error getting Key name for RSA-SRK: "
739 << GetErrorString(result);
740 return result;
741 }
742 TPM2B_AUTH new_auth = Make_TPM2B_DIGEST(new_password);
743 TPM2B_PRIVATE new_private_data;
744 new_private_data.size = 0;
745 result = factory_.GetTpm()->ObjectChangeAuthSync(key_handle,
746 key_name,
747 kRSAStorageRootKey,
748 parent_name,
749 new_auth,
750 &new_private_data,
751 delegate);
752 if (result != TPM_RC_SUCCESS) {
753 LOG(ERROR) << "Error changing object authorization data: "
754 << GetErrorString(result);
755 return result;
756 }
757 if (key_blob) {
758 TPMT_PUBLIC public_data;
759 result = GetKeyPublicArea(key_handle, &public_data);
760 if (result != TPM_RC_SUCCESS) {
761 return result;
762 }
763 if (!factory_.GetBlobParser()->SerializeKeyBlob(
764 Make_TPM2B_PUBLIC(public_data), new_private_data, key_blob)) {
765 return SAPI_RC_BAD_TCTI_STRUCTURE;
766 }
767 }
768 return TPM_RC_SUCCESS;
769 }
770
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)771 TPM_RC TpmUtilityImpl::ImportRSAKey(AsymmetricKeyUsage key_type,
772 const std::string& modulus,
773 uint32_t public_exponent,
774 const std::string& prime_factor,
775 const std::string& password,
776 AuthorizationDelegate* delegate,
777 std::string* key_blob) {
778 TPM_RC result;
779 if (delegate == nullptr) {
780 result = SAPI_RC_INVALID_SESSIONS;
781 LOG(ERROR) << "This method needs a valid authorization delegate: "
782 << GetErrorString(result);
783 return result;
784 }
785 std::string parent_name;
786 result = GetKeyName(kRSAStorageRootKey, &parent_name);
787 if (result != TPM_RC_SUCCESS) {
788 LOG(ERROR) << "Error getting Key name for RSA-SRK: "
789 << GetErrorString(result);
790 return result;
791 }
792 TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
793 public_area.object_attributes = kUserWithAuth | kNoDA;
794 switch (key_type) {
795 case AsymmetricKeyUsage::kDecryptKey:
796 public_area.object_attributes |= kDecrypt;
797 break;
798 case AsymmetricKeyUsage::kSignKey:
799 public_area.object_attributes |= kSign;
800 break;
801 case AsymmetricKeyUsage::kDecryptAndSignKey:
802 public_area.object_attributes |= (kSign | kDecrypt);
803 break;
804 }
805 public_area.parameters.rsa_detail.key_bits = modulus.size() * 8;
806 public_area.parameters.rsa_detail.exponent = public_exponent;
807 public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA(modulus);
808 TPM2B_DATA encryption_key;
809 encryption_key.size = kAesKeySize;
810 CHECK_EQ(RAND_bytes(encryption_key.buffer, encryption_key.size), 1) <<
811 "Error generating a cryptographically random Aes Key.";
812 TPM2B_PUBLIC public_data = Make_TPM2B_PUBLIC(public_area);
813 TPM2B_ENCRYPTED_SECRET in_sym_seed = Make_TPM2B_ENCRYPTED_SECRET("");
814 TPMT_SYM_DEF_OBJECT symmetric_alg;
815 symmetric_alg.algorithm = TPM_ALG_AES;
816 symmetric_alg.key_bits.aes = kAesKeySize * 8;
817 symmetric_alg.mode.aes = TPM_ALG_CFB;
818 TPMT_SENSITIVE in_sensitive;
819 in_sensitive.sensitive_type = TPM_ALG_RSA;
820 in_sensitive.auth_value = Make_TPM2B_DIGEST(password);
821 in_sensitive.seed_value = Make_TPM2B_DIGEST("");
822 in_sensitive.sensitive.rsa = Make_TPM2B_PRIVATE_KEY_RSA(prime_factor);
823 TPM2B_PRIVATE private_data;
824 result = EncryptPrivateData(in_sensitive, public_area,
825 &private_data, &encryption_key);
826 if (result != TPM_RC_SUCCESS) {
827 LOG(ERROR) << "Error creating encrypted private struct: "
828 << GetErrorString(result);
829 return result;
830 }
831 TPM2B_PRIVATE tpm_private_data;
832 tpm_private_data.size = 0;
833 result = factory_.GetTpm()->ImportSync(kRSAStorageRootKey,
834 parent_name,
835 encryption_key,
836 public_data,
837 private_data,
838 in_sym_seed,
839 symmetric_alg,
840 &tpm_private_data,
841 delegate);
842 if (result != TPM_RC_SUCCESS) {
843 LOG(ERROR) << "Error importing key: " << GetErrorString(result);
844 return result;
845 }
846 if (key_blob) {
847 if (!factory_.GetBlobParser()->SerializeKeyBlob(
848 public_data, tpm_private_data, key_blob)) {
849 return SAPI_RC_BAD_TCTI_STRUCTURE;
850 }
851 }
852 return TPM_RC_SUCCESS;
853 }
854
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)855 TPM_RC TpmUtilityImpl::CreateRSAKeyPair(AsymmetricKeyUsage key_type,
856 int modulus_bits,
857 uint32_t public_exponent,
858 const std::string& password,
859 const std::string& policy_digest,
860 bool use_only_policy_authorization,
861 int creation_pcr_index,
862 AuthorizationDelegate* delegate,
863 std::string* key_blob,
864 std::string* creation_blob) {
865 CHECK(key_blob);
866 TPM_RC result;
867 if (delegate == nullptr) {
868 result = SAPI_RC_INVALID_SESSIONS;
869 LOG(ERROR) << "This method needs a valid authorization delegate: "
870 << GetErrorString(result);
871 return result;
872 }
873 std::string parent_name;
874 result = GetKeyName(kRSAStorageRootKey, &parent_name);
875 if (result != TPM_RC_SUCCESS) {
876 LOG(ERROR) << "Error getting Key name for RSA-SRK: "
877 << GetErrorString(result);
878 return result;
879 }
880 TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
881 public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest);
882 public_area.object_attributes |=
883 (kSensitiveDataOrigin | kUserWithAuth | kNoDA);
884 switch (key_type) {
885 case AsymmetricKeyUsage::kDecryptKey:
886 public_area.object_attributes |= kDecrypt;
887 break;
888 case AsymmetricKeyUsage::kSignKey:
889 public_area.object_attributes |= kSign;
890 break;
891 case AsymmetricKeyUsage::kDecryptAndSignKey:
892 public_area.object_attributes |= (kSign | kDecrypt);
893 break;
894 }
895 if (use_only_policy_authorization && !policy_digest.empty()) {
896 public_area.object_attributes |= kAdminWithPolicy;
897 public_area.object_attributes &= (~kUserWithAuth);
898 }
899 public_area.parameters.rsa_detail.key_bits = modulus_bits;
900 public_area.parameters.rsa_detail.exponent = public_exponent;
901 TPML_PCR_SELECTION creation_pcrs = {};
902 if (creation_pcr_index == kNoCreationPCR) {
903 creation_pcrs.count = 0;
904 } else if (creation_pcr_index < 0 ||
905 creation_pcr_index > (PCR_SELECT_MIN * 8)) {
906 LOG(ERROR) << "Creation PCR index is not within the allocated bank.";
907 return SAPI_RC_BAD_PARAMETER;
908 } else {
909 creation_pcrs.count = 1;
910 creation_pcrs.pcr_selections[0].hash = TPM_ALG_SHA256;
911 creation_pcrs.pcr_selections[0].sizeof_select = PCR_SELECT_MIN;
912 creation_pcrs.pcr_selections[0].pcr_select[creation_pcr_index / 8] =
913 1 << (creation_pcr_index % 8);
914 }
915 TPMS_SENSITIVE_CREATE sensitive;
916 sensitive.user_auth = Make_TPM2B_DIGEST(password);
917 sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
918 TPM2B_SENSITIVE_CREATE sensitive_create = Make_TPM2B_SENSITIVE_CREATE(
919 sensitive);
920 TPM2B_DATA outside_info = Make_TPM2B_DATA("");
921 TPM2B_PUBLIC out_public;
922 out_public.size = 0;
923 TPM2B_PRIVATE out_private;
924 out_private.size = 0;
925 TPM2B_CREATION_DATA creation_data;
926 TPM2B_DIGEST creation_hash;
927 TPMT_TK_CREATION creation_ticket;
928 result = factory_.GetTpm()->CreateSync(kRSAStorageRootKey,
929 parent_name,
930 sensitive_create,
931 Make_TPM2B_PUBLIC(public_area),
932 outside_info,
933 creation_pcrs,
934 &out_private,
935 &out_public,
936 &creation_data,
937 &creation_hash,
938 &creation_ticket,
939 delegate);
940 if (result != TPM_RC_SUCCESS) {
941 LOG(ERROR) << "Error creating RSA key: " << GetErrorString(result);
942 return result;
943 }
944 if (!factory_.GetBlobParser()->SerializeKeyBlob(
945 out_public, out_private, key_blob)) {
946 return SAPI_RC_BAD_TCTI_STRUCTURE;
947 }
948 if (creation_blob) {
949 if (!factory_.GetBlobParser()->SerializeCreationBlob(
950 creation_data, creation_hash, creation_ticket, creation_blob)) {
951 return SAPI_RC_BAD_TCTI_STRUCTURE;
952 }
953 }
954 return TPM_RC_SUCCESS;
955 }
956
LoadKey(const std::string & key_blob,AuthorizationDelegate * delegate,TPM_HANDLE * key_handle)957 TPM_RC TpmUtilityImpl::LoadKey(const std::string& key_blob,
958 AuthorizationDelegate* delegate,
959 TPM_HANDLE* key_handle) {
960 CHECK(key_handle);
961 TPM_RC result;
962 if (delegate == nullptr) {
963 result = SAPI_RC_INVALID_SESSIONS;
964 LOG(ERROR) << "This method needs a valid authorization delegate: "
965 << GetErrorString(result);
966 return result;
967 }
968 std::string parent_name;
969 result = GetKeyName(kRSAStorageRootKey, &parent_name);
970 if (result != TPM_RC_SUCCESS) {
971 LOG(ERROR) << "Error getting parent key name: " << GetErrorString(result);
972 return result;
973 }
974 TPM2B_PUBLIC in_public;
975 TPM2B_PRIVATE in_private;
976 if (!factory_.GetBlobParser()->ParseKeyBlob(
977 key_blob, &in_public, &in_private)) {
978 return SAPI_RC_BAD_TCTI_STRUCTURE;
979 }
980 TPM2B_NAME key_name;
981 key_name.size = 0;
982 result = factory_.GetTpm()->LoadSync(kRSAStorageRootKey,
983 parent_name,
984 in_private,
985 in_public,
986 key_handle,
987 &key_name,
988 delegate);
989 if (result != TPM_RC_SUCCESS) {
990 LOG(ERROR) << "Error loading key: " << GetErrorString(result);
991 return result;
992 }
993 return TPM_RC_SUCCESS;
994 }
995
GetKeyName(TPM_HANDLE handle,std::string * name)996 TPM_RC TpmUtilityImpl::GetKeyName(TPM_HANDLE handle, std::string* name) {
997 CHECK(name);
998 TPM_RC result;
999 TPMT_PUBLIC public_data;
1000 result = GetKeyPublicArea(handle, &public_data);
1001 if (result != TPM_RC_SUCCESS) {
1002 LOG(ERROR) << "Error fetching public info: " << GetErrorString(result);
1003 return result;
1004 }
1005 result = ComputeKeyName(public_data, name);
1006 if (result != TPM_RC_SUCCESS) {
1007 LOG(ERROR) << "Error computing key name: " << GetErrorString(result);
1008 return TPM_RC_SUCCESS;
1009 }
1010 return TPM_RC_SUCCESS;
1011 }
1012
GetKeyPublicArea(TPM_HANDLE handle,TPMT_PUBLIC * public_data)1013 TPM_RC TpmUtilityImpl::GetKeyPublicArea(TPM_HANDLE handle,
1014 TPMT_PUBLIC* public_data) {
1015 CHECK(public_data);
1016 TPM2B_NAME out_name;
1017 TPM2B_PUBLIC public_area;
1018 TPM2B_NAME qualified_name;
1019 std::string handle_name; // Unused
1020 TPM_RC return_code = factory_.GetTpm()->ReadPublicSync(handle,
1021 handle_name,
1022 &public_area,
1023 &out_name,
1024 &qualified_name,
1025 nullptr);
1026 if (return_code) {
1027 LOG(ERROR) << "Error getting public area for object: " << handle;
1028 return return_code;
1029 }
1030 *public_data = public_area.public_area;
1031 return TPM_RC_SUCCESS;
1032 }
1033
SealData(const std::string & data_to_seal,const std::string & policy_digest,AuthorizationDelegate * delegate,std::string * sealed_data)1034 TPM_RC TpmUtilityImpl::SealData(const std::string& data_to_seal,
1035 const std::string& policy_digest,
1036 AuthorizationDelegate* delegate,
1037 std::string* sealed_data) {
1038 CHECK(sealed_data);
1039 TPM_RC result;
1040 if (delegate == nullptr) {
1041 result = SAPI_RC_INVALID_SESSIONS;
1042 LOG(ERROR) << "This method needs a valid authorization delegate: "
1043 << GetErrorString(result);
1044 return result;
1045 }
1046 std::string parent_name;
1047 result = GetKeyName(kRSAStorageRootKey, &parent_name);
1048 if (result != TPM_RC_SUCCESS) {
1049 LOG(ERROR) << "Error getting Key name for RSA-SRK: "
1050 << GetErrorString(result);
1051 return result;
1052 }
1053 // We seal data to the TPM by creating a KEYEDHASH object with sign and
1054 // decrypt attributes disabled.
1055 TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_KEYEDHASH);
1056 public_area.auth_policy = Make_TPM2B_DIGEST(policy_digest);
1057 public_area.object_attributes = kAdminWithPolicy | kNoDA;
1058 public_area.unique.keyed_hash.size = 0;
1059 TPML_PCR_SELECTION creation_pcrs = {};
1060 TPMS_SENSITIVE_CREATE sensitive;
1061 sensitive.user_auth = Make_TPM2B_DIGEST("");
1062 sensitive.data = Make_TPM2B_SENSITIVE_DATA(data_to_seal);
1063 TPM2B_SENSITIVE_CREATE sensitive_create = Make_TPM2B_SENSITIVE_CREATE(
1064 sensitive);
1065 TPM2B_DATA outside_info = Make_TPM2B_DATA("");
1066 TPM2B_PUBLIC out_public;
1067 out_public.size = 0;
1068 TPM2B_PRIVATE out_private;
1069 out_private.size = 0;
1070 TPM2B_CREATION_DATA creation_data;
1071 TPM2B_DIGEST creation_hash;
1072 TPMT_TK_CREATION creation_ticket;
1073 result = factory_.GetTpm()->CreateSync(kRSAStorageRootKey,
1074 parent_name,
1075 sensitive_create,
1076 Make_TPM2B_PUBLIC(public_area),
1077 outside_info,
1078 creation_pcrs,
1079 &out_private,
1080 &out_public,
1081 &creation_data,
1082 &creation_hash,
1083 &creation_ticket,
1084 delegate);
1085 if (result != TPM_RC_SUCCESS) {
1086 LOG(ERROR) << "Error creating sealed object: " << GetErrorString(result);
1087 return result;
1088 }
1089 if (!factory_.GetBlobParser()->SerializeKeyBlob(
1090 out_public, out_private, sealed_data)) {
1091 return SAPI_RC_BAD_TCTI_STRUCTURE;
1092 }
1093 return TPM_RC_SUCCESS;
1094 }
1095
UnsealData(const std::string & sealed_data,AuthorizationDelegate * delegate,std::string * unsealed_data)1096 TPM_RC TpmUtilityImpl::UnsealData(const std::string& sealed_data,
1097 AuthorizationDelegate* delegate,
1098 std::string* unsealed_data) {
1099 CHECK(unsealed_data);
1100 TPM_RC result;
1101 if (delegate == nullptr) {
1102 result = SAPI_RC_INVALID_SESSIONS;
1103 LOG(ERROR) << "This method needs a valid authorization delegate: "
1104 << GetErrorString(result);
1105 return result;
1106 }
1107 TPM_HANDLE object_handle;
1108 scoped_ptr<AuthorizationDelegate> password_delegate =
1109 factory_.GetPasswordAuthorization("");
1110 result = LoadKey(sealed_data, password_delegate.get(), &object_handle);
1111 if (result != TPM_RC_SUCCESS) {
1112 LOG(ERROR) << "Error loading sealed object: " << GetErrorString(result);
1113 return result;
1114 }
1115 ScopedKeyHandle sealed_object(factory_, object_handle);
1116 std::string object_name;
1117 result = GetKeyName(sealed_object.get(), &object_name);
1118 if (result != TPM_RC_SUCCESS) {
1119 LOG(ERROR) << "Error getting object name: " << GetErrorString(result);
1120 return result;
1121 }
1122 TPM2B_SENSITIVE_DATA out_data;
1123 result = factory_.GetTpm()->UnsealSync(sealed_object.get(), object_name,
1124 &out_data, delegate);
1125 if (result != TPM_RC_SUCCESS) {
1126 LOG(ERROR) << "Error unsealing object: " << GetErrorString(result);
1127 return result;
1128 }
1129 *unsealed_data = StringFrom_TPM2B_SENSITIVE_DATA(out_data);
1130 return TPM_RC_SUCCESS;
1131 }
1132
StartSession(HmacSession * session)1133 TPM_RC TpmUtilityImpl::StartSession(HmacSession* session) {
1134 TPM_RC result = session->StartUnboundSession(true /* enable_encryption */);
1135 if (result != TPM_RC_SUCCESS) {
1136 LOG(ERROR) << "Error starting unbound session: " << GetErrorString(result);
1137 return result;
1138 }
1139 session->SetEntityAuthorizationValue("");
1140 return TPM_RC_SUCCESS;
1141 }
1142
GetPolicyDigestForPcrValue(int pcr_index,const std::string & pcr_value,std::string * policy_digest)1143 TPM_RC TpmUtilityImpl::GetPolicyDigestForPcrValue(int pcr_index,
1144 const std::string& pcr_value,
1145 std::string* policy_digest) {
1146 CHECK(policy_digest);
1147 scoped_ptr<PolicySession> session = factory_.GetTrialSession();
1148 TPM_RC result = session->StartUnboundSession(false);
1149 if (result != TPM_RC_SUCCESS) {
1150 LOG(ERROR) << "Error starting unbound trial session: "
1151 << GetErrorString(result);
1152 return result;
1153 }
1154 std::string mutable_pcr_value;
1155 if (pcr_value.empty()) {
1156 result = ReadPCR(pcr_index, &mutable_pcr_value);
1157 if (result != TPM_RC_SUCCESS) {
1158 LOG(ERROR) << "Error reading pcr_value: " << GetErrorString(result);
1159 return result;
1160 }
1161 } else {
1162 mutable_pcr_value = pcr_value;
1163 }
1164 result = session->PolicyPCR(pcr_index, mutable_pcr_value);
1165 if (result != TPM_RC_SUCCESS) {
1166 LOG(ERROR) << "Error restricting policy to PCR value: "
1167 << GetErrorString(result);
1168 return result;
1169 }
1170 result = session->GetDigest(policy_digest);
1171 if (result != TPM_RC_SUCCESS) {
1172 LOG(ERROR) << "Error getting policy digest: " << GetErrorString(result);
1173 return result;
1174 }
1175 return TPM_RC_SUCCESS;
1176 }
1177
DefineNVSpace(uint32_t index,size_t num_bytes,AuthorizationDelegate * delegate)1178 TPM_RC TpmUtilityImpl::DefineNVSpace(uint32_t index,
1179 size_t num_bytes,
1180 AuthorizationDelegate* delegate) {
1181 TPM_RC result;
1182 if (num_bytes > MAX_NV_INDEX_SIZE) {
1183 result = SAPI_RC_BAD_SIZE;
1184 LOG(ERROR) << "Cannot define non-volatile space of given size: "
1185 << GetErrorString(result);
1186 return result;
1187 }
1188 if (index > kMaxNVSpaceIndex) {
1189 result = SAPI_RC_BAD_PARAMETER;
1190 LOG(ERROR) << "Cannot define non-volatile space with the given index: "
1191 << GetErrorString(result);
1192 return result;
1193 }
1194 if (delegate == nullptr) {
1195 result = SAPI_RC_INVALID_SESSIONS;
1196 LOG(ERROR) << "This method needs a valid authorization delegate: "
1197 << GetErrorString(result);
1198 return result;
1199 }
1200 uint32_t nv_index = NV_INDEX_FIRST + index;
1201 TPMS_NV_PUBLIC public_data;
1202 public_data.nv_index = nv_index;
1203 public_data.name_alg = TPM_ALG_SHA256;
1204 // We define the following attributes for NVSpaces created:
1205 // TPMA_NV_NO_DA: Dictionary attack does not trigger on authorization errors.
1206 // TPMA_NV_OWNERWRITE: Owner authorization must be provided on write actions.
1207 // TPMA_NV_WRITEDEFINE: NVSpace is write lockable, and lock persists across
1208 // reboot.
1209 // TPMA_NV_AUTHREAD: The index authValue (default: "") can be used to
1210 // authorize read actions.
1211 public_data.attributes = TPMA_NV_NO_DA |
1212 TPMA_NV_OWNERWRITE |
1213 TPMA_NV_WRITEDEFINE |
1214 TPMA_NV_AUTHREAD;
1215 public_data.auth_policy = Make_TPM2B_DIGEST("");
1216 public_data.data_size = num_bytes;
1217 TPM2B_AUTH authorization = Make_TPM2B_DIGEST("");
1218 TPM2B_NV_PUBLIC public_area = Make_TPM2B_NV_PUBLIC(public_data);
1219 result = factory_.GetTpm()->NV_DefineSpaceSync(
1220 TPM_RH_OWNER,
1221 NameFromHandle(TPM_RH_OWNER),
1222 authorization,
1223 public_area,
1224 delegate);
1225 if (result != TPM_RC_SUCCESS) {
1226 LOG(ERROR) << "Error defining non-volatile space: "
1227 << GetErrorString(result);
1228 return result;
1229 }
1230 nvram_public_area_map_[index] = public_data;
1231 return TPM_RC_SUCCESS;
1232 }
1233
DestroyNVSpace(uint32_t index,AuthorizationDelegate * delegate)1234 TPM_RC TpmUtilityImpl::DestroyNVSpace(uint32_t index,
1235 AuthorizationDelegate* delegate) {
1236 TPM_RC result;
1237 if (index > kMaxNVSpaceIndex) {
1238 result = SAPI_RC_BAD_PARAMETER;
1239 LOG(ERROR) << "Cannot undefine non-volatile space with the given index: "
1240 << GetErrorString(result);
1241 return result;
1242 }
1243 if (delegate == nullptr) {
1244 result = SAPI_RC_INVALID_SESSIONS;
1245 LOG(ERROR) << "This method needs a valid authorization delegate: "
1246 << GetErrorString(result);
1247 return result;
1248 }
1249 std::string nv_name;
1250 result = GetNVSpaceName(index, &nv_name);
1251 if (result != TPM_RC_SUCCESS) {
1252 return result;
1253 }
1254 uint32_t nv_index = NV_INDEX_FIRST + index;
1255 result = factory_.GetTpm()->NV_UndefineSpaceSync(
1256 TPM_RH_OWNER,
1257 NameFromHandle(TPM_RH_OWNER),
1258 nv_index,
1259 nv_name,
1260 delegate);
1261 if (result != TPM_RC_SUCCESS) {
1262 LOG(ERROR) << "Error undefining non-volatile space: "
1263 << GetErrorString(result);
1264 return result;
1265 }
1266 nvram_public_area_map_.erase(index);
1267 return TPM_RC_SUCCESS;
1268 }
1269
LockNVSpace(uint32_t index,AuthorizationDelegate * delegate)1270 TPM_RC TpmUtilityImpl::LockNVSpace(uint32_t index,
1271 AuthorizationDelegate* delegate) {
1272 TPM_RC result;
1273 if (index > kMaxNVSpaceIndex) {
1274 result = SAPI_RC_BAD_PARAMETER;
1275 LOG(ERROR) << "Cannot lock non-volatile space with the given index: "
1276 << GetErrorString(result);
1277 return result;
1278 }
1279 if (delegate == nullptr) {
1280 result = SAPI_RC_INVALID_SESSIONS;
1281 LOG(ERROR) << "This method needs a valid authorization delegate: "
1282 << GetErrorString(result);
1283 return result;
1284 }
1285 std::string nv_name;
1286 result = GetNVSpaceName(index, &nv_name);
1287 if (result != TPM_RC_SUCCESS) {
1288 return result;
1289 }
1290 uint32_t nv_index = NV_INDEX_FIRST + index;
1291 result = factory_.GetTpm()->NV_WriteLockSync(TPM_RH_OWNER,
1292 NameFromHandle(TPM_RH_OWNER),
1293 nv_index,
1294 nv_name,
1295 delegate);
1296 if (result != TPM_RC_SUCCESS) {
1297 LOG(ERROR) << "Error locking non-volatile spaces: "
1298 << GetErrorString(result);
1299 return result;
1300 }
1301 auto it = nvram_public_area_map_.find(index);
1302 if (it != nvram_public_area_map_.end()) {
1303 it->second.attributes |= TPMA_NV_WRITELOCKED;
1304 }
1305 return TPM_RC_SUCCESS;
1306 }
1307
WriteNVSpace(uint32_t index,uint32_t offset,const std::string & nvram_data,AuthorizationDelegate * delegate)1308 TPM_RC TpmUtilityImpl::WriteNVSpace(uint32_t index,
1309 uint32_t offset,
1310 const std::string& nvram_data,
1311 AuthorizationDelegate* delegate) {
1312 TPM_RC result;
1313 if (nvram_data.size() > MAX_NV_BUFFER_SIZE) {
1314 result = SAPI_RC_BAD_SIZE;
1315 LOG(ERROR) << "Insufficient buffer for non-volatile write: "
1316 << GetErrorString(result);
1317 return result;
1318 }
1319 if (index > kMaxNVSpaceIndex) {
1320 result = SAPI_RC_BAD_PARAMETER;
1321 LOG(ERROR) << "Cannot write to non-volatile space with the given index: "
1322 << GetErrorString(result);
1323 return result;
1324 }
1325 if (delegate == nullptr) {
1326 result = SAPI_RC_INVALID_SESSIONS;
1327 LOG(ERROR) << "This method needs a valid authorization delegate: "
1328 << GetErrorString(result);
1329 return result;
1330 }
1331 std::string nv_name;
1332 result = GetNVSpaceName(index, &nv_name);
1333 if (result != TPM_RC_SUCCESS) {
1334 return result;
1335 }
1336 uint32_t nv_index = NV_INDEX_FIRST + index;
1337 result = factory_.GetTpm()->NV_WriteSync(TPM_RH_OWNER,
1338 NameFromHandle(TPM_RH_OWNER),
1339 nv_index,
1340 nv_name,
1341 Make_TPM2B_MAX_NV_BUFFER(nvram_data),
1342 offset,
1343 delegate);
1344 if (result != TPM_RC_SUCCESS) {
1345 LOG(ERROR) << "Error writing to non-volatile space: "
1346 << GetErrorString(result);
1347 return result;
1348 }
1349 auto it = nvram_public_area_map_.find(index);
1350 if (it != nvram_public_area_map_.end()) {
1351 it->second.attributes |= TPMA_NV_WRITTEN;
1352 }
1353 return TPM_RC_SUCCESS;
1354 }
1355
ReadNVSpace(uint32_t index,uint32_t offset,size_t num_bytes,std::string * nvram_data,AuthorizationDelegate * delegate)1356 TPM_RC TpmUtilityImpl::ReadNVSpace(uint32_t index,
1357 uint32_t offset,
1358 size_t num_bytes,
1359 std::string* nvram_data,
1360 AuthorizationDelegate* delegate) {
1361 TPM_RC result;
1362 if (num_bytes > MAX_NV_BUFFER_SIZE) {
1363 result = SAPI_RC_BAD_SIZE;
1364 LOG(ERROR) << "Insufficient buffer for non-volatile read: "
1365 << GetErrorString(result);
1366 return result;
1367 }
1368 if (index > kMaxNVSpaceIndex) {
1369 result = SAPI_RC_BAD_PARAMETER;
1370 LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
1371 << GetErrorString(result);
1372 return result;
1373 }
1374 if (delegate == nullptr) {
1375 result = SAPI_RC_INVALID_SESSIONS;
1376 LOG(ERROR) << "This method needs a valid authorization delegate: "
1377 << GetErrorString(result);
1378 return result;
1379 }
1380 std::string nv_name;
1381 result = GetNVSpaceName(index, &nv_name);
1382 if (result != TPM_RC_SUCCESS) {
1383 return result;
1384 }
1385 uint32_t nv_index = NV_INDEX_FIRST + index;
1386 TPM2B_MAX_NV_BUFFER data_buffer;
1387 data_buffer.size = 0;
1388 result = factory_.GetTpm()->NV_ReadSync(nv_index,
1389 nv_name,
1390 nv_index,
1391 nv_name,
1392 num_bytes,
1393 offset,
1394 &data_buffer,
1395 delegate);
1396 if (result != TPM_RC_SUCCESS) {
1397 LOG(ERROR) << "Error reading from non-volatile space: "
1398 << GetErrorString(result);
1399 return result;
1400 }
1401 nvram_data->assign(StringFrom_TPM2B_MAX_NV_BUFFER(data_buffer));
1402 return TPM_RC_SUCCESS;
1403 }
1404
GetNVSpaceName(uint32_t index,std::string * name)1405 TPM_RC TpmUtilityImpl::GetNVSpaceName(uint32_t index, std::string* name) {
1406 TPM_RC result;
1407 if (index > kMaxNVSpaceIndex) {
1408 result = SAPI_RC_BAD_PARAMETER;
1409 LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
1410 << GetErrorString(result);
1411 return result;
1412 }
1413 TPMS_NV_PUBLIC nv_public_data;
1414 result = GetNVSpacePublicArea(index, &nv_public_data);
1415 if (result != TPM_RC_SUCCESS) {
1416 return result;
1417 }
1418 result = ComputeNVSpaceName(nv_public_data, name);
1419 if (result != TPM_RC_SUCCESS) {
1420 return result;
1421 }
1422 return TPM_RC_SUCCESS;
1423 }
1424
GetNVSpacePublicArea(uint32_t index,TPMS_NV_PUBLIC * public_data)1425 TPM_RC TpmUtilityImpl::GetNVSpacePublicArea(uint32_t index,
1426 TPMS_NV_PUBLIC* public_data) {
1427 TPM_RC result;
1428 if (index > kMaxNVSpaceIndex) {
1429 result = SAPI_RC_BAD_PARAMETER;
1430 LOG(ERROR) << "Cannot read from non-volatile space with the given index: "
1431 << GetErrorString(result);
1432 return result;
1433 }
1434 auto it = nvram_public_area_map_.find(index);
1435 if (it != nvram_public_area_map_.end()) {
1436 *public_data = it->second;
1437 return TPM_RC_SUCCESS;
1438 }
1439 TPM2B_NAME nvram_name;
1440 TPM2B_NV_PUBLIC public_area;
1441 public_area.nv_public.nv_index = 0;
1442 uint32_t nv_index = NV_INDEX_FIRST + index;
1443 result = factory_.GetTpm()->NV_ReadPublicSync(nv_index,
1444 "",
1445 &public_area,
1446 &nvram_name,
1447 nullptr);
1448 if (result != TPM_RC_SUCCESS) {
1449 LOG(ERROR) << "Error reading non-volatile space public information: "
1450 << GetErrorString(result);
1451 return result;
1452 }
1453 *public_data = public_area.nv_public;
1454 nvram_public_area_map_[index] = public_area.nv_public;
1455 return TPM_RC_SUCCESS;
1456 }
1457
SetKnownOwnerPassword(const std::string & known_owner_password)1458 TPM_RC TpmUtilityImpl::SetKnownOwnerPassword(
1459 const std::string& known_owner_password) {
1460 scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
1461 TPM_RC result = tpm_state->Initialize();
1462 if (result) {
1463 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1464 return result;
1465 }
1466 scoped_ptr<AuthorizationDelegate> delegate =
1467 factory_.GetPasswordAuthorization("");
1468 if (tpm_state->IsOwnerPasswordSet()) {
1469 LOG(INFO) << "Owner password is already set. "
1470 << "This is normal if ownership is already taken.";
1471 return TPM_RC_SUCCESS;
1472 }
1473 result = SetHierarchyAuthorization(TPM_RH_OWNER,
1474 known_owner_password,
1475 delegate.get());
1476 if (result) {
1477 LOG(ERROR) << "Error setting storage hierarchy authorization "
1478 << "to its default value: " << GetErrorString(result);
1479 return result;
1480 }
1481 return TPM_RC_SUCCESS;
1482 }
1483
CreateStorageRootKeys(const std::string & owner_password)1484 TPM_RC TpmUtilityImpl::CreateStorageRootKeys(
1485 const std::string& owner_password) {
1486 TPM_RC result = TPM_RC_SUCCESS;
1487 scoped_ptr<TpmState> tpm_state(factory_.GetTpmState());
1488 result = tpm_state->Initialize();
1489 if (result) {
1490 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1491 return result;
1492 }
1493 Tpm* tpm = factory_.GetTpm();
1494 TPML_PCR_SELECTION creation_pcrs;
1495 creation_pcrs.count = 0;
1496 TPMS_SENSITIVE_CREATE sensitive;
1497 sensitive.user_auth = Make_TPM2B_DIGEST("");
1498 sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
1499 TPM_HANDLE object_handle;
1500 TPM2B_CREATION_DATA creation_data;
1501 TPM2B_DIGEST creation_digest;
1502 TPMT_TK_CREATION creation_ticket;
1503 TPM2B_NAME object_name;
1504 object_name.size = 0;
1505 scoped_ptr<AuthorizationDelegate> delegate =
1506 factory_.GetPasswordAuthorization(owner_password);
1507 if (tpm_state->IsRSASupported()) {
1508 bool exists = false;
1509 result = DoesPersistentKeyExist(kRSAStorageRootKey, &exists);
1510 if (result) {
1511 return result;
1512 }
1513 if (!exists) {
1514 TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
1515 public_area.object_attributes |=
1516 (kSensitiveDataOrigin | kUserWithAuth | kNoDA |
1517 kRestricted | kDecrypt);
1518 public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_AES;
1519 public_area.parameters.rsa_detail.symmetric.key_bits.aes = 128;
1520 public_area.parameters.rsa_detail.symmetric.mode.aes = TPM_ALG_CFB;
1521 TPM2B_PUBLIC rsa_public_area = Make_TPM2B_PUBLIC(public_area);
1522 result = tpm->CreatePrimarySync(TPM_RH_OWNER,
1523 NameFromHandle(TPM_RH_OWNER),
1524 Make_TPM2B_SENSITIVE_CREATE(sensitive),
1525 rsa_public_area,
1526 Make_TPM2B_DATA(""),
1527 creation_pcrs,
1528 &object_handle,
1529 &rsa_public_area,
1530 &creation_data,
1531 &creation_digest,
1532 &creation_ticket,
1533 &object_name,
1534 delegate.get());
1535 if (result) {
1536 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1537 return result;
1538 }
1539 ScopedKeyHandle rsa_key(factory_, object_handle);
1540 // This will make the key persistent.
1541 result = tpm->EvictControlSync(TPM_RH_OWNER,
1542 NameFromHandle(TPM_RH_OWNER),
1543 object_handle,
1544 StringFrom_TPM2B_NAME(object_name),
1545 kRSAStorageRootKey,
1546 delegate.get());
1547 if (result != TPM_RC_SUCCESS) {
1548 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1549 return result;
1550 }
1551 LOG(INFO) << "Created RSA SRK.";
1552 } else {
1553 LOG(INFO) << "Skip RSA SRK because it already exists.";
1554 }
1555 } else {
1556 LOG(INFO) << "Skip RSA SRK because RSA is not supported.";
1557 }
1558
1559 // Do it again for ECC.
1560 if (tpm_state->IsRSASupported()) {
1561 bool exists = false;
1562 result = DoesPersistentKeyExist(kECCStorageRootKey, &exists);
1563 if (result) {
1564 return result;
1565 }
1566 if (!exists) {
1567 TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_ECC);
1568 public_area.object_attributes |=
1569 (kSensitiveDataOrigin | kUserWithAuth | kNoDA |
1570 kRestricted | kDecrypt);
1571 public_area.parameters.ecc_detail.symmetric.algorithm = TPM_ALG_AES;
1572 public_area.parameters.ecc_detail.symmetric.key_bits.aes = 128;
1573 public_area.parameters.ecc_detail.symmetric.mode.aes = TPM_ALG_CFB;
1574 TPM2B_PUBLIC ecc_public_area = Make_TPM2B_PUBLIC(public_area);
1575 result = tpm->CreatePrimarySync(TPM_RH_OWNER,
1576 NameFromHandle(TPM_RH_OWNER),
1577 Make_TPM2B_SENSITIVE_CREATE(sensitive),
1578 ecc_public_area,
1579 Make_TPM2B_DATA(""),
1580 creation_pcrs,
1581 &object_handle,
1582 &ecc_public_area,
1583 &creation_data,
1584 &creation_digest,
1585 &creation_ticket,
1586 &object_name,
1587 delegate.get());
1588 if (result) {
1589 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1590 return result;
1591 }
1592 ScopedKeyHandle ecc_key(factory_, object_handle);
1593 // This will make the key persistent.
1594 result = tpm->EvictControlSync(TPM_RH_OWNER,
1595 NameFromHandle(TPM_RH_OWNER),
1596 object_handle,
1597 StringFrom_TPM2B_NAME(object_name),
1598 kECCStorageRootKey,
1599 delegate.get());
1600 if (result != TPM_RC_SUCCESS) {
1601 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1602 return result;
1603 }
1604 LOG(INFO) << "Created ECC SRK.";
1605 } else {
1606 LOG(INFO) << "Skip ECC SRK because it already exists.";
1607 }
1608 } else {
1609 LOG(INFO) << "Skip ECC SRK because ECC is not supported.";
1610 }
1611 return TPM_RC_SUCCESS;
1612 }
1613
CreateSaltingKey(const std::string & owner_password)1614 TPM_RC TpmUtilityImpl::CreateSaltingKey(const std::string& owner_password) {
1615 bool exists = false;
1616 TPM_RC result = DoesPersistentKeyExist(kSaltingKey, &exists);
1617 if (result != TPM_RC_SUCCESS) {
1618 return result;
1619 }
1620 if (exists) {
1621 LOG(INFO) << "Salting key already exists.";
1622 return TPM_RC_SUCCESS;
1623 }
1624 std::string parent_name;
1625 result = GetKeyName(kRSAStorageRootKey, &parent_name);
1626 if (result != TPM_RC_SUCCESS) {
1627 LOG(ERROR) << "Error getting Key name for RSA-SRK: "
1628 << GetErrorString(result);
1629 return result;
1630 }
1631 TPMT_PUBLIC public_area = CreateDefaultPublicArea(TPM_ALG_RSA);
1632 public_area.name_alg = TPM_ALG_SHA256;
1633 public_area.object_attributes |=
1634 kSensitiveDataOrigin | kUserWithAuth | kNoDA | kDecrypt;
1635 TPML_PCR_SELECTION creation_pcrs;
1636 creation_pcrs.count = 0;
1637 TPMS_SENSITIVE_CREATE sensitive;
1638 sensitive.user_auth = Make_TPM2B_DIGEST("");
1639 sensitive.data = Make_TPM2B_SENSITIVE_DATA("");
1640 TPM2B_SENSITIVE_CREATE sensitive_create = Make_TPM2B_SENSITIVE_CREATE(
1641 sensitive);
1642 TPM2B_DATA outside_info = Make_TPM2B_DATA("");
1643
1644 TPM2B_PRIVATE out_private;
1645 out_private.size = 0;
1646 TPM2B_PUBLIC out_public;
1647 out_public.size = 0;
1648 TPM2B_CREATION_DATA creation_data;
1649 TPM2B_DIGEST creation_hash;
1650 TPMT_TK_CREATION creation_ticket;
1651 // TODO(usanghi): MITM vulnerability with SaltingKey creation.
1652 // Currently we cannot verify the key returned by the TPM.
1653 // crbug.com/442331
1654 scoped_ptr<AuthorizationDelegate> delegate =
1655 factory_.GetPasswordAuthorization("");
1656 result = factory_.GetTpm()->CreateSync(kRSAStorageRootKey,
1657 parent_name,
1658 sensitive_create,
1659 Make_TPM2B_PUBLIC(public_area),
1660 outside_info,
1661 creation_pcrs,
1662 &out_private,
1663 &out_public,
1664 &creation_data,
1665 &creation_hash,
1666 &creation_ticket,
1667 delegate.get());
1668 if (result != TPM_RC_SUCCESS) {
1669 LOG(ERROR) << "Error creating salting key: " << GetErrorString(result);
1670 return result;
1671 }
1672 TPM2B_NAME key_name;
1673 key_name.size = 0;
1674 TPM_HANDLE key_handle;
1675 result = factory_.GetTpm()->LoadSync(kRSAStorageRootKey,
1676 parent_name,
1677 out_private,
1678 out_public,
1679 &key_handle,
1680 &key_name,
1681 delegate.get());
1682 if (result != TPM_RC_SUCCESS) {
1683 LOG(ERROR) << "Error loading salting key: " << GetErrorString(result);
1684 return result;
1685 }
1686 ScopedKeyHandle key(factory_, key_handle);
1687 scoped_ptr<AuthorizationDelegate> owner_delegate =
1688 factory_.GetPasswordAuthorization(owner_password);
1689 result = factory_.GetTpm()->EvictControlSync(TPM_RH_OWNER,
1690 NameFromHandle(TPM_RH_OWNER),
1691 key_handle,
1692 StringFrom_TPM2B_NAME(key_name),
1693 kSaltingKey,
1694 owner_delegate.get());
1695 if (result != TPM_RC_SUCCESS) {
1696 LOG(ERROR) << __func__ << ": " << GetErrorString(result);
1697 return result;
1698 }
1699 return TPM_RC_SUCCESS;
1700 }
1701
CreateDefaultPublicArea(TPM_ALG_ID key_alg)1702 TPMT_PUBLIC TpmUtilityImpl::CreateDefaultPublicArea(TPM_ALG_ID key_alg) {
1703 TPMT_PUBLIC public_area;
1704 public_area.name_alg = TPM_ALG_SHA256;
1705 public_area.auth_policy = Make_TPM2B_DIGEST("");
1706 public_area.object_attributes = kFixedTPM | kFixedParent;
1707 if (key_alg == TPM_ALG_RSA) {
1708 public_area.type = TPM_ALG_RSA;
1709 public_area.parameters.rsa_detail.scheme.scheme = TPM_ALG_NULL;
1710 public_area.parameters.rsa_detail.symmetric.algorithm = TPM_ALG_NULL;
1711 public_area.parameters.rsa_detail.key_bits = 2048;
1712 public_area.parameters.rsa_detail.exponent = 0;
1713 public_area.unique.rsa = Make_TPM2B_PUBLIC_KEY_RSA("");
1714 } else if (key_alg == TPM_ALG_ECC) {
1715 public_area.type = TPM_ALG_ECC;
1716 public_area.parameters.ecc_detail.curve_id = TPM_ECC_NIST_P256;
1717 public_area.parameters.ecc_detail.kdf.scheme = TPM_ALG_NULL;
1718 public_area.unique.ecc.x = Make_TPM2B_ECC_PARAMETER("");
1719 public_area.unique.ecc.y = Make_TPM2B_ECC_PARAMETER("");
1720 } else if (key_alg == TPM_ALG_KEYEDHASH) {
1721 public_area.type = TPM_ALG_KEYEDHASH;
1722 public_area.parameters.keyed_hash_detail.scheme.scheme = TPM_ALG_NULL;
1723 } else {
1724 LOG(WARNING) << "Unrecognized key_type. Not filling parameters.";
1725 }
1726 return public_area;
1727 }
1728
SetHierarchyAuthorization(TPMI_RH_HIERARCHY_AUTH hierarchy,const std::string & password,AuthorizationDelegate * authorization)1729 TPM_RC TpmUtilityImpl::SetHierarchyAuthorization(
1730 TPMI_RH_HIERARCHY_AUTH hierarchy,
1731 const std::string& password,
1732 AuthorizationDelegate* authorization) {
1733 if (password.size() > kMaxPasswordLength) {
1734 LOG(ERROR) << "Hierarchy passwords can be at most " << kMaxPasswordLength
1735 << " bytes. Current password length is: " << password.size();
1736 return SAPI_RC_BAD_SIZE;
1737 }
1738 return factory_.GetTpm()->HierarchyChangeAuthSync(
1739 hierarchy,
1740 NameFromHandle(hierarchy),
1741 Make_TPM2B_DIGEST(password),
1742 authorization);
1743 }
1744
DisablePlatformHierarchy(AuthorizationDelegate * authorization)1745 TPM_RC TpmUtilityImpl::DisablePlatformHierarchy(
1746 AuthorizationDelegate* authorization) {
1747 return factory_.GetTpm()->HierarchyControlSync(
1748 TPM_RH_PLATFORM, // The authorizing entity.
1749 NameFromHandle(TPM_RH_PLATFORM),
1750 TPM_RH_PLATFORM, // The target hierarchy.
1751 0, // Disable.
1752 authorization);
1753 }
1754
ComputeKeyName(const TPMT_PUBLIC & public_area,std::string * object_name)1755 TPM_RC TpmUtilityImpl::ComputeKeyName(const TPMT_PUBLIC& public_area,
1756 std::string* object_name) {
1757 CHECK(object_name);
1758 if (public_area.type == TPM_ALG_ERROR) {
1759 // We do not compute a name for empty public area.
1760 object_name->clear();
1761 return TPM_RC_SUCCESS;
1762 }
1763 std::string serialized_public_area;
1764 TPM_RC result = Serialize_TPMT_PUBLIC(public_area, &serialized_public_area);
1765 if (result != TPM_RC_SUCCESS) {
1766 LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
1767 return result;
1768 }
1769 std::string serialized_name_alg;
1770 result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
1771 if (result != TPM_RC_SUCCESS) {
1772 LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
1773 return result;
1774 }
1775 object_name->assign(serialized_name_alg +
1776 crypto::SHA256HashString(serialized_public_area));
1777 return TPM_RC_SUCCESS;
1778 }
1779
ComputeNVSpaceName(const TPMS_NV_PUBLIC & nv_public_area,std::string * nv_name)1780 TPM_RC TpmUtilityImpl::ComputeNVSpaceName(const TPMS_NV_PUBLIC& nv_public_area,
1781 std::string* nv_name) {
1782 CHECK(nv_name);
1783 if ((nv_public_area.nv_index & NV_INDEX_FIRST) == 0) {
1784 // If the index is not an nvram index, we do not compute a name.
1785 nv_name->clear();
1786 return TPM_RC_SUCCESS;
1787 }
1788 std::string serialized_public_area;
1789 TPM_RC result = Serialize_TPMS_NV_PUBLIC(nv_public_area,
1790 &serialized_public_area);
1791 if (result != TPM_RC_SUCCESS) {
1792 LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
1793 return result;
1794 }
1795 std::string serialized_name_alg;
1796 result = Serialize_TPM_ALG_ID(TPM_ALG_SHA256, &serialized_name_alg);
1797 if (result != TPM_RC_SUCCESS) {
1798 LOG(ERROR) << "Error serializing public area: " << GetErrorString(result);
1799 return result;
1800 }
1801 nv_name->assign(serialized_name_alg +
1802 crypto::SHA256HashString(serialized_public_area));
1803 return TPM_RC_SUCCESS;
1804 }
1805
EncryptPrivateData(const TPMT_SENSITIVE & sensitive_area,const TPMT_PUBLIC & public_area,TPM2B_PRIVATE * encrypted_private_data,TPM2B_DATA * encryption_key)1806 TPM_RC TpmUtilityImpl::EncryptPrivateData(const TPMT_SENSITIVE& sensitive_area,
1807 const TPMT_PUBLIC& public_area,
1808 TPM2B_PRIVATE* encrypted_private_data,
1809 TPM2B_DATA* encryption_key) {
1810 TPM2B_SENSITIVE sensitive_data = Make_TPM2B_SENSITIVE(sensitive_area);
1811 std::string serialized_sensitive_data;
1812 TPM_RC result = Serialize_TPM2B_SENSITIVE(sensitive_data,
1813 &serialized_sensitive_data);
1814 if (result != TPM_RC_SUCCESS) {
1815 LOG(ERROR) << "Error serializing sensitive data: "
1816 << GetErrorString(result);
1817 return result;
1818 }
1819 std::string object_name;
1820 result = ComputeKeyName(public_area, &object_name);
1821 if (result != TPM_RC_SUCCESS) {
1822 LOG(ERROR) << "Error computing object name: " << GetErrorString(result);
1823 return result;
1824 }
1825 TPM2B_DIGEST inner_integrity = Make_TPM2B_DIGEST(crypto::SHA256HashString(
1826 serialized_sensitive_data + object_name));
1827 std::string serialized_inner_integrity;
1828 result = Serialize_TPM2B_DIGEST(inner_integrity, &serialized_inner_integrity);
1829 if (result != TPM_RC_SUCCESS) {
1830 LOG(ERROR) << "Error serializing inner integrity: "
1831 << GetErrorString(result);
1832 return result;
1833 }
1834 std::string unencrypted_private_data = serialized_inner_integrity +
1835 serialized_sensitive_data;
1836 AES_KEY key;
1837 AES_set_encrypt_key(encryption_key->buffer, kAesKeySize * 8, &key);
1838 std::string private_data_string(unencrypted_private_data.size(), 0);
1839 int iv_in = 0;
1840 unsigned char iv[MAX_AES_BLOCK_SIZE_BYTES] = {0};
1841 AES_cfb128_encrypt(
1842 reinterpret_cast<const unsigned char*>(unencrypted_private_data.data()),
1843 reinterpret_cast<unsigned char*>(string_as_array(&private_data_string)),
1844 unencrypted_private_data.size(), &key, iv, &iv_in, AES_ENCRYPT);
1845 *encrypted_private_data = Make_TPM2B_PRIVATE(private_data_string);
1846 if (result != TPM_RC_SUCCESS) {
1847 LOG(ERROR) << "Error making private area: "
1848 << GetErrorString(result);
1849 return result;
1850 }
1851 return TPM_RC_SUCCESS;
1852 }
1853
DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle,bool * exists)1854 TPM_RC TpmUtilityImpl::DoesPersistentKeyExist(TPMI_DH_PERSISTENT key_handle,
1855 bool* exists) {
1856 TPM_RC result;
1857 TPMI_YES_NO more_data = YES;
1858 TPMS_CAPABILITY_DATA capability_data;
1859 result = factory_.GetTpm()->GetCapabilitySync(
1860 TPM_CAP_HANDLES, key_handle, 1 /*property_count*/, &more_data,
1861 &capability_data, nullptr /*authorization_delegate*/);
1862 if (result != TPM_RC_SUCCESS) {
1863 LOG(ERROR) << __func__
1864 << ": Error querying handles: " << GetErrorString(result);
1865 return result;
1866 }
1867 TPML_HANDLE& handles = capability_data.data.handles;
1868 *exists = (handles.count == 1 && handles.handle[0] == key_handle);
1869 return TPM_RC_SUCCESS;
1870 }
1871
1872 } // namespace trunks
1873