blob: aa3447ea3b2db5956a1fa9c40727998f7927c080 [file] [log] [blame]
Andrew Sculldd077872021-06-01 10:22:07 +00001/*
2 * Copyright 2021, 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#define LOG_TAG "android.hardware.security.keymint-impl"
18#include "MicrodroidKeyMintDevice.h"
19
20#include <aidl/android/hardware/security/keymint/ErrorCode.h>
21#include <android-base/logging.h>
22#include <keymaster/android_keymaster.h>
23#include <keymaster/contexts/pure_soft_keymaster_context.h>
24#include <keymaster/keymaster_configuration.h>
25
26#include "AndroidKeyMintOperation.h"
27#include "KeyMintUtils.h"
28
29namespace aidl::android::hardware::security::keymint {
30
31using namespace keymaster; // NOLINT(google-build-using-namespace)
32
33using km_utils::authToken2AidlVec;
34using km_utils::kmBlob2vector;
35using km_utils::kmError2ScopedAStatus;
36using km_utils::kmParam2Aidl;
37using km_utils::KmParamSet;
38using km_utils::kmParamSet2Aidl;
39using km_utils::legacy_enum_conversion;
40using secureclock::TimeStampToken;
41
42namespace {
43
Andrew Sculla003f852021-07-06 16:09:07 +000044vector<KeyCharacteristics> convertKeyCharacteristics(const AuthorizationSet& requestParams,
Andrew Sculldd077872021-06-01 10:22:07 +000045 const AuthorizationSet& sw_enforced,
46 const AuthorizationSet& hw_enforced,
47 bool include_keystore_enforced = true) {
Andrew Sculla003f852021-07-06 16:09:07 +000048 KeyCharacteristics keyMintEnforced{SecurityLevel::SOFTWARE, {}};
Andrew Sculldd077872021-06-01 10:22:07 +000049 KeyCharacteristics keystoreEnforced{SecurityLevel::KEYSTORE, {}};
50 CHECK(hw_enforced.empty()) << "Hardware-enforced list is non-empty for pure SW KeyMint";
51
52 // This is a pure software implementation, so all tags are in sw_enforced.
53 // We need to walk through the SW-enforced list and figure out which tags to
54 // return in the software list and which in the keystore list.
55
56 for (auto& entry : sw_enforced) {
57 switch (entry.tag) {
58 /* Invalid and unused */
59 case KM_TAG_ECIES_SINGLE_HASH_MODE:
60 case KM_TAG_INVALID:
61 case KM_TAG_KDF:
62 case KM_TAG_ROLLBACK_RESISTANCE:
63 CHECK(false) << "We shouldn't see tag " << entry.tag;
64 break;
65
66 /* Unimplemented */
67 case KM_TAG_ALLOW_WHILE_ON_BODY:
68 case KM_TAG_BOOTLOADER_ONLY:
69 case KM_TAG_EARLY_BOOT_ONLY:
70 case KM_TAG_ROLLBACK_RESISTANT:
71 case KM_TAG_STORAGE_KEY:
72 case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED:
73 case KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED:
74 break;
75
76 /* Keystore-enforced if not locally generated. */
77 case KM_TAG_CREATION_DATETIME:
78 // A KeyMaster implementation is required to add this tag to generated/imported
79 // keys. A KeyMint implementation is not required to create this tag, only to echo
80 // it back if it was included in the key generation/import request.
81 if (requestParams.Contains(KM_TAG_CREATION_DATETIME)) {
82 keystoreEnforced.authorizations.push_back(kmParam2Aidl(entry));
83 }
84 break;
85
86 /* Disallowed in KeyCharacteristics */
87 case KM_TAG_APPLICATION_DATA:
88 case KM_TAG_ATTESTATION_APPLICATION_ID:
89 break;
90
91 /* Not key characteristics */
92 case KM_TAG_ASSOCIATED_DATA:
93 case KM_TAG_ATTESTATION_CHALLENGE:
94 case KM_TAG_ATTESTATION_ID_BRAND:
95 case KM_TAG_ATTESTATION_ID_DEVICE:
96 case KM_TAG_ATTESTATION_ID_IMEI:
97 case KM_TAG_ATTESTATION_ID_MANUFACTURER:
98 case KM_TAG_ATTESTATION_ID_MEID:
99 case KM_TAG_ATTESTATION_ID_MODEL:
100 case KM_TAG_ATTESTATION_ID_PRODUCT:
101 case KM_TAG_ATTESTATION_ID_SERIAL:
102 case KM_TAG_AUTH_TOKEN:
103 case KM_TAG_CERTIFICATE_SERIAL:
104 case KM_TAG_CERTIFICATE_SUBJECT:
105 case KM_TAG_CERTIFICATE_NOT_AFTER:
106 case KM_TAG_CERTIFICATE_NOT_BEFORE:
107 case KM_TAG_CONFIRMATION_TOKEN:
108 case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
109 case KM_TAG_IDENTITY_CREDENTIAL_KEY:
110 case KM_TAG_MAC_LENGTH:
111 case KM_TAG_NONCE:
112 case KM_TAG_RESET_SINCE_ID_ROTATION:
113 case KM_TAG_ROOT_OF_TRUST:
114 case KM_TAG_UNIQUE_ID:
115 break;
116
117 /* KeyMint-enforced */
118 case KM_TAG_ALGORITHM:
119 case KM_TAG_APPLICATION_ID:
120 case KM_TAG_AUTH_TIMEOUT:
121 case KM_TAG_BLOB_USAGE_REQUIREMENTS:
122 case KM_TAG_BLOCK_MODE:
123 case KM_TAG_BOOT_PATCHLEVEL:
124 case KM_TAG_CALLER_NONCE:
125 case KM_TAG_DIGEST:
126 case KM_TAG_EC_CURVE:
127 case KM_TAG_EXPORTABLE:
128 case KM_TAG_INCLUDE_UNIQUE_ID:
129 case KM_TAG_KEY_SIZE:
130 case KM_TAG_MAX_USES_PER_BOOT:
131 case KM_TAG_MIN_MAC_LENGTH:
132 case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
133 case KM_TAG_NO_AUTH_REQUIRED:
134 case KM_TAG_ORIGIN:
135 case KM_TAG_OS_PATCHLEVEL:
136 case KM_TAG_OS_VERSION:
137 case KM_TAG_PADDING:
138 case KM_TAG_PURPOSE:
139 case KM_TAG_RSA_OAEP_MGF_DIGEST:
140 case KM_TAG_RSA_PUBLIC_EXPONENT:
141 case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
142 case KM_TAG_USER_AUTH_TYPE:
143 case KM_TAG_USER_SECURE_ID:
144 case KM_TAG_VENDOR_PATCHLEVEL:
145 keyMintEnforced.authorizations.push_back(kmParam2Aidl(entry));
146 break;
147
148 /* Keystore-enforced */
149 case KM_TAG_ACTIVE_DATETIME:
150 case KM_TAG_ALL_APPLICATIONS:
151 case KM_TAG_ALL_USERS:
152 case KM_TAG_MAX_BOOT_LEVEL:
153 case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
154 case KM_TAG_USAGE_EXPIRE_DATETIME:
155 case KM_TAG_USER_ID:
156 case KM_TAG_USAGE_COUNT_LIMIT:
157 keystoreEnforced.authorizations.push_back(kmParam2Aidl(entry));
158 break;
159 }
160 }
161
162 vector<KeyCharacteristics> retval;
163 retval.reserve(2);
164 if (!keyMintEnforced.authorizations.empty()) retval.push_back(std::move(keyMintEnforced));
165 if (include_keystore_enforced && !keystoreEnforced.authorizations.empty()) {
166 retval.push_back(std::move(keystoreEnforced));
167 }
168
169 return retval;
170}
171
172Certificate convertCertificate(const keymaster_blob_t& cert) {
173 return {std::vector<uint8_t>(cert.data, cert.data + cert.data_length)};
174}
175
176vector<Certificate> convertCertificateChain(const CertificateChain& chain) {
177 vector<Certificate> retval;
178 retval.reserve(chain.entry_count);
179 std::transform(chain.begin(), chain.end(), std::back_inserter(retval), convertCertificate);
180 return retval;
181}
182
183void addClientAndAppData(const std::vector<uint8_t>& appId, const std::vector<uint8_t>& appData,
184 ::keymaster::AuthorizationSet* params) {
185 params->Clear();
186 if (appId.size()) {
187 params->push_back(::keymaster::TAG_APPLICATION_ID, appId.data(), appId.size());
188 }
189 if (appData.size()) {
190 params->push_back(::keymaster::TAG_APPLICATION_DATA, appData.data(), appData.size());
191 }
192}
193
194} // namespace
195
196constexpr size_t kOperationTableSize = 16;
197
Andrew Sculla003f852021-07-06 16:09:07 +0000198MicrodroidKeyMintDevice::MicrodroidKeyMintDevice()
Andrew Sculldd077872021-06-01 10:22:07 +0000199 : impl_(new ::keymaster::AndroidKeymaster(
200 [&]() -> auto {
Andrew Sculla003f852021-07-06 16:09:07 +0000201 auto context = new PureSoftKeymasterContext(KmVersion::KEYMINT_1,
202 KM_SECURITY_LEVEL_SOFTWARE);
Andrew Sculldd077872021-06-01 10:22:07 +0000203 context->SetSystemVersion(::keymaster::GetOsVersion(),
204 ::keymaster::GetOsPatchlevel());
205 return context;
206 }(),
Andrew Sculla003f852021-07-06 16:09:07 +0000207 kOperationTableSize)) {}
Andrew Sculldd077872021-06-01 10:22:07 +0000208
209MicrodroidKeyMintDevice::~MicrodroidKeyMintDevice() {}
210
211ScopedAStatus MicrodroidKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) {
212 info->versionNumber = 1;
Andrew Sculla003f852021-07-06 16:09:07 +0000213 info->securityLevel = SecurityLevel::SOFTWARE;
214 info->keyMintName = "MicrodroidKeyMintDevice";
Andrew Sculldd077872021-06-01 10:22:07 +0000215 info->keyMintAuthorName = "Google";
216 info->timestampTokenRequired = false;
217 return ScopedAStatus::ok();
218}
219
220ScopedAStatus MicrodroidKeyMintDevice::addRngEntropy(const vector<uint8_t>& data) {
221 if (data.size() == 0) {
222 return ScopedAStatus::ok();
223 }
224
225 AddEntropyRequest request(impl_->message_version());
226 request.random_data.Reinitialize(data.data(), data.size());
227
228 AddEntropyResponse response(impl_->message_version());
229 impl_->AddRngEntropy(request, &response);
230
231 return kmError2ScopedAStatus(response.error);
232}
233
234ScopedAStatus MicrodroidKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams,
235 const optional<AttestationKey>& attestationKey,
236 KeyCreationResult* creationResult) {
237 GenerateKeyRequest request(impl_->message_version());
238 request.key_description.Reinitialize(KmParamSet(keyParams));
239 if (attestationKey) {
240 request.attestation_signing_key_blob =
241 KeymasterKeyBlob(attestationKey->keyBlob.data(), attestationKey->keyBlob.size());
242 request.attest_key_params.Reinitialize(KmParamSet(attestationKey->attestKeyParams));
243 request.issuer_subject = KeymasterBlob(attestationKey->issuerSubjectName.data(),
244 attestationKey->issuerSubjectName.size());
245 }
246
247 GenerateKeyResponse response(impl_->message_version());
248 impl_->GenerateKey(request, &response);
249
250 if (response.error != KM_ERROR_OK) {
251 // Note a key difference between this current aidl and previous hal, is
252 // that hal returns void where as aidl returns the error status. If
253 // aidl returns error, then aidl will not return any change you may make
254 // to the out parameters. This is quite different from hal where all
255 // output variable can be modified due to hal returning void.
256 //
257 // So the caller need to be aware not to expect aidl functions to clear
258 // the output variables for you in case of error. If you left some
259 // wrong data set in the out parameters, they will stay there.
260 return kmError2ScopedAStatus(response.error);
261 }
262
263 creationResult->keyBlob = kmBlob2vector(response.key_blob);
264 creationResult->keyCharacteristics =
Andrew Sculla003f852021-07-06 16:09:07 +0000265 convertKeyCharacteristics(request.key_description, response.unenforced,
Andrew Sculldd077872021-06-01 10:22:07 +0000266 response.enforced);
267 creationResult->certificateChain = convertCertificateChain(response.certificate_chain);
268 return ScopedAStatus::ok();
269}
270
271ScopedAStatus MicrodroidKeyMintDevice::importKey(const vector<KeyParameter>& keyParams,
272 KeyFormat keyFormat,
273 const vector<uint8_t>& keyData,
274 const optional<AttestationKey>& attestationKey,
275 KeyCreationResult* creationResult) {
276 ImportKeyRequest request(impl_->message_version());
277 request.key_description.Reinitialize(KmParamSet(keyParams));
278 request.key_format = legacy_enum_conversion(keyFormat);
279 request.key_data = KeymasterKeyBlob(keyData.data(), keyData.size());
280 if (attestationKey) {
281 request.attestation_signing_key_blob =
282 KeymasterKeyBlob(attestationKey->keyBlob.data(), attestationKey->keyBlob.size());
283 request.attest_key_params.Reinitialize(KmParamSet(attestationKey->attestKeyParams));
284 request.issuer_subject = KeymasterBlob(attestationKey->issuerSubjectName.data(),
285 attestationKey->issuerSubjectName.size());
286 }
287
288 ImportKeyResponse response(impl_->message_version());
289 impl_->ImportKey(request, &response);
290
291 if (response.error != KM_ERROR_OK) {
292 return kmError2ScopedAStatus(response.error);
293 }
294
295 creationResult->keyBlob = kmBlob2vector(response.key_blob);
296 creationResult->keyCharacteristics =
Andrew Sculla003f852021-07-06 16:09:07 +0000297 convertKeyCharacteristics(request.key_description, response.unenforced,
Andrew Sculldd077872021-06-01 10:22:07 +0000298 response.enforced);
299 creationResult->certificateChain = convertCertificateChain(response.certificate_chain);
300
301 return ScopedAStatus::ok();
302}
303
304ScopedAStatus MicrodroidKeyMintDevice::importWrappedKey(
Andrew Sculla003f852021-07-06 16:09:07 +0000305 const vector<uint8_t>& wrappedKeyData, const vector<uint8_t>& wrappingKeyBlob,
306 const vector<uint8_t>& maskingKey, const vector<KeyParameter>& unwrappingParams,
307 int64_t passwordSid, int64_t biometricSid, KeyCreationResult* creationResult) {
Andrew Sculldd077872021-06-01 10:22:07 +0000308 ImportWrappedKeyRequest request(impl_->message_version());
309 request.SetWrappedMaterial(wrappedKeyData.data(), wrappedKeyData.size());
310 request.SetWrappingMaterial(wrappingKeyBlob.data(), wrappingKeyBlob.size());
311 request.SetMaskingKeyMaterial(maskingKey.data(), maskingKey.size());
312 request.additional_params.Reinitialize(KmParamSet(unwrappingParams));
313 request.password_sid = static_cast<uint64_t>(passwordSid);
314 request.biometric_sid = static_cast<uint64_t>(biometricSid);
315
316 ImportWrappedKeyResponse response(impl_->message_version());
317 impl_->ImportWrappedKey(request, &response);
318
319 if (response.error != KM_ERROR_OK) {
320 return kmError2ScopedAStatus(response.error);
321 }
322
323 creationResult->keyBlob = kmBlob2vector(response.key_blob);
324 creationResult->keyCharacteristics =
Andrew Sculla003f852021-07-06 16:09:07 +0000325 convertKeyCharacteristics(request.additional_params, response.unenforced,
326 response.enforced);
Andrew Sculldd077872021-06-01 10:22:07 +0000327 creationResult->certificateChain = convertCertificateChain(response.certificate_chain);
328
329 return ScopedAStatus::ok();
330}
331
332ScopedAStatus MicrodroidKeyMintDevice::upgradeKey(const vector<uint8_t>& keyBlobToUpgrade,
333 const vector<KeyParameter>& upgradeParams,
334 vector<uint8_t>* keyBlob) {
335 UpgradeKeyRequest request(impl_->message_version());
336 request.SetKeyMaterial(keyBlobToUpgrade.data(), keyBlobToUpgrade.size());
337 request.upgrade_params.Reinitialize(KmParamSet(upgradeParams));
338
339 UpgradeKeyResponse response(impl_->message_version());
340 impl_->UpgradeKey(request, &response);
341
342 if (response.error != KM_ERROR_OK) {
343 return kmError2ScopedAStatus(response.error);
344 }
345
346 *keyBlob = kmBlob2vector(response.upgraded_key);
347 return ScopedAStatus::ok();
348}
349
Andrew Sculla003f852021-07-06 16:09:07 +0000350ScopedAStatus MicrodroidKeyMintDevice::deleteKey(const vector<uint8_t>&) {
351 // There's nothing to be done to delete software key blobs.
352 return kmError2ScopedAStatus(KM_ERROR_OK);
Andrew Sculldd077872021-06-01 10:22:07 +0000353}
354
355ScopedAStatus MicrodroidKeyMintDevice::deleteAllKeys() {
356 // There's nothing to be done to delete software key blobs.
Andrew Sculla003f852021-07-06 16:09:07 +0000357 return kmError2ScopedAStatus(KM_ERROR_OK);
Andrew Sculldd077872021-06-01 10:22:07 +0000358}
359
360ScopedAStatus MicrodroidKeyMintDevice::destroyAttestationIds() {
361 return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
362}
363
364ScopedAStatus MicrodroidKeyMintDevice::begin(KeyPurpose purpose, const vector<uint8_t>& keyBlob,
365 const vector<KeyParameter>& params,
366 const optional<HardwareAuthToken>& authToken,
367 BeginResult* result) {
368 BeginOperationRequest request(impl_->message_version());
369 request.purpose = legacy_enum_conversion(purpose);
370 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
371 request.additional_params.Reinitialize(KmParamSet(params));
372
373 vector<uint8_t> vector_token = authToken2AidlVec(authToken);
374 request.additional_params.push_back(TAG_AUTH_TOKEN,
375 reinterpret_cast<uint8_t*>(vector_token.data()),
376 vector_token.size());
377
378 BeginOperationResponse response(impl_->message_version());
379 impl_->BeginOperation(request, &response);
380
381 if (response.error != KM_ERROR_OK) {
382 return kmError2ScopedAStatus(response.error);
383 }
384
385 result->params = kmParamSet2Aidl(response.output_params);
386 result->challenge = response.op_handle;
387 result->operation =
388 ndk::SharedRefBase::make<AndroidKeyMintOperation>(impl_, response.op_handle);
389 return ScopedAStatus::ok();
390}
391
392ScopedAStatus MicrodroidKeyMintDevice::deviceLocked(
Andrew Sculla003f852021-07-06 16:09:07 +0000393 bool, const std::optional<secureclock::TimeStampToken>&) {
394 // Microdroid doesn't yet have a concept of a locked device.
395 return kmError2ScopedAStatus(KM_ERROR_OK);
Andrew Sculldd077872021-06-01 10:22:07 +0000396}
397
398ScopedAStatus MicrodroidKeyMintDevice::earlyBootEnded() {
Andrew Sculla003f852021-07-06 16:09:07 +0000399 return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
Andrew Sculldd077872021-06-01 10:22:07 +0000400}
401
402ScopedAStatus MicrodroidKeyMintDevice::convertStorageKeyToEphemeral(
403 const std::vector<uint8_t>& /* storageKeyBlob */,
404 std::vector<uint8_t>* /* ephemeralKeyBlob */) {
405 return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
406}
407
408ScopedAStatus MicrodroidKeyMintDevice::getKeyCharacteristics(
409 const std::vector<uint8_t>& keyBlob, const std::vector<uint8_t>& appId,
410 const std::vector<uint8_t>& appData, std::vector<KeyCharacteristics>* keyCharacteristics) {
411 GetKeyCharacteristicsRequest request(impl_->message_version());
412 request.SetKeyMaterial(keyBlob.data(), keyBlob.size());
413 addClientAndAppData(appId, appData, &request.additional_params);
414
415 GetKeyCharacteristicsResponse response(impl_->message_version());
416 impl_->GetKeyCharacteristics(request, &response);
417
418 if (response.error != KM_ERROR_OK) {
419 return kmError2ScopedAStatus(response.error);
420 }
421
422 AuthorizationSet emptySet;
Andrew Sculla003f852021-07-06 16:09:07 +0000423 *keyCharacteristics =
424 convertKeyCharacteristics(emptySet, response.unenforced, response.enforced,
425 /* include_keystore_enforced = */ false);
Andrew Sculldd077872021-06-01 10:22:07 +0000426
427 return ScopedAStatus::ok();
428}
429
Andrew Sculldd077872021-06-01 10:22:07 +0000430} // namespace aidl::android::hardware::security::keymint