• 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 
30 #include "host/commands/secure_env/tpm_attestation_record.h"
31 #include "host/commands/secure_env/tpm_random_source.h"
32 #include "host/commands/secure_env/tpm_key_blob_maker.h"
33 
34 using keymaster::AuthorizationSet;
35 using keymaster::KeymasterKeyBlob;
36 using keymaster::KeyFactory;
37 using keymaster::OperationFactory;
38 
TpmKeymasterContext(TpmResourceManager & resource_manager,keymaster::KeymasterEnforcement & enforcement)39 TpmKeymasterContext::TpmKeymasterContext(
40     TpmResourceManager& resource_manager,
41     keymaster::KeymasterEnforcement& enforcement)
42     : resource_manager_(resource_manager)
43     , enforcement_(enforcement)
44     , key_blob_maker_(new TpmKeyBlobMaker(resource_manager_))
45     , random_source_(new TpmRandomSource(resource_manager_.Esys()))
46     , attestation_context_(new TpmAttestationRecordContext()) {
47   key_factories_.emplace(
48       KM_ALGORITHM_RSA, new keymaster::RsaKeyFactory(*key_blob_maker_, *this));
49   key_factories_.emplace(
50       KM_ALGORITHM_EC, new keymaster::EcKeyFactory(*key_blob_maker_, *this));
51   key_factories_.emplace(
52       KM_ALGORITHM_AES,
53       new keymaster::AesKeyFactory(*key_blob_maker_, *random_source_));
54   key_factories_.emplace(
55       KM_ALGORITHM_TRIPLE_DES,
56       new keymaster::TripleDesKeyFactory(*key_blob_maker_, *random_source_));
57   key_factories_.emplace(
58       KM_ALGORITHM_HMAC,
59       new keymaster::HmacKeyFactory(*key_blob_maker_, *random_source_));
60   for (const auto& it : key_factories_) {
61     supported_algorithms_.push_back(it.first);
62   }
63 }
64 
SetSystemVersion(uint32_t os_version,uint32_t os_patchlevel)65 keymaster_error_t TpmKeymasterContext::SetSystemVersion(
66     uint32_t os_version, uint32_t os_patchlevel) {
67   // TODO(b/155697375): Only accept new values of these from the bootloader
68   os_version_ = os_version;
69   os_patchlevel_ = os_patchlevel;
70   key_blob_maker_->SetSystemVersion(os_version, os_patchlevel);
71   return KM_ERROR_OK;
72 }
73 
GetSystemVersion(uint32_t * os_version,uint32_t * os_patchlevel) const74 void TpmKeymasterContext::GetSystemVersion(
75     uint32_t* os_version, uint32_t* os_patchlevel) const {
76   *os_version = os_version_;
77   *os_patchlevel = os_patchlevel_;
78 }
79 
GetKeyFactory(keymaster_algorithm_t algorithm) const80 const KeyFactory* TpmKeymasterContext::GetKeyFactory(
81     keymaster_algorithm_t algorithm) const {
82   auto it = key_factories_.find(algorithm);
83   if (it == key_factories_.end()) {
84     LOG(ERROR) << "Could not find key factory for " << algorithm;
85     return nullptr;
86   }
87   return it->second.get();
88 }
89 
GetOperationFactory(keymaster_algorithm_t algorithm,keymaster_purpose_t purpose) const90 const OperationFactory* TpmKeymasterContext::GetOperationFactory(
91     keymaster_algorithm_t algorithm, keymaster_purpose_t purpose) const {
92   auto key_factory = GetKeyFactory(algorithm);
93   if (key_factory == nullptr) {
94     LOG(ERROR) << "Tried to get operation factory for " << purpose
95               << " for invalid algorithm " << algorithm;
96     return nullptr;
97   }
98   auto operation_factory = key_factory->GetOperationFactory(purpose);
99   if (operation_factory == nullptr) {
100     LOG(ERROR) << "Could not get operation factory for " << purpose
101                << " from key factory for " << algorithm;
102   }
103   return operation_factory;
104 }
105 
GetSupportedAlgorithms(size_t * algorithms_count) const106 const keymaster_algorithm_t* TpmKeymasterContext::GetSupportedAlgorithms(
107       size_t* algorithms_count) const {
108   *algorithms_count = supported_algorithms_.size();
109   return supported_algorithms_.data();
110 }
111 
112 // Based on https://cs.android.com/android/platform/superproject/+/master:system/keymaster/key_blob_utils/software_keyblobs.cpp;l=44;drc=master
113 
UpgradeIntegerTag(keymaster_tag_t tag,uint32_t value,AuthorizationSet * set,bool * set_changed)114 static bool UpgradeIntegerTag(
115     keymaster_tag_t tag,
116     uint32_t value,
117     AuthorizationSet* set,
118     bool* set_changed) {
119   int index = set->find(tag);
120   if (index == -1) {
121     keymaster_key_param_t param;
122     param.tag = tag;
123     param.integer = value;
124     set->push_back(param);
125     *set_changed = true;
126     return true;
127   }
128 
129   if (set->params[index].integer > value) {
130     return false;
131   }
132 
133   if (set->params[index].integer != value) {
134     set->params[index].integer = value;
135     *set_changed = true;
136   }
137   return true;
138 }
139 
140 // Based on https://cs.android.com/android/platform/superproject/+/master:system/keymaster/key_blob_utils/software_keyblobs.cpp;l=310;drc=master
141 
UpgradeKeyBlob(const KeymasterKeyBlob & blob_to_upgrade,const AuthorizationSet & upgrade_params,KeymasterKeyBlob * upgraded_key) const142 keymaster_error_t TpmKeymasterContext::UpgradeKeyBlob(
143     const KeymasterKeyBlob& blob_to_upgrade,
144     const AuthorizationSet& upgrade_params,
145     KeymasterKeyBlob* upgraded_key) const {
146   keymaster::UniquePtr<keymaster::Key> key;
147   auto error = ParseKeyBlob(blob_to_upgrade, upgrade_params, &key);
148   if (error != KM_ERROR_OK) {
149     LOG(ERROR) << "Failed to parse key blob";
150     return error;
151   }
152 
153   bool set_changed = false;
154 
155   if (os_version_ == 0) {
156     // We need to allow "upgrading" OS version to zero, to support upgrading
157     // from proper numbered releases to unnumbered development and preview
158     // releases.
159 
160     int key_os_version_pos = key->hw_enforced().find(keymaster::TAG_OS_VERSION);
161     if (key_os_version_pos != -1) {
162       uint32_t key_os_version = key->hw_enforced()[key_os_version_pos].integer;
163       if (key_os_version != 0) {
164         key->hw_enforced()[key_os_version_pos].integer = os_version_;
165         set_changed = true;
166       }
167     }
168   }
169 
170   auto update_os = UpgradeIntegerTag(keymaster::TAG_OS_VERSION, os_version_,
171                                      &key->hw_enforced(), &set_changed);
172 
173   auto update_patchlevel =
174       UpgradeIntegerTag(keymaster::TAG_OS_PATCHLEVEL, os_patchlevel_,
175                         &key->hw_enforced(), &set_changed);
176 
177   if (!update_os || !update_patchlevel) {
178     LOG(ERROR) << "One of the version fields would have been a downgrade. "
179                << "Not allowed.";
180     return KM_ERROR_INVALID_ARGUMENT;
181   }
182 
183   if (!set_changed) {
184     // Don't need an upgrade.
185     return KM_ERROR_OK;
186   }
187 
188   return key_blob_maker_->UnvalidatedCreateKeyBlob(
189       key->key_material(), key->hw_enforced(), key->sw_enforced(),
190       upgraded_key);
191 }
192 
ParseKeyBlob(const KeymasterKeyBlob & blob,const AuthorizationSet & additional_params,keymaster::UniquePtr<keymaster::Key> * key) const193 keymaster_error_t TpmKeymasterContext::ParseKeyBlob(
194     const KeymasterKeyBlob& blob,
195     const AuthorizationSet& additional_params,
196     keymaster::UniquePtr<keymaster::Key>* key) const {
197   keymaster::AuthorizationSet hw_enforced;
198   keymaster::AuthorizationSet sw_enforced;
199   keymaster::KeymasterKeyBlob key_material;
200 
201   auto rc =
202       key_blob_maker_->UnwrapKeyBlob(
203           blob,
204           &hw_enforced,
205           &sw_enforced,
206           &key_material);
207   if (rc != KM_ERROR_OK) {
208     LOG(ERROR) << "Failed to unwrap key: " << rc;
209     return rc;
210   }
211 
212   keymaster_algorithm_t algorithm;
213   if (!hw_enforced.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm) &&
214       !sw_enforced.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm)) {
215     LOG(ERROR) << "No TAG_ALGORITHM value in hw_enforced or sw_enforced.";
216     return KM_ERROR_UNKNOWN_ERROR;
217   }
218 
219   auto factory = GetKeyFactory(algorithm);
220   if (factory == nullptr) {
221     LOG(ERROR) << "Unable to find key factory for " << algorithm;
222     return KM_ERROR_UNSUPPORTED_ALGORITHM;
223   }
224   rc =
225       factory->LoadKey(
226           std::move(key_material),
227           additional_params,
228           std::move(hw_enforced),
229           std::move(sw_enforced),
230           key);
231   if (rc != KM_ERROR_OK) {
232     LOG(ERROR) << "Unable to load unwrapped key: " << rc;
233   }
234   return rc;
235 }
236 
AddRngEntropy(const uint8_t * buffer,size_t size) const237 keymaster_error_t TpmKeymasterContext::AddRngEntropy(
238     const uint8_t* buffer, size_t size) const {
239   return random_source_->AddRngEntropy(buffer, size);
240 }
241 
enforcement_policy()242 keymaster::KeymasterEnforcement* TpmKeymasterContext::enforcement_policy() {
243   return &enforcement_;
244 }
245 
246 // Based on https://cs.android.com/android/platform/superproject/+/master:system/keymaster/contexts/pure_soft_keymaster_context.cpp;l=261;drc=8367d5351c4d417a11f49b12394b63a413faa02d
247 
GenerateAttestation(const keymaster::Key & key,const keymaster::AuthorizationSet & attest_params,keymaster::UniquePtr<keymaster::Key>,const keymaster::KeymasterBlob &,keymaster_error_t * error) const248 keymaster::CertificateChain TpmKeymasterContext::GenerateAttestation(
249     const keymaster::Key& key, const keymaster::AuthorizationSet& attest_params,
250     keymaster::UniquePtr<keymaster::Key> /* attest_key */,
251     const keymaster::KeymasterBlob& /* issuer_subject */,
252     keymaster_error_t* error) const {
253   LOG(INFO) << "TODO(b/155697200): Link attestation back to the TPM";
254   keymaster_algorithm_t key_algorithm;
255   if (!key.authorizations().GetTagValue(keymaster::TAG_ALGORITHM,
256                                         &key_algorithm)) {
257     *error = KM_ERROR_UNKNOWN_ERROR;
258     return {};
259   }
260 
261   if ((key_algorithm != KM_ALGORITHM_RSA && key_algorithm != KM_ALGORITHM_EC)) {
262     *error = KM_ERROR_INCOMPATIBLE_ALGORITHM;
263     return {};
264   }
265 
266   // We have established that the given key has the correct algorithm, and
267   // because this is the TpmKeymasterContext we can assume that the Key is an
268   // AsymmetricKey. So we can downcast.
269   const keymaster::AsymmetricKey& asymmetric_key =
270       static_cast<const keymaster::AsymmetricKey&>(key);
271 
272   // DEVICE_UNIQUE_ATTESTATION is only allowed for strongbox devices. See
273   // hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl:845
274   // at commit beefae4790ccd4f1ee75ea69603d4c9c2a45c0aa .
275   // While the specification says to return ErrorCode::INVALID_ARGUMENT , the
276   // relevant VTS test actually tests for ErrorCode::UNIMPLEMENTED . See
277   // hardware/interfaces/keymaster/4.1/vts/functional/DeviceUniqueAttestationTest.cpp:203
278   // at commit 36dcf1a404a9cf07ca5a2a6ad92371507194fe1b .
279   if (attest_params.find(keymaster::TAG_DEVICE_UNIQUE_ATTESTATION) != -1) {
280     *error = KM_ERROR_UNIMPLEMENTED;
281     return {};
282   }
283 
284   return keymaster::generate_attestation(asymmetric_key, attest_params,
285                                          {} /* attest_key */,
286                                          *attestation_context_, error);
287 }
288 
GenerateSelfSignedCertificate(const keymaster::Key & key,const keymaster::AuthorizationSet & cert_params,bool fake_signature,keymaster_error_t * error) const289 keymaster::CertificateChain TpmKeymasterContext::GenerateSelfSignedCertificate(
290     const keymaster::Key& key, const keymaster::AuthorizationSet& cert_params,
291     bool fake_signature, keymaster_error_t* error) const {
292   keymaster_algorithm_t key_algorithm;
293   if (!key.authorizations().GetTagValue(keymaster::TAG_ALGORITHM, &key_algorithm)) {
294       *error = KM_ERROR_UNKNOWN_ERROR;
295       return {};
296   }
297 
298   if ((key_algorithm != KM_ALGORITHM_RSA && key_algorithm != KM_ALGORITHM_EC)) {
299       *error = KM_ERROR_INCOMPATIBLE_ALGORITHM;
300       return {};
301   }
302 
303   // We have established that the given key has the correct algorithm, and because this is the
304   // SoftKeymasterContext we can assume that the Key is an AsymmetricKey. So we can downcast.
305   const keymaster::AsymmetricKey& asymmetric_key =
306       static_cast<const keymaster::AsymmetricKey&>(key);
307 
308   return generate_self_signed_cert(asymmetric_key, cert_params, fake_signature, error);
309 }
310 
UnwrapKey(const KeymasterKeyBlob &,const KeymasterKeyBlob &,const AuthorizationSet &,const KeymasterKeyBlob &,AuthorizationSet *,keymaster_key_format_t *,KeymasterKeyBlob *) const311 keymaster_error_t TpmKeymasterContext::UnwrapKey(
312     const KeymasterKeyBlob&,
313     const KeymasterKeyBlob&,
314     const AuthorizationSet&,
315     const KeymasterKeyBlob&,
316     AuthorizationSet*,
317     keymaster_key_format_t*,
318     KeymasterKeyBlob*) const {
319   LOG(ERROR) << "TODO(b/155697375): Implement UnwrapKey";
320   return KM_ERROR_UNIMPLEMENTED;
321 }
322