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