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