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