1 //
2 // Copyright (C) 2020 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 #include "tpm_keymaster_context.h"
17 
18 #include <android-base/logging.h>
19 #include <keymaster/contexts/soft_attestation_cert.h>
20 #include <keymaster/km_openssl/aes_key.h>
21 #include <keymaster/km_openssl/asymmetric_key.h>
22 #include <keymaster/km_openssl/attestation_utils.h>
23 #include <keymaster/km_openssl/certificate_utils.h>
24 #include <keymaster/km_openssl/ec_key_factory.h>
25 #include <keymaster/km_openssl/hmac_key.h>
26 #include <keymaster/km_openssl/rsa_key_factory.h>
27 #include <keymaster/km_openssl/soft_keymaster_enforcement.h>
28 #include <keymaster/km_openssl/triple_des_key.h>
29 #include <keymaster/operation.h>
30 #include <keymaster/wrapped_key.h>
31 
32 #include "host/commands/secure_env/primary_key_builder.h"
33 #include "host/commands/secure_env/tpm_attestation_record.h"
34 #include "host/commands/secure_env/tpm_hmac.h"
35 #include "host/commands/secure_env/tpm_key_blob_maker.h"
36 #include "host/commands/secure_env/tpm_random_source.h"
37 #include "host/commands/secure_env/tpm_remote_provisioning_context.h"
38 
39 namespace cuttlefish {
40 
41 namespace {
42 using keymaster::AuthorizationSet;
43 using keymaster::KeyFactory;
44 using keymaster::KeymasterBlob;
45 using keymaster::KeymasterKeyBlob;
46 using keymaster::OperationFactory;
47 
GetHiddenTags(const AuthorizationSet & authorizations)48 keymaster::AuthorizationSet GetHiddenTags(
49     const AuthorizationSet& authorizations) {
50   keymaster::AuthorizationSet output;
51   keymaster_blob_t entry;
52   if (authorizations.GetTagValue(keymaster::TAG_APPLICATION_ID, &entry)) {
53     output.push_back(keymaster::TAG_APPLICATION_ID, entry.data,
54                      entry.data_length);
55   }
56   if (authorizations.GetTagValue(keymaster::TAG_APPLICATION_DATA, &entry)) {
57     output.push_back(keymaster::TAG_APPLICATION_DATA, entry.data,
58                      entry.data_length);
59   }
60   return output;
61 }
62 
TranslateAuthorizationSetError(AuthorizationSet::Error err)63 keymaster_error_t TranslateAuthorizationSetError(AuthorizationSet::Error err) {
64   switch (err) {
65     case AuthorizationSet::OK:
66       return KM_ERROR_OK;
67     case AuthorizationSet::ALLOCATION_FAILURE:
68       return KM_ERROR_MEMORY_ALLOCATION_FAILED;
69     case AuthorizationSet::MALFORMED_DATA:
70       return KM_ERROR_UNKNOWN_ERROR;
71   }
72   return KM_ERROR_UNKNOWN_ERROR;
73 }
74 
75 }  // namespace
76 
TpmKeymasterContext(TpmResourceManager & resource_manager,keymaster::KeymasterEnforcement & enforcement)77 TpmKeymasterContext::TpmKeymasterContext(
78     TpmResourceManager& resource_manager,
79     keymaster::KeymasterEnforcement& enforcement)
80     : resource_manager_(resource_manager),
81       enforcement_(enforcement),
82       key_blob_maker_(new TpmKeyBlobMaker(resource_manager_)),
83       random_source_(new TpmRandomSource(resource_manager_)),
84       attestation_context_(new TpmAttestationRecordContext),
85       remote_provisioning_context_(
86           new TpmRemoteProvisioningContext(resource_manager_)) {
87   key_factories_.emplace(KM_ALGORITHM_RSA,
88                          new keymaster::RsaKeyFactory(*key_blob_maker_, *this));
89   key_factories_.emplace(KM_ALGORITHM_EC,
90                          new keymaster::EcKeyFactory(*key_blob_maker_, *this));
91   key_factories_.emplace(
92       KM_ALGORITHM_AES,
93       new keymaster::AesKeyFactory(*key_blob_maker_, *random_source_));
94   key_factories_.emplace(
95       KM_ALGORITHM_TRIPLE_DES,
96       new keymaster::TripleDesKeyFactory(*key_blob_maker_, *random_source_));
97   key_factories_.emplace(
98       KM_ALGORITHM_HMAC,
99       new keymaster::HmacKeyFactory(*key_blob_maker_, *random_source_));
100   for (const auto& it : key_factories_) {
101     supported_algorithms_.push_back(it.first);
102   }
103 }
104 
SetSystemVersion(uint32_t os_version,uint32_t os_patchlevel)105 keymaster_error_t TpmKeymasterContext::SetSystemVersion(
106     uint32_t os_version, uint32_t os_patchlevel) {
107   // TODO(b/155697375): Only accept new values of these from the bootloader
108   os_version_ = os_version;
109   os_patchlevel_ = os_patchlevel;
110   key_blob_maker_->SetSystemVersion(os_version, os_patchlevel);
111   remote_provisioning_context_->SetSystemVersion(os_version_, os_patchlevel_);
112   return KM_ERROR_OK;
113 }
114 
GetSystemVersion(uint32_t * os_version,uint32_t * os_patchlevel) const115 void TpmKeymasterContext::GetSystemVersion(uint32_t* os_version,
116                                            uint32_t* os_patchlevel) const {
117   *os_version = os_version_;
118   *os_patchlevel = os_patchlevel_;
119 }
120 
GetKeyFactory(keymaster_algorithm_t algorithm) const121 const KeyFactory* TpmKeymasterContext::GetKeyFactory(
122     keymaster_algorithm_t algorithm) const {
123   auto it = key_factories_.find(algorithm);
124   if (it == key_factories_.end()) {
125     LOG(ERROR) << "Could not find key factory for " << algorithm;
126     return nullptr;
127   }
128   return it->second.get();
129 }
130 
GetOperationFactory(keymaster_algorithm_t algorithm,keymaster_purpose_t purpose) const131 OperationFactory* TpmKeymasterContext::GetOperationFactory(
132     keymaster_algorithm_t algorithm, keymaster_purpose_t purpose) const {
133   auto key_factory = GetKeyFactory(algorithm);
134   if (key_factory == nullptr) {
135     LOG(ERROR) << "Tried to get operation factory for " << purpose
136                << " for invalid algorithm " << algorithm;
137     return nullptr;
138   }
139   auto operation_factory = key_factory->GetOperationFactory(purpose);
140   if (operation_factory == nullptr) {
141     LOG(ERROR) << "Could not get operation factory for " << purpose
142                << " from key factory for " << algorithm;
143   }
144   return operation_factory;
145 }
146 
GetSupportedAlgorithms(size_t * algorithms_count) const147 const keymaster_algorithm_t* TpmKeymasterContext::GetSupportedAlgorithms(
148     size_t* algorithms_count) const {
149   *algorithms_count = supported_algorithms_.size();
150   return supported_algorithms_.data();
151 }
152 
153 // Based on
154 // https://cs.android.com/android/platform/superproject/+/master:system/keymaster/key_blob_utils/software_keyblobs.cpp;l=44;drc=master
155 
UpgradeIntegerTag(keymaster_tag_t tag,uint32_t value,AuthorizationSet * set,bool * set_changed)156 static bool UpgradeIntegerTag(keymaster_tag_t tag, uint32_t value,
157                               AuthorizationSet* set, bool* set_changed) {
158   int index = set->find(tag);
159   if (index == -1) {
160     keymaster_key_param_t param;
161     param.tag = tag;
162     param.integer = value;
163     set->push_back(param);
164     *set_changed = true;
165     return true;
166   }
167 
168   if (set->params[index].integer > value) {
169     return false;
170   }
171 
172   if (set->params[index].integer != value) {
173     set->params[index].integer = value;
174     *set_changed = true;
175   }
176   return true;
177 }
178 
179 // Based on
180 // https://cs.android.com/android/platform/superproject/+/master:system/keymaster/key_blob_utils/software_keyblobs.cpp;l=310;drc=master
181 
UpgradeKeyBlob(const KeymasterKeyBlob & blob_to_upgrade,const AuthorizationSet & upgrade_params,KeymasterKeyBlob * upgraded_key) const182 keymaster_error_t TpmKeymasterContext::UpgradeKeyBlob(
183     const KeymasterKeyBlob& blob_to_upgrade,
184     const AuthorizationSet& upgrade_params,
185     KeymasterKeyBlob* upgraded_key) const {
186   keymaster::UniquePtr<keymaster::Key> key;
187   auto error = ParseKeyBlob(blob_to_upgrade, upgrade_params, &key);
188   if (error != KM_ERROR_OK) {
189     LOG(ERROR) << "Failed to parse key blob";
190     return error;
191   }
192 
193   bool set_changed = false;
194 
195   if (os_version_ == 0) {
196     // We need to allow "upgrading" OS version to zero, to support upgrading
197     // from proper numbered releases to unnumbered development and preview
198     // releases.
199 
200     int key_os_version_pos = key->hw_enforced().find(keymaster::TAG_OS_VERSION);
201     if (key_os_version_pos != -1) {
202       uint32_t key_os_version = key->hw_enforced()[key_os_version_pos].integer;
203       if (key_os_version != 0) {
204         key->hw_enforced()[key_os_version_pos].integer = os_version_;
205         set_changed = true;
206       }
207     }
208   }
209 
210   auto update_os = UpgradeIntegerTag(keymaster::TAG_OS_VERSION, os_version_,
211                                      &key->hw_enforced(), &set_changed);
212 
213   auto update_patchlevel =
214       UpgradeIntegerTag(keymaster::TAG_OS_PATCHLEVEL, os_patchlevel_,
215                         &key->hw_enforced(), &set_changed);
216 
217   if (!update_os || !update_patchlevel) {
218     LOG(ERROR) << "One of the version fields would have been a downgrade. "
219                << "Not allowed.";
220     return KM_ERROR_INVALID_ARGUMENT;
221   }
222 
223   if (!set_changed) {
224     // Don't need an upgrade.
225     return KM_ERROR_OK;
226   }
227 
228   return key_blob_maker_->UnvalidatedCreateKeyBlob(
229       key->key_material(), key->hw_enforced(), key->sw_enforced(),
230       GetHiddenTags(upgrade_params), upgraded_key);
231 }
232 
ParseKeyBlob(const KeymasterKeyBlob & blob,const AuthorizationSet & additional_params,keymaster::UniquePtr<keymaster::Key> * key) const233 keymaster_error_t TpmKeymasterContext::ParseKeyBlob(
234     const KeymasterKeyBlob& blob, const AuthorizationSet& additional_params,
235     keymaster::UniquePtr<keymaster::Key>* key) const {
236   keymaster::AuthorizationSet hw_enforced;
237   keymaster::AuthorizationSet sw_enforced;
238   keymaster::KeymasterKeyBlob key_material;
239 
240   keymaster::AuthorizationSet hidden = GetHiddenTags(additional_params);
241 
242   auto rc = key_blob_maker_->UnwrapKeyBlob(blob, &hw_enforced, &sw_enforced,
243                                            hidden, &key_material);
244   if (rc != KM_ERROR_OK) {
245     LOG(ERROR) << "Failed to unwrap key: " << rc;
246     return rc;
247   }
248 
249   keymaster_algorithm_t algorithm;
250   if (!hw_enforced.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm) &&
251       !sw_enforced.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm)) {
252     LOG(ERROR) << "No TAG_ALGORITHM value in hw_enforced or sw_enforced.";
253     return KM_ERROR_UNKNOWN_ERROR;
254   }
255 
256   auto factory = GetKeyFactory(algorithm);
257   if (factory == nullptr) {
258     LOG(ERROR) << "Unable to find key factory for " << algorithm;
259     return KM_ERROR_UNSUPPORTED_ALGORITHM;
260   }
261   rc = factory->LoadKey(std::move(key_material), additional_params,
262                         std::move(hw_enforced), std::move(sw_enforced), key);
263   if (rc != KM_ERROR_OK) {
264     LOG(ERROR) << "Unable to load unwrapped key: " << rc;
265   }
266   return rc;
267 }
268 
AddRngEntropy(const uint8_t * buffer,size_t size) const269 keymaster_error_t TpmKeymasterContext::AddRngEntropy(const uint8_t* buffer,
270                                                      size_t size) const {
271   return random_source_->AddRngEntropy(buffer, size);
272 }
273 
enforcement_policy()274 keymaster::KeymasterEnforcement* TpmKeymasterContext::enforcement_policy() {
275   return &enforcement_;
276 }
277 
278 // Based on
279 // https://cs.android.com/android/platform/superproject/+/master:system/keymaster/contexts/pure_soft_keymaster_context.cpp;l=261;drc=8367d5351c4d417a11f49b12394b63a413faa02d
280 
GenerateAttestation(const keymaster::Key & key,const keymaster::AuthorizationSet & attest_params,keymaster::UniquePtr<keymaster::Key> attest_key,const keymaster::KeymasterBlob & issuer_subject,keymaster_error_t * error) const281 keymaster::CertificateChain TpmKeymasterContext::GenerateAttestation(
282     const keymaster::Key& key, const keymaster::AuthorizationSet& attest_params,
283     keymaster::UniquePtr<keymaster::Key> attest_key,
284     const keymaster::KeymasterBlob& issuer_subject,
285     keymaster_error_t* error) const {
286   LOG(INFO) << "TODO(b/155697200): Link attestation back to the TPM";
287   keymaster_algorithm_t key_algorithm;
288   if (!key.authorizations().GetTagValue(keymaster::TAG_ALGORITHM,
289                                         &key_algorithm)) {
290     LOG(ERROR) << "Cannot find key algorithm (TAG_ALGORITHM)";
291     *error = KM_ERROR_UNKNOWN_ERROR;
292     return {};
293   }
294 
295   if ((key_algorithm != KM_ALGORITHM_RSA && key_algorithm != KM_ALGORITHM_EC)) {
296     LOG(ERROR) << "Invalid algorithm: " << key_algorithm;
297     *error = KM_ERROR_INCOMPATIBLE_ALGORITHM;
298     return {};
299   }
300 
301   // We have established that the given key has the correct algorithm, and
302   // because this is the TpmKeymasterContext we can assume that the Key is an
303   // AsymmetricKey. So we can downcast.
304   const keymaster::AsymmetricKey& asymmetric_key =
305       static_cast<const keymaster::AsymmetricKey&>(key);
306 
307   // DEVICE_UNIQUE_ATTESTATION is only allowed for strongbox devices. See
308   // hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl:845
309   // at commit beefae4790ccd4f1ee75ea69603d4c9c2a45c0aa .
310   // While the specification says to return ErrorCode::INVALID_ARGUMENT , the
311   // relevant VTS test actually tests for ErrorCode::UNIMPLEMENTED . See
312   // hardware/interfaces/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp:203
313   // at commit 36dcf1a404a9cf07ca5a2a6ad92371507194fe1b .
314   if (attest_params.find(keymaster::TAG_DEVICE_UNIQUE_ATTESTATION) != -1) {
315     LOG(ERROR) << "TAG_DEVICE_UNIQUE_ATTESTATION not supported";
316     *error = KM_ERROR_UNIMPLEMENTED;
317     return {};
318   }
319 
320   keymaster::AttestKeyInfo attest_key_info(attest_key, &issuer_subject, error);
321   if (*error != KM_ERROR_OK) {
322     LOG(ERROR)
323         << "Error creating attestation key info from given key and subject";
324     return {};
325   }
326 
327   return keymaster::generate_attestation(asymmetric_key, attest_params,
328                                          std::move(attest_key_info),
329                                          *attestation_context_, error);
330 }
331 
GenerateSelfSignedCertificate(const keymaster::Key & key,const keymaster::AuthorizationSet & cert_params,bool fake_signature,keymaster_error_t * error) const332 keymaster::CertificateChain TpmKeymasterContext::GenerateSelfSignedCertificate(
333     const keymaster::Key& key, const keymaster::AuthorizationSet& cert_params,
334     bool fake_signature, keymaster_error_t* error) const {
335   keymaster_algorithm_t key_algorithm;
336   if (!key.authorizations().GetTagValue(keymaster::TAG_ALGORITHM,
337                                         &key_algorithm)) {
338     *error = KM_ERROR_UNKNOWN_ERROR;
339     return {};
340   }
341 
342   if ((key_algorithm != KM_ALGORITHM_RSA && key_algorithm != KM_ALGORITHM_EC)) {
343     *error = KM_ERROR_INCOMPATIBLE_ALGORITHM;
344     return {};
345   }
346 
347   // We have established that the given key has the correct algorithm, and
348   // because this is the SoftKeymasterContext we can assume that the Key is an
349   // AsymmetricKey. So we can downcast.
350   const keymaster::AsymmetricKey& asymmetric_key =
351       static_cast<const keymaster::AsymmetricKey&>(key);
352 
353   return generate_self_signed_cert(asymmetric_key, cert_params, fake_signature,
354                                    error);
355 }
356 
UnwrapKey(const KeymasterKeyBlob & wrapped_key_blob,const KeymasterKeyBlob & wrapping_key_blob,const AuthorizationSet & wrapping_key_params,const KeymasterKeyBlob & masking_key,AuthorizationSet * wrapped_key_params,keymaster_key_format_t * wrapped_key_format,KeymasterKeyBlob * wrapped_key_material) const357 keymaster_error_t TpmKeymasterContext::UnwrapKey(
358     const KeymasterKeyBlob& wrapped_key_blob,
359     const KeymasterKeyBlob& wrapping_key_blob,
360     const AuthorizationSet& wrapping_key_params,
361     const KeymasterKeyBlob& masking_key, AuthorizationSet* wrapped_key_params,
362     keymaster_key_format_t* wrapped_key_format,
363     KeymasterKeyBlob* wrapped_key_material) const {
364   keymaster_error_t error = KM_ERROR_OK;
365 
366   if (wrapped_key_material == nullptr) {
367     return KM_ERROR_UNEXPECTED_NULL_POINTER;
368   }
369 
370   // Parse wrapping key.
371   keymaster::UniquePtr<keymaster::Key> wrapping_key;
372   error = ParseKeyBlob(wrapping_key_blob, wrapping_key_params, &wrapping_key);
373   if (error != KM_ERROR_OK) {
374     return error;
375   }
376 
377   keymaster::AuthProxy wrapping_key_auths(wrapping_key->hw_enforced(),
378                                           wrapping_key->sw_enforced());
379 
380   // Check Wrapping Key Purpose
381   if (!wrapping_key_auths.Contains(keymaster::TAG_PURPOSE, KM_PURPOSE_WRAP)) {
382     LOG(ERROR) << "Wrapping key did not have KM_PURPOSE_WRAP";
383     return KM_ERROR_INCOMPATIBLE_PURPOSE;
384   }
385 
386   // Check Padding mode is RSA_OAEP and digest is SHA_2_256 (spec
387   // mandated)
388   if (!wrapping_key_auths.Contains(keymaster::TAG_DIGEST,
389                                    KM_DIGEST_SHA_2_256)) {
390     LOG(ERROR) << "Wrapping key lacks authorization for SHA2-256";
391     return KM_ERROR_INCOMPATIBLE_DIGEST;
392   }
393   if (!wrapping_key_auths.Contains(keymaster::TAG_PADDING, KM_PAD_RSA_OAEP)) {
394     LOG(ERROR) << "Wrapping key lacks authorization for padding OAEP";
395     return KM_ERROR_INCOMPATIBLE_PADDING_MODE;
396   }
397 
398   // Check that that was also the padding mode and digest specified
399   if (!wrapping_key_params.Contains(keymaster::TAG_DIGEST,
400                                     KM_DIGEST_SHA_2_256)) {
401     LOG(ERROR) << "Wrapping key must use SHA2-256";
402     return KM_ERROR_INCOMPATIBLE_DIGEST;
403   }
404   if (!wrapping_key_params.Contains(keymaster::TAG_PADDING, KM_PAD_RSA_OAEP)) {
405     LOG(ERROR) << "Wrapping key must use OAEP padding";
406     return KM_ERROR_INCOMPATIBLE_PADDING_MODE;
407   }
408 
409   // Parse wrapped key data.
410   KeymasterBlob iv;
411   KeymasterKeyBlob transit_key;
412   KeymasterKeyBlob secure_key;
413   KeymasterBlob tag;
414   KeymasterBlob wrapped_key_description;
415   error = parse_wrapped_key(wrapped_key_blob, &iv, &transit_key, &secure_key,
416                             &tag, wrapped_key_params, wrapped_key_format,
417                             &wrapped_key_description);
418   if (error != KM_ERROR_OK) {
419     return error;
420   }
421 
422   // Decrypt encryptedTransportKey (transit_key) with wrapping_key
423   keymaster::OperationFactory* operation_factory =
424       wrapping_key->key_factory()->GetOperationFactory(KM_PURPOSE_DECRYPT);
425   if (operation_factory == NULL) {
426     return KM_ERROR_UNKNOWN_ERROR;
427   }
428 
429   AuthorizationSet out_params;
430   keymaster::OperationPtr operation(operation_factory->CreateOperation(
431       std::move(*wrapping_key), wrapping_key_params, &error));
432   if ((operation.get() == nullptr) || (error != KM_ERROR_OK)) {
433     return error;
434   }
435 
436   error = operation->Begin(wrapping_key_params, &out_params);
437   if (error != KM_ERROR_OK) {
438     return error;
439   }
440 
441   keymaster::Buffer input;
442   if (!input.Reinitialize(transit_key.key_material,
443                           transit_key.key_material_size)) {
444     return KM_ERROR_MEMORY_ALLOCATION_FAILED;
445   }
446 
447   keymaster::Buffer output;
448   error = operation->Finish(wrapping_key_params, input,
449                             keymaster::Buffer() /* signature */, &out_params,
450                             &output);
451   if (error != KM_ERROR_OK) {
452     return error;
453   }
454 
455   // decrypt the encrypted key material with the transit key
456   KeymasterKeyBlob transport_key = {output.peek_read(),
457                                     output.available_read()};
458 
459   // XOR the transit key with the masking key
460   if (transport_key.key_material_size != masking_key.key_material_size) {
461     return KM_ERROR_INVALID_ARGUMENT;
462   }
463   for (size_t i = 0; i < transport_key.key_material_size; i++) {
464     transport_key.writable_data()[i] ^= masking_key.key_material[i];
465   }
466 
467   auto transport_key_authorizations =
468       keymaster::AuthorizationSetBuilder()
469           .AesEncryptionKey(256)
470           .Padding(KM_PAD_NONE)
471           .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
472           .Authorization(keymaster::TAG_NONCE, iv)
473           .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 128)
474           .build();
475   if (transport_key_authorizations.is_valid() != AuthorizationSet::Error::OK) {
476     return TranslateAuthorizationSetError(
477         transport_key_authorizations.is_valid());
478   }
479 
480   auto gcm_params = keymaster::AuthorizationSetBuilder()
481                         .Padding(KM_PAD_NONE)
482                         .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
483                         .Authorization(keymaster::TAG_NONCE, iv)
484                         .Authorization(keymaster::TAG_MAC_LENGTH, 128)
485                         .build();
486   if (gcm_params.is_valid() != AuthorizationSet::Error::OK) {
487     return TranslateAuthorizationSetError(
488         transport_key_authorizations.is_valid());
489   }
490 
491   auto aes_factory = GetKeyFactory(KM_ALGORITHM_AES);
492   if (!aes_factory) {
493     return KM_ERROR_UNKNOWN_ERROR;
494   }
495 
496   keymaster::UniquePtr<keymaster::Key> aes_transport_key;
497   error = aes_factory->LoadKey(std::move(transport_key), gcm_params,
498                                std::move(transport_key_authorizations),
499                                AuthorizationSet(), &aes_transport_key);
500   if (error != KM_ERROR_OK) {
501     return error;
502   }
503 
504   keymaster::OperationFactory* aes_operation_factory =
505       GetOperationFactory(KM_ALGORITHM_AES, KM_PURPOSE_DECRYPT);
506   if (!aes_operation_factory) {
507     return KM_ERROR_UNKNOWN_ERROR;
508   }
509 
510   keymaster::OperationPtr aes_operation(aes_operation_factory->CreateOperation(
511       std::move(*aes_transport_key), gcm_params, &error));
512   if (!aes_operation.get()) {
513     return error;
514   }
515 
516   error = aes_operation->Begin(gcm_params, &out_params);
517   if (error != KM_ERROR_OK) {
518     return error;
519   }
520 
521   size_t total_key_size = secure_key.key_material_size + tag.data_length;
522   keymaster::Buffer plaintext_key;
523   if (!plaintext_key.Reinitialize(total_key_size)) {
524     return KM_ERROR_MEMORY_ALLOCATION_FAILED;
525   }
526   keymaster::Buffer encrypted_key;
527   if (!encrypted_key.Reinitialize(total_key_size)) {
528     return KM_ERROR_MEMORY_ALLOCATION_FAILED;
529   }
530 
531   // Concatenate key data and authentication tag.
532   if (!encrypted_key.write(secure_key.key_material,
533                            secure_key.key_material_size)) {
534     return KM_ERROR_UNKNOWN_ERROR;
535   }
536   if (!encrypted_key.write(tag.data, tag.data_length)) {
537     return KM_ERROR_UNKNOWN_ERROR;
538   }
539 
540   auto update_params = keymaster::AuthorizationSetBuilder()
541                            .Authorization(keymaster::TAG_ASSOCIATED_DATA,
542                                           wrapped_key_description.data,
543                                           wrapped_key_description.data_length)
544                            .build();
545   if (update_params.is_valid() != AuthorizationSet::Error::OK) {
546     return TranslateAuthorizationSetError(update_params.is_valid());
547   }
548 
549   size_t update_consumed = 0;
550   AuthorizationSet update_outparams;
551   error = aes_operation->Update(update_params, encrypted_key, &update_outparams,
552                                 &plaintext_key, &update_consumed);
553   if (error != KM_ERROR_OK) {
554     return error;
555   }
556 
557   AuthorizationSet finish_params;
558   AuthorizationSet finish_out_params;
559   keymaster::Buffer finish_input;
560   error = aes_operation->Finish(finish_params, finish_input,
561                                 keymaster::Buffer() /* signature */,
562                                 &finish_out_params, &plaintext_key);
563   if (error != KM_ERROR_OK) {
564     return error;
565   }
566 
567   *wrapped_key_material = {plaintext_key.peek_read(),
568                            plaintext_key.available_read()};
569   if (!wrapped_key_material->key_material && plaintext_key.peek_read()) {
570     return KM_ERROR_MEMORY_ALLOCATION_FAILED;
571   }
572 
573   return error;
574 }
575 
CheckConfirmationToken(const std::uint8_t * input_data,size_t input_data_size,const uint8_t confirmation_token[keymaster::kConfirmationTokenSize]) const576 keymaster_error_t TpmKeymasterContext::CheckConfirmationToken(
577     const std::uint8_t* input_data, size_t input_data_size,
578     const uint8_t confirmation_token[keymaster::kConfirmationTokenSize]) const {
579   auto hmac = TpmHmacWithContext(resource_manager_, "confirmation_token",
580                                  input_data, input_data_size);
581   if (!hmac) {
582     LOG(ERROR) << "Could not calculate confirmation token hmac";
583     return KM_ERROR_UNKNOWN_ERROR;
584   }
585 
586   CHECK(hmac->size == keymaster::kConfirmationTokenSize)
587       << "Hmac size for confirmation UI must be "
588       << keymaster::kConfirmationTokenSize;
589 
590   std::vector<std::uint8_t> hmac_buffer(hmac->buffer,
591                                         hmac->buffer + hmac->size);
592 
593   const auto is_equal =
594       std::equal(hmac_buffer.cbegin(), hmac_buffer.cend(), confirmation_token);
595   return is_equal ? KM_ERROR_OK : KM_ERROR_NO_USER_CONFIRMATION;
596 }
597 
598 keymaster::RemoteProvisioningContext*
GetRemoteProvisioningContext() const599 TpmKeymasterContext::GetRemoteProvisioningContext() const {
600   return remote_provisioning_context_.get();
601 }
602 
ToHexString(const std::vector<uint8_t> & binary)603 std::string ToHexString(const std::vector<uint8_t>& binary) {
604   std::string hex;
605   hex.reserve(binary.size() * 2);
606   for (uint8_t byte : binary) {
607     char buf[8];
608     snprintf(buf, sizeof(buf), "%02x", byte);
609     hex.append(buf);
610   }
611   return hex;
612 }
613 
SetVerifiedBootInfo(std::string_view verified_boot_state,std::string_view bootloader_state,const std::vector<uint8_t> & vbmeta_digest)614 keymaster_error_t TpmKeymasterContext::SetVerifiedBootInfo(
615     std::string_view verified_boot_state, std::string_view bootloader_state,
616     const std::vector<uint8_t>& vbmeta_digest) {
617   if (verified_boot_state_ && verified_boot_state != *verified_boot_state_) {
618     LOG(ERROR) << "Invalid set verified boot state attempt. "
619                << "Old verified boot state: \"" << *verified_boot_state_
620                << "\","
621                << "new verified boot state: \"" << verified_boot_state << "\"";
622     return KM_ERROR_INVALID_ARGUMENT;
623   }
624   if (bootloader_state_ && bootloader_state != *bootloader_state_) {
625     LOG(ERROR) << "Invalid set bootloader state attempt. "
626                << "Old bootloader state: \"" << *bootloader_state_ << "\","
627                << "new bootloader state: \"" << bootloader_state << "\"";
628     return KM_ERROR_INVALID_ARGUMENT;
629   }
630   if (vbmeta_digest_ && vbmeta_digest != *vbmeta_digest_) {
631     LOG(ERROR) << "Invalid set vbmeta digest state attempt. "
632                << "Old vbmeta digest state: \"" << ToHexString(*vbmeta_digest_)
633                << "\","
634                << "new vbmeta digest state: \"" << ToHexString(vbmeta_digest)
635                << "\"";
636     return KM_ERROR_INVALID_ARGUMENT;
637   }
638   verified_boot_state_ = verified_boot_state;
639   bootloader_state_ = bootloader_state;
640   vbmeta_digest_ = vbmeta_digest;
641   attestation_context_->SetVerifiedBootInfo(verified_boot_state,
642                                             bootloader_state, vbmeta_digest);
643   remote_provisioning_context_->SetVerifiedBootInfo(
644       verified_boot_state, bootloader_state, vbmeta_digest);
645   return KM_ERROR_OK;
646 }
647 
SetVendorPatchlevel(uint32_t vendor_patchlevel)648 keymaster_error_t TpmKeymasterContext::SetVendorPatchlevel(
649     uint32_t vendor_patchlevel) {
650   if (vendor_patchlevel_.has_value() &&
651       vendor_patchlevel != vendor_patchlevel_.value()) {
652     // Can't set patchlevel to a different value.
653     LOG(ERROR) << "Invalid set vendor patchlevel attempt. Old patchlevel: \""
654                << *vendor_patchlevel_ << "\", new patchlevel: \""
655                << vendor_patchlevel << "\"";
656     return KM_ERROR_INVALID_ARGUMENT;
657   }
658   vendor_patchlevel_ = vendor_patchlevel;
659   remote_provisioning_context_->SetVendorPatchlevel(vendor_patchlevel);
660   return key_blob_maker_->SetVendorPatchlevel(*vendor_patchlevel_);
661 }
662 
SetBootPatchlevel(uint32_t boot_patchlevel)663 keymaster_error_t TpmKeymasterContext::SetBootPatchlevel(
664     uint32_t boot_patchlevel) {
665   if (boot_patchlevel_.has_value() &&
666       boot_patchlevel != boot_patchlevel_.value()) {
667     // Can't set patchlevel to a different value.
668     LOG(ERROR) << "Invalid set boot patchlevel attempt. Old patchlevel: \""
669                << *boot_patchlevel_ << "\", new patchlevel: \""
670                << boot_patchlevel << "\"";
671     return KM_ERROR_INVALID_ARGUMENT;
672   }
673   boot_patchlevel_ = boot_patchlevel;
674   remote_provisioning_context_->SetBootPatchlevel(boot_patchlevel);
675   return key_blob_maker_->SetBootPatchlevel(*boot_patchlevel_);
676 }
677 
GetVendorPatchlevel() const678 std::optional<uint32_t> TpmKeymasterContext::GetVendorPatchlevel() const {
679   return vendor_patchlevel_;
680 }
681 
GetBootPatchlevel() const682 std::optional<uint32_t> TpmKeymasterContext::GetBootPatchlevel() const {
683   return boot_patchlevel_;
684 }
685 
686 }  // namespace cuttlefish
687