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