diff options
author | Shawn Willden <swillden@google.com> | 2021-04-22 13:32:56 -0600 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2021-06-14 14:33:00 -0600 |
commit | 5bd73cceb57e937f9f6aa21a2540236c2459a502 (patch) | |
tree | 88a11eb46463cc9b7029b5253f8bf489fecf8266 | |
parent | 8f654d8a99738d096e2a7bf87324a515ec0c33bc (diff) | |
download | core-5bd73cceb57e937f9f6aa21a2540236c2459a502.tar.gz |
Add TrustyKeyMintDevice
Ignore-AOSP-First: No merge path from AOSP
Bug: 177729159
Test: Not testable until more CLs land
Change-Id: Iea4e70bb5b4ce051492f2e42d2e0d219d088388e
17 files changed, 981 insertions, 18 deletions
diff --git a/trusty/keymaster/3.0/service.cpp b/trusty/keymaster/3.0/service.cpp index 0d8436eff..b916c3760 100644 --- a/trusty/keymaster/3.0/service.cpp +++ b/trusty/keymaster/3.0/service.cpp @@ -24,7 +24,7 @@ int main() { ::android::hardware::configureRpcThreadpool(1, true); auto trustyKeymaster = new keymaster::TrustyKeymaster(); - int err = trustyKeymaster->Initialize(); + int err = trustyKeymaster->Initialize(keymaster::KmVersion::KEYMASTER_3); if (err != 0) { LOG(FATAL) << "Could not initialize TrustyKeymaster (" << err << ")"; return -1; diff --git a/trusty/keymaster/4.0/service.cpp b/trusty/keymaster/4.0/service.cpp index 96eb58422..0e5144dfb 100644 --- a/trusty/keymaster/4.0/service.cpp +++ b/trusty/keymaster/4.0/service.cpp @@ -24,7 +24,7 @@ int main() { ::android::hardware::configureRpcThreadpool(1, true); auto trustyKeymaster = new keymaster::TrustyKeymaster(); - int err = trustyKeymaster->Initialize(); + int err = trustyKeymaster->Initialize(keymaster::KmVersion::KEYMASTER_4); if (err != 0) { LOG(FATAL) << "Could not initialize TrustyKeymaster (" << err << ")"; return -1; diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp index 6d24e8497..58dfa9400 100644 --- a/trusty/keymaster/Android.bp +++ b/trusty/keymaster/Android.bp @@ -80,6 +80,49 @@ cc_binary { vintf_fragments: ["4.0/android.hardware.keymaster@4.0-service.trusty.xml"], } +cc_binary { + name: "android.hardware.security.keymint-service.trusty", + relative_install_path: "hw", + init_rc: ["keymint/android.hardware.security.keymint-service.trusty.rc"], + vintf_fragments: [ + "keymint/android.hardware.security.keymint-service.trusty.xml", + ], + vendor: true, + cflags: [ + "-Wall", + "-Wextra", + ], + local_include_dirs: [ + "include", + ], + srcs: [ + "TrustyKeymaster.cpp", + "ipc/trusty_keymaster_ipc.cpp", + "keymint/TrustyKeyMintDevice.cpp", + "keymint/TrustyKeyMintOperation.cpp", + "keymint/TrustySecureClock.cpp", + "keymint/TrustySharedSecret.cpp", + "keymint/service.cpp", + ], + shared_libs: [ + "android.hardware.security.keymint-V1-ndk_platform", + "android.hardware.security.secureclock-V1-ndk_platform", + "android.hardware.security.sharedsecret-V1-ndk_platform", + "lib_android_keymaster_keymint_utils", + "libbase", + "libbinder_ndk", + "libhardware", + "libkeymaster_messages", + "libkeymint", + "liblog", + "libtrusty", + ], + required: [ + "RemoteProvisioner", + "android.hardware.hardware_keystore.xml", + ], +} + prebuilt_etc { name: "keymaster_soft_attestation_keys.xml", vendor: true, diff --git a/trusty/keymaster/TrustyKeymaster.cpp b/trusty/keymaster/TrustyKeymaster.cpp index 23e04334c..ef5fc3fc2 100644 --- a/trusty/keymaster/TrustyKeymaster.cpp +++ b/trusty/keymaster/TrustyKeymaster.cpp @@ -14,7 +14,9 @@ * limitations under the License. */ -#include <cutils/log.h> +#define LOG_TAG "trusty_keymaster_hal" +#include <android-base/logging.h> + #include <keymaster/android_keymaster_messages.h> #include <keymaster/keymaster_configuration.h> #include <trusty_keymaster/TrustyKeymaster.h> @@ -22,24 +24,28 @@ namespace keymaster { -int TrustyKeymaster::Initialize() { +int TrustyKeymaster::Initialize(KmVersion version) { int err; + LOG(INFO) << "Initializing TrustyKeymaster as KmVersion: " << (int)version; + err = trusty_keymaster_connect(); if (err) { - ALOGE("Failed to connect to trusty keymaster %d", err); + LOG(ERROR) << "Failed to connect to trusty keymaster (1st try)" << err; return err; } // Try GetVersion2 first. GetVersion2Request versionReq; + versionReq.max_message_version = MessageVersion(version); GetVersion2Response versionRsp = GetVersion2(versionReq); if (versionRsp.error != KM_ERROR_OK) { - ALOGW("TA appears not to support GetVersion2, falling back (err = %d)", versionRsp.error); + LOG(WARNING) << "TA appears not to support GetVersion2, falling back (err = " + << versionRsp.error << ")"; err = trusty_keymaster_connect(); if (err) { - ALOGE("Failed to connect to trusty keymaster %d", err); + LOG(FATAL) << "Failed to connect to trusty keymaster (2nd try) " << err; return err; } @@ -47,13 +53,13 @@ int TrustyKeymaster::Initialize() { GetVersionResponse versionRsp; GetVersion(versionReq, &versionRsp); if (versionRsp.error != KM_ERROR_OK) { - ALOGE("Failed to get TA version %d", versionRsp.error); + LOG(FATAL) << "Failed to get TA version " << versionRsp.error; return -1; } else { keymaster_error_t error; message_version_ = NegotiateMessageVersion(versionRsp, &error); if (error != KM_ERROR_OK) { - ALOGE("Failed to negotiate message version %d", error); + LOG(FATAL) << "Failed to negotiate message version " << error; return -1; } } @@ -69,7 +75,7 @@ int TrustyKeymaster::Initialize() { Configure(req, &rsp); if (rsp.error != KM_ERROR_OK) { - ALOGE("Failed to configure keymaster %d", rsp.error); + LOG(FATAL) << "Failed to configure keymaster " << rsp.error; return -1; } @@ -87,7 +93,7 @@ static void ForwardCommand(enum keymaster_command command, const KeymasterMessag keymaster_error_t err; err = trusty_keymaster_send(command, req, rsp); if (err != KM_ERROR_OK) { - ALOGE("Failed to send cmd %d err: %d", command, err); + LOG(ERROR) << "Cmd " << command << " returned error: " << err; rsp->error = err; } } @@ -137,14 +143,19 @@ void TrustyKeymaster::Configure(const ConfigureRequest& request, ConfigureRespon void TrustyKeymaster::GenerateKey(const GenerateKeyRequest& request, GenerateKeyResponse* response) { - GenerateKeyRequest datedRequest(request.message_version); - datedRequest.key_description = request.key_description; + if (message_version_ < 4) { + // Pre-KeyMint we need to add TAG_CREATION_DATETIME if not provided by the caller. + GenerateKeyRequest datedRequest(request.message_version); + datedRequest.key_description = request.key_description; - if (!request.key_description.Contains(TAG_CREATION_DATETIME)) { - datedRequest.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); - } + if (!request.key_description.Contains(TAG_CREATION_DATETIME)) { + datedRequest.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL))); + } - ForwardCommand(KM_GENERATE_KEY, datedRequest, response); + ForwardCommand(KM_GENERATE_KEY, datedRequest, response); + } else { + ForwardCommand(KM_GENERATE_KEY, request, response); + } } void TrustyKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request, @@ -229,4 +240,16 @@ GetVersion2Response TrustyKeymaster::GetVersion2(const GetVersion2Request& reque return response; } +EarlyBootEndedResponse TrustyKeymaster::EarlyBootEnded() { + EarlyBootEndedResponse response(message_version()); + ForwardCommand(KM_EARLY_BOOT_ENDED, EarlyBootEndedRequest(message_version()), &response); + return response; +} + +DeviceLockedResponse TrustyKeymaster::DeviceLocked(const DeviceLockedRequest& request) { + DeviceLockedResponse response(message_version()); + ForwardCommand(KM_DEVICE_LOCKED, request, &response); + return response; +} + } // namespace keymaster diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h new file mode 100644 index 000000000..5fd628f3c --- /dev/null +++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h @@ -0,0 +1,88 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/security/keymint/BnKeyMintDevice.h> +#include <aidl/android/hardware/security/keymint/BnKeyMintOperation.h> +#include <aidl/android/hardware/security/keymint/HardwareAuthToken.h> + +#include <trusty_keymaster/TrustyKeymaster.h> + +namespace aidl::android::hardware::security::keymint::trusty { + +using ::keymaster::TrustyKeymaster; +using ::ndk::ScopedAStatus; +using secureclock::TimeStampToken; +using ::std::optional; +using ::std::shared_ptr; +using ::std::vector; + +class TrustyKeyMintDevice : public BnKeyMintDevice { + public: + explicit TrustyKeyMintDevice(shared_ptr<TrustyKeymaster> impl) : impl_(std::move(impl)) {} + virtual ~TrustyKeyMintDevice() = default; + + ScopedAStatus getHardwareInfo(KeyMintHardwareInfo* info) override; + + ScopedAStatus addRngEntropy(const vector<uint8_t>& data) override; + + ScopedAStatus generateKey(const vector<KeyParameter>& keyParams, + const optional<AttestationKey>& attestationKey, + KeyCreationResult* creationResult) override; + + ScopedAStatus getKeyCharacteristics(const vector<uint8_t>& keyBlob, + const vector<uint8_t>& clientId, + const vector<uint8_t>& appData, + vector<KeyCharacteristics>* characteristics) override; + + ScopedAStatus importKey(const vector<KeyParameter>& keyParams, KeyFormat keyFormat, + const vector<uint8_t>& keyData, + const optional<AttestationKey>& attestationKey, + KeyCreationResult* creationResult) override; + + ScopedAStatus importWrappedKey(const vector<uint8_t>& wrappedKeyData, + const vector<uint8_t>& wrappingKeyBlob, + const vector<uint8_t>& maskingKey, + const vector<KeyParameter>& unwrappingParams, + int64_t passwordSid, int64_t biometricSid, + KeyCreationResult* creationResult) override; + + ScopedAStatus upgradeKey(const vector<uint8_t>& keyBlobToUpgrade, + const vector<KeyParameter>& upgradeParams, + vector<uint8_t>* keyBlob) override; + + ScopedAStatus deleteKey(const vector<uint8_t>& keyBlob) override; + ScopedAStatus deleteAllKeys() override; + ScopedAStatus destroyAttestationIds() override; + + ScopedAStatus begin(KeyPurpose purpose, const vector<uint8_t>& keyBlob, + const vector<KeyParameter>& params, + const optional<HardwareAuthToken>& authToken, BeginResult* result) override; + + ScopedAStatus deviceLocked(bool passwordOnly, + const optional<TimeStampToken>& timestampToken) override; + ScopedAStatus earlyBootEnded() override; + + ScopedAStatus convertStorageKeyToEphemeral(const std::vector<uint8_t>& storageKeyBlob, + std::vector<uint8_t>* ephemeralKeyBlob) override; + + protected: + std::shared_ptr<TrustyKeymaster> impl_; + SecurityLevel securityLevel_; +}; + +} // namespace aidl::android::hardware::security::keymint::trusty diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintOperation.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintOperation.h new file mode 100644 index 000000000..65fd2f5b8 --- /dev/null +++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintOperation.h @@ -0,0 +1,64 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/security/keymint/BnKeyMintOperation.h> +#include <aidl/android/hardware/security/secureclock/ISecureClock.h> + +#include <trusty_keymaster/TrustyKeymaster.h> + +#include <hardware/keymaster_defs.h> + +namespace aidl::android::hardware::security::keymint { + +using ::keymaster::TrustyKeymaster; +using ::ndk::ScopedAStatus; +using secureclock::TimeStampToken; +using std::optional; +using std::shared_ptr; +using std::string; +using std::vector; + +class TrustyKeyMintOperation : public BnKeyMintOperation { + public: + explicit TrustyKeyMintOperation(shared_ptr<TrustyKeymaster> implementation, + keymaster_operation_handle_t opHandle); + virtual ~TrustyKeyMintOperation(); + + ScopedAStatus updateAad(const vector<uint8_t>& input, + const optional<HardwareAuthToken>& authToken, + const optional<TimeStampToken>& timestampToken) override; + + ScopedAStatus update(const vector<uint8_t>& input, const optional<HardwareAuthToken>& authToken, + const optional<TimeStampToken>& timestampToken, + vector<uint8_t>* output) override; + + ScopedAStatus finish(const optional<vector<uint8_t>>& input, // + const optional<vector<uint8_t>>& signature, // + const optional<HardwareAuthToken>& authToken, // + const optional<TimeStampToken>& timestampToken, + const optional<vector<uint8_t>>& confirmationToken, + vector<uint8_t>* output) override; + + ScopedAStatus abort() override; + + protected: + std::shared_ptr<TrustyKeymaster> impl_; + keymaster_operation_handle_t opHandle_; +}; + +} // namespace aidl::android::hardware::security::keymint diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h index bec2a2aea..45ebf7fda 100644 --- a/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h +++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h @@ -25,7 +25,7 @@ class TrustyKeymaster { public: TrustyKeymaster(); ~TrustyKeymaster(); - int Initialize(); + int Initialize(KmVersion version); void GetVersion(const GetVersionRequest& request, GetVersionResponse* response); void SupportedAlgorithms(const SupportedAlgorithmsRequest& request, SupportedAlgorithmsResponse* response); @@ -60,6 +60,8 @@ class TrustyKeymaster { ComputeSharedHmacResponse ComputeSharedHmac(const ComputeSharedHmacRequest& request); VerifyAuthorizationResponse VerifyAuthorization(const VerifyAuthorizationRequest& request); GetVersion2Response GetVersion2(const GetVersion2Request& request); + EarlyBootEndedResponse EarlyBootEnded(); + DeviceLockedResponse DeviceLocked(const DeviceLockedRequest& request); uint32_t message_version() const { return message_version_; } diff --git a/trusty/keymaster/include/trusty_keymaster/TrustySecureClock.h b/trusty/keymaster/include/trusty_keymaster/TrustySecureClock.h new file mode 100644 index 000000000..f077b276f --- /dev/null +++ b/trusty/keymaster/include/trusty_keymaster/TrustySecureClock.h @@ -0,0 +1,38 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/security/secureclock/BnSecureClock.h> +#include <aidl/android/hardware/security/secureclock/TimeStampToken.h> +#include <aidl/android/hardware/security/secureclock/Timestamp.h> + +#include <trusty_keymaster/TrustyKeymaster.h> + +namespace aidl::android::hardware::security::secureclock::trusty { + +class TrustySecureClock : public BnSecureClock { + public: + explicit TrustySecureClock(std::shared_ptr<::keymaster::TrustyKeymaster> impl) + : impl_(std::move(impl)) {} + ~TrustySecureClock() = default; + ::ndk::ScopedAStatus generateTimeStamp(int64_t challenge, TimeStampToken* token) override; + + private: + std::shared_ptr<::keymaster::TrustyKeymaster> impl_; +}; + +} // namespace aidl::android::hardware::security::secureclock::trusty diff --git a/trusty/keymaster/include/trusty_keymaster/TrustySharedSecret.h b/trusty/keymaster/include/trusty_keymaster/TrustySharedSecret.h new file mode 100644 index 000000000..946f57e9d --- /dev/null +++ b/trusty/keymaster/include/trusty_keymaster/TrustySharedSecret.h @@ -0,0 +1,39 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <aidl/android/hardware/security/sharedsecret/BnSharedSecret.h> +#include <aidl/android/hardware/security/sharedsecret/SharedSecretParameters.h> + +#include <trusty_keymaster/TrustyKeymaster.h> + +namespace aidl::android::hardware::security::sharedsecret::trusty { + +class TrustySharedSecret : public BnSharedSecret { + public: + explicit TrustySharedSecret(std::shared_ptr<::keymaster::TrustyKeymaster> impl) + : impl_(std::move(impl)) {} + ~TrustySharedSecret() = default; + + ::ndk::ScopedAStatus getSharedSecretParameters(SharedSecretParameters* params) override; + ::ndk::ScopedAStatus computeSharedSecret(const std::vector<SharedSecretParameters>& params, + std::vector<uint8_t>* sharingCheck) override; + + private: + std::shared_ptr<::keymaster::TrustyKeymaster> impl_; +}; +} // namespace aidl::android::hardware::security::sharedsecret::trusty diff --git a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h index 419c96f71..a1229a391 100644 --- a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h +++ b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h @@ -54,6 +54,8 @@ enum keymaster_command : uint32_t { KM_DESTROY_ATTESTATION_IDS = (24 << KEYMASTER_REQ_SHIFT), KM_IMPORT_WRAPPED_KEY = (25 << KEYMASTER_REQ_SHIFT), KM_GET_VERSION_2 = (28 << KEYMASTER_REQ_SHIFT), + KM_EARLY_BOOT_ENDED = (29 << KEYMASTER_REQ_SHIFT), + KM_DEVICE_LOCKED = (30 << KEYMASTER_REQ_SHIFT), // Bootloader/provisioning calls. KM_SET_BOOT_PARAMS = (0x1000 << KEYMASTER_REQ_SHIFT), diff --git a/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp b/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp new file mode 100644 index 000000000..5f8524b01 --- /dev/null +++ b/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp @@ -0,0 +1,324 @@ +/* + + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <trusty_keymaster/TrustyKeyMintDevice.h> + +#define TAG TrustyKeyMintDevice +#include <android-base/logging.h> + +#include <keymaster/android_keymaster_messages.h> +#include <keymaster/authorization_set.h> + +#include <KeyMintUtils.h> + +#include <trusty_keymaster/TrustyKeyMintOperation.h> + +namespace aidl::android::hardware::security::keymint::trusty { + +using keymaster::KeymasterBlob; +using keymaster::KeymasterKeyBlob; +using keymaster::TAG_APPLICATION_DATA; +using keymaster::TAG_APPLICATION_ID; +using keymaster::TAG_AUTH_TOKEN; +using km_utils::authToken2AidlVec; +using km_utils::kmBlob2vector; +using km_utils::kmError2ScopedAStatus; +using km_utils::kmParam2Aidl; +using km_utils::KmParamSet; +using km_utils::kmParamSet2Aidl; +using km_utils::legacy_enum_conversion; + +namespace { + +auto kSecurityLevel = SecurityLevel::TRUSTED_ENVIRONMENT; + +KeyCharacteristics convertAuthSet(SecurityLevel securityLevel, + const keymaster::AuthorizationSet& authorizations) { + KeyCharacteristics retval{securityLevel, {}}; + std::transform(authorizations.begin(), authorizations.end(), + std::back_inserter(retval.authorizations), kmParam2Aidl); + return retval; +} + +vector<KeyCharacteristics> convertKeyCharacteristics(const keymaster::AuthorizationSet& sw_enforced, + const keymaster::AuthorizationSet& hw_enforced, + bool includeKeystoreEnforced = true) { + KeyCharacteristics keyMintEnforced = convertAuthSet(kSecurityLevel, hw_enforced); + KeyCharacteristics keystoreEnforced = convertAuthSet(SecurityLevel::KEYSTORE, sw_enforced); + + vector<KeyCharacteristics> retval; + retval.reserve(2); + + if (!keyMintEnforced.authorizations.empty()) retval.push_back(std::move(keyMintEnforced)); + if (includeKeystoreEnforced && !keystoreEnforced.authorizations.empty()) { + retval.push_back(std::move(keystoreEnforced)); + } + + return retval; +} + +Certificate convertCertificate(const keymaster_blob_t& cert) { + return {std::vector<uint8_t>(cert.data, cert.data + cert.data_length)}; +} + +vector<Certificate> convertCertificateChain(const keymaster::CertificateChain& chain) { + vector<Certificate> retval; + std::transform(chain.begin(), chain.end(), std::back_inserter(retval), convertCertificate); + return retval; +} + +void addClientAndAppData(const vector<uint8_t>& clientId, const vector<uint8_t>& appData, + ::keymaster::AuthorizationSet* params) { + params->Clear(); + if (clientId.size()) params->push_back(TAG_APPLICATION_ID, clientId.data(), clientId.size()); + if (appData.size()) params->push_back(TAG_APPLICATION_DATA, appData.data(), appData.size()); +} + +} // namespace + +ScopedAStatus TrustyKeyMintDevice::getHardwareInfo(KeyMintHardwareInfo* info) { + info->versionNumber = 1; + info->securityLevel = kSecurityLevel; + info->keyMintName = "TrustyKeyMintDevice"; + info->keyMintAuthorName = "Google"; + info->timestampTokenRequired = false; + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::addRngEntropy(const vector<uint8_t>& data) { + if (data.size() == 0) return ScopedAStatus::ok(); + if (data.size() > 2048) { + LOG(DEBUG) << "Too-large entropy update of " << data.size() << " bytes."; + return kmError2ScopedAStatus(KM_ERROR_INVALID_INPUT_LENGTH); + } + + keymaster::AddEntropyRequest request(impl_->message_version()); + request.random_data.Reinitialize(data.data(), data.size()); + + keymaster::AddEntropyResponse response(impl_->message_version()); + impl_->AddRngEntropy(request, &response); + + return kmError2ScopedAStatus(response.error); +} + +ScopedAStatus TrustyKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams, + const optional<AttestationKey>& attestationKey, + KeyCreationResult* creationResult) { + keymaster::GenerateKeyRequest request(impl_->message_version()); + request.key_description.Reinitialize(KmParamSet(keyParams)); + if (attestationKey) { + request.attestation_signing_key_blob = + KeymasterKeyBlob(attestationKey->keyBlob.data(), attestationKey->keyBlob.size()); + request.attest_key_params.Reinitialize(KmParamSet(attestationKey->attestKeyParams)); + request.issuer_subject = KeymasterBlob(attestationKey->issuerSubjectName.data(), + attestationKey->issuerSubjectName.size()); + } + + keymaster::GenerateKeyResponse response(impl_->message_version()); + impl_->GenerateKey(request, &response); + + if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error); + + creationResult->keyBlob = kmBlob2vector(response.key_blob); + creationResult->keyCharacteristics = + convertKeyCharacteristics(response.unenforced, response.enforced); + creationResult->certificateChain = convertCertificateChain(response.certificate_chain); + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::getKeyCharacteristics( + const vector<uint8_t>& keyBlob, + const vector<uint8_t>& clientId, // + const vector<uint8_t>& appData, // + vector<KeyCharacteristics>* characteristics) { + keymaster::GetKeyCharacteristicsRequest request(impl_->message_version()); + request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); + addClientAndAppData(clientId, appData, &request.additional_params); + + keymaster::GetKeyCharacteristicsResponse response(impl_->message_version()); + impl_->GetKeyCharacteristics(request, &response); + + if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error); + + *characteristics = convertKeyCharacteristics(response.unenforced, response.enforced, + false /* includeKeystoreEnforced */); + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::importKey(const vector<KeyParameter>& keyParams, + KeyFormat keyFormat, const vector<uint8_t>& keyData, + const optional<AttestationKey>& attestationKey, + KeyCreationResult* creationResult) { + keymaster::ImportKeyRequest request(impl_->message_version()); + request.key_description.Reinitialize(KmParamSet(keyParams)); + request.key_format = legacy_enum_conversion(keyFormat); + request.key_data = KeymasterKeyBlob(keyData.data(), keyData.size()); + if (attestationKey) { + request.attestation_signing_key_blob = + KeymasterKeyBlob(attestationKey->keyBlob.data(), attestationKey->keyBlob.size()); + request.attest_key_params.Reinitialize(KmParamSet(attestationKey->attestKeyParams)); + request.issuer_subject = KeymasterBlob(attestationKey->issuerSubjectName.data(), + attestationKey->issuerSubjectName.size()); + } + + keymaster::ImportKeyResponse response(impl_->message_version()); + impl_->ImportKey(request, &response); + + if (response.error != KM_ERROR_OK) { + return kmError2ScopedAStatus(response.error); + } + + creationResult->keyBlob = kmBlob2vector(response.key_blob); + creationResult->keyCharacteristics = + convertKeyCharacteristics(response.unenforced, response.enforced); + creationResult->certificateChain = convertCertificateChain(response.certificate_chain); + + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::importWrappedKey(const vector<uint8_t>& wrappedKeyData, + const vector<uint8_t>& wrappingKeyBlob, // + const vector<uint8_t>& maskingKey, + const vector<KeyParameter>& unwrappingParams, + int64_t passwordSid, // + int64_t biometricSid, + KeyCreationResult* creationResult) { + keymaster::ImportWrappedKeyRequest request(impl_->message_version()); + request.SetWrappedMaterial(wrappedKeyData.data(), wrappedKeyData.size()); + request.SetWrappingMaterial(wrappingKeyBlob.data(), wrappingKeyBlob.size()); + request.SetMaskingKeyMaterial(maskingKey.data(), maskingKey.size()); + request.additional_params.Reinitialize(KmParamSet(unwrappingParams)); + request.password_sid = static_cast<uint64_t>(passwordSid); + request.biometric_sid = static_cast<uint64_t>(biometricSid); + + keymaster::ImportWrappedKeyResponse response(impl_->message_version()); + impl_->ImportWrappedKey(request, &response); + + if (response.error != KM_ERROR_OK) { + return kmError2ScopedAStatus(response.error); + } + + creationResult->keyBlob = kmBlob2vector(response.key_blob); + creationResult->keyCharacteristics = + convertKeyCharacteristics(response.unenforced, response.enforced); + creationResult->certificateChain = convertCertificateChain(response.certificate_chain); + + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::upgradeKey(const vector<uint8_t>& keyBlobToUpgrade, + const vector<KeyParameter>& upgradeParams, + vector<uint8_t>* keyBlob) { + keymaster::UpgradeKeyRequest request(impl_->message_version()); + request.SetKeyMaterial(keyBlobToUpgrade.data(), keyBlobToUpgrade.size()); + request.upgrade_params.Reinitialize(KmParamSet(upgradeParams)); + + keymaster::UpgradeKeyResponse response(impl_->message_version()); + impl_->UpgradeKey(request, &response); + + if (response.error != KM_ERROR_OK) { + return kmError2ScopedAStatus(response.error); + } + + *keyBlob = kmBlob2vector(response.upgraded_key); + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::deleteKey(const vector<uint8_t>& keyBlob) { + keymaster::DeleteKeyRequest request(impl_->message_version()); + request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); + + keymaster::DeleteKeyResponse response(impl_->message_version()); + impl_->DeleteKey(request, &response); + + return kmError2ScopedAStatus(response.error); +} + +ScopedAStatus TrustyKeyMintDevice::deleteAllKeys() { + // There's nothing to be done to delete software key blobs. + keymaster::DeleteAllKeysRequest request(impl_->message_version()); + keymaster::DeleteAllKeysResponse response(impl_->message_version()); + impl_->DeleteAllKeys(request, &response); + + return kmError2ScopedAStatus(response.error); +} + +ScopedAStatus TrustyKeyMintDevice::destroyAttestationIds() { + return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED); +} + +ScopedAStatus TrustyKeyMintDevice::begin(KeyPurpose purpose, const vector<uint8_t>& keyBlob, + const vector<KeyParameter>& params, + const optional<HardwareAuthToken>& authToken, + BeginResult* result) { + keymaster::BeginOperationRequest request(impl_->message_version()); + request.purpose = legacy_enum_conversion(purpose); + request.SetKeyMaterial(keyBlob.data(), keyBlob.size()); + request.additional_params.Reinitialize(KmParamSet(params)); + + vector<uint8_t> vector_token = authToken2AidlVec(authToken); + request.additional_params.push_back( + TAG_AUTH_TOKEN, reinterpret_cast<uint8_t*>(vector_token.data()), vector_token.size()); + + keymaster::BeginOperationResponse response(impl_->message_version()); + impl_->BeginOperation(request, &response); + + if (response.error != KM_ERROR_OK) { + return kmError2ScopedAStatus(response.error); + } + + result->params = kmParamSet2Aidl(response.output_params); + result->challenge = response.op_handle; + result->operation = ndk::SharedRefBase::make<TrustyKeyMintOperation>(impl_, response.op_handle); + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintDevice::deviceLocked( + bool passwordOnly, const std::optional<secureclock::TimeStampToken>& timestampToken) { + keymaster::DeviceLockedRequest request(impl_->message_version()); + request.passwordOnly = passwordOnly; + if (timestampToken.has_value()) { + request.token.challenge = timestampToken->challenge; + request.token.mac = {timestampToken->mac.data(), timestampToken->mac.size()}; + request.token.timestamp = timestampToken->timestamp.milliSeconds; + } + keymaster::DeviceLockedResponse response = impl_->DeviceLocked(request); + return kmError2ScopedAStatus(response.error); +} + +ScopedAStatus TrustyKeyMintDevice::earlyBootEnded() { + keymaster::EarlyBootEndedResponse response = impl_->EarlyBootEnded(); + return kmError2ScopedAStatus(response.error); +} + +ScopedAStatus TrustyKeyMintDevice::convertStorageKeyToEphemeral( + const std::vector<uint8_t>& storageKeyBlob, std::vector<uint8_t>* ephemeralKeyBlob) { + keymaster::ExportKeyRequest request(impl_->message_version()); + request.SetKeyMaterial(storageKeyBlob.data(), storageKeyBlob.size()); + request.key_format = KM_KEY_FORMAT_RAW; + + keymaster::ExportKeyResponse response(impl_->message_version()); + impl_->ExportKey(request, &response); + + if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error); + if (response.key_data) { + *ephemeralKeyBlob = {response.key_data, response.key_data + response.key_data_length}; + } + return ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::security::keymint::trusty diff --git a/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp b/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp new file mode 100644 index 000000000..41a21e9f4 --- /dev/null +++ b/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp @@ -0,0 +1,168 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <trusty_keymaster/TrustyKeyMintOperation.h> + +#define TAG TrustyKeyMintOperation +#include <android-base/logging.h> + +#include <aidl/android/hardware/security/keymint/ErrorCode.h> +#include <aidl/android/hardware/security/secureclock/ISecureClock.h> + +#include <KeyMintUtils.h> +#include <keymaster/android_keymaster.h> +#include <trusty_keymaster/ipc/trusty_keymaster_ipc.h> + +namespace aidl::android::hardware::security::keymint { + +using ::keymaster::AbortOperationRequest; +using ::keymaster::AbortOperationResponse; +using ::keymaster::FinishOperationRequest; +using ::keymaster::FinishOperationResponse; +using ::keymaster::TAG_ASSOCIATED_DATA; +using ::keymaster::TAG_AUTH_TOKEN; +using ::keymaster::UpdateOperationRequest; +using ::keymaster::UpdateOperationResponse; +using km_utils::authToken2AidlVec; +using km_utils::kmError2ScopedAStatus; +using secureclock::TimeStampToken; + +TrustyKeyMintOperation::TrustyKeyMintOperation(shared_ptr<TrustyKeymaster> implementation, + keymaster_operation_handle_t opHandle) + : impl_(std::move(implementation)), opHandle_(opHandle) {} + +TrustyKeyMintOperation::~TrustyKeyMintOperation() { + if (opHandle_ != 0) { + abort(); + } +} + +ScopedAStatus TrustyKeyMintOperation::updateAad( + const vector<uint8_t>& input, const optional<HardwareAuthToken>& /* authToken */, + const optional<TimeStampToken>& /* timestampToken */) { + UpdateOperationRequest request(impl_->message_version()); + request.op_handle = opHandle_; + request.additional_params.push_back(TAG_ASSOCIATED_DATA, input.data(), input.size()); + + UpdateOperationResponse response(impl_->message_version()); + impl_->UpdateOperation(request, &response); + + return kmError2ScopedAStatus(response.error); +} + +ScopedAStatus TrustyKeyMintOperation::update(const vector<uint8_t>& input, + const optional<HardwareAuthToken>& authToken, + const optional<TimeStampToken>& /* timestampToken */, + vector<uint8_t>* output) { + if (!output) return kmError2ScopedAStatus(KM_ERROR_OUTPUT_PARAMETER_NULL); + + UpdateOperationRequest request(impl_->message_version()); + request.op_handle = opHandle_; + if (authToken) { + auto tokenAsVec(authToken2AidlVec(*authToken)); + request.additional_params.push_back(TAG_AUTH_TOKEN, tokenAsVec.data(), tokenAsVec.size()); + } + + size_t serialized_size = request.SerializedSize(); + if (serialized_size > TRUSTY_KEYMASTER_SEND_BUF_SIZE) { + return kmError2ScopedAStatus(KM_ERROR_INVALID_INPUT_LENGTH); + } + + const uint8_t* input_pos = input.data(); + const uint8_t* input_end = input.data() + input.size(); + const size_t max_chunk_size = TRUSTY_KEYMASTER_SEND_BUF_SIZE - serialized_size; + output->clear(); + + while (input_pos < input_end) { + size_t to_send = std::min(max_chunk_size, static_cast<size_t>(input_end - input_pos)); + LOG(DEBUG) << "update: Sending " << to_send << " of " << (input_end - input_pos) + << " bytes"; + request.input.Reinitialize(input_pos, to_send); + + UpdateOperationResponse response(impl_->message_version()); + impl_->UpdateOperation(request, &response); + if (response.error != KM_ERROR_OK) { + opHandle_ = 0; // Operation has ended, the handle is invalid. This saves an abort(). + return kmError2ScopedAStatus(response.error); + } + + input_pos += response.input_consumed; + output->insert(output->end(), response.output.begin(), response.output.end()); + } + + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintOperation::finish( + const optional<vector<uint8_t>>& input, // + const optional<vector<uint8_t>>& signature, // + const optional<HardwareAuthToken>& authToken, + const optional<TimeStampToken>& /* timestampToken */, + const optional<vector<uint8_t>>& /* confirmationToken */, vector<uint8_t>* output) { + if (!output) { + return ScopedAStatus(AStatus_fromServiceSpecificError( + static_cast<int32_t>(ErrorCode::OUTPUT_PARAMETER_NULL))); + } + output->clear(); + + FinishOperationRequest request(impl_->message_version()); + request.op_handle = opHandle_; + if (signature) request.signature.Reinitialize(signature->data(), signature->size()); + size_t serialized_size = request.SerializedSize(); + if (serialized_size > TRUSTY_KEYMASTER_SEND_BUF_SIZE) { + return kmError2ScopedAStatus(KM_ERROR_INVALID_INPUT_LENGTH); + } + + if (input) { + const size_t max_chunk_size = TRUSTY_KEYMASTER_SEND_BUF_SIZE - serialized_size; + + if (input->size() > max_chunk_size) { + LOG(DEBUG) << "Sending an update to process finish() data"; + // Use update to process all but the last max_chunk_size bytes. + auto result = update({input->begin(), input->end() - max_chunk_size}, authToken, + std::nullopt /* timestampToken */, output); + if (!result.isOk()) return result; + + // Process the last max_chunk_size with finish. + request.input.Reinitialize(input->data() + (input->size() - max_chunk_size), + max_chunk_size); + } else { + request.input.Reinitialize(input->data(), input->size()); + } + } + + FinishOperationResponse response(impl_->message_version()); + impl_->FinishOperation(request, &response); + opHandle_ = 0; + + if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error); + + *output = {response.output.begin(), response.output.end()}; + return ScopedAStatus::ok(); +} + +ScopedAStatus TrustyKeyMintOperation::abort() { + AbortOperationRequest request(impl_->message_version()); + request.op_handle = opHandle_; + + AbortOperationResponse response(impl_->message_version()); + impl_->AbortOperation(request, &response); + opHandle_ = 0; + + return kmError2ScopedAStatus(response.error); +} + +} // namespace aidl::android::hardware::security::keymint diff --git a/trusty/keymaster/keymint/TrustySecureClock.cpp b/trusty/keymaster/keymint/TrustySecureClock.cpp new file mode 100644 index 000000000..fed5420ae --- /dev/null +++ b/trusty/keymaster/keymint/TrustySecureClock.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <trusty_keymaster/TrustySecureClock.h> + +#include <aidl/android/hardware/security/keymint/ErrorCode.h> + +#include <KeyMintUtils.h> + +namespace aidl::android::hardware::security::secureclock::trusty { + +using keymint::km_utils::kmBlob2vector; +using keymint::km_utils::kmError2ScopedAStatus; + +::ndk::ScopedAStatus TrustySecureClock::generateTimeStamp(int64_t challenge, + TimeStampToken* token) { + keymaster::VerifyAuthorizationRequest request(impl_->message_version()); + request.challenge = challenge; + + auto response = impl_->VerifyAuthorization(request); + if (response.error != KM_ERROR_OK) return kmError2ScopedAStatus(response.error); + + token->challenge = response.token.challenge; + token->timestamp.milliSeconds = static_cast<int64_t>(response.token.timestamp); + token->mac = kmBlob2vector(response.token.mac); + return ::ndk::ScopedAStatus::ok(); +} + +} // namespace aidl::android::hardware::security::secureclock::trusty diff --git a/trusty/keymaster/keymint/TrustySharedSecret.cpp b/trusty/keymaster/keymint/TrustySharedSecret.cpp new file mode 100644 index 000000000..81091688a --- /dev/null +++ b/trusty/keymaster/keymint/TrustySharedSecret.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2020, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <trusty_keymaster/TrustySharedSecret.h> + +#include <aidl/android/hardware/security/keymint/ErrorCode.h> +#include <keymaster/android_keymaster.h> +#include "KeyMintUtils.h" + +namespace aidl::android::hardware::security::sharedsecret::trusty { + +using keymint::km_utils::kmBlob2vector; +using keymint::km_utils::kmError2ScopedAStatus; + +::ndk::ScopedAStatus TrustySharedSecret::getSharedSecretParameters(SharedSecretParameters* params) { + auto response = impl_->GetHmacSharingParameters(); + params->seed = kmBlob2vector(response.params.seed); + params->nonce = {std::begin(response.params.nonce), std::end(response.params.nonce)}; + return kmError2ScopedAStatus(response.error); +} + +::ndk::ScopedAStatus TrustySharedSecret::computeSharedSecret( + const std::vector<SharedSecretParameters>& params, std::vector<uint8_t>* sharingCheck) { + keymaster::ComputeSharedHmacRequest request(impl_->message_version()); + request.params_array.params_array = new keymaster::HmacSharingParameters[params.size()]; + request.params_array.num_params = params.size(); + for (size_t i = 0; i < params.size(); ++i) { + request.params_array.params_array[i].seed = {params[i].seed.data(), params[i].seed.size()}; + if (sizeof(request.params_array.params_array[i].nonce) != params[i].nonce.size()) { + return kmError2ScopedAStatus(KM_ERROR_INVALID_ARGUMENT); + } + memcpy(request.params_array.params_array[i].nonce, params[i].nonce.data(), + params[i].nonce.size()); + } + + auto response = impl_->ComputeSharedHmac(request); + if (response.error == KM_ERROR_OK) *sharingCheck = kmBlob2vector(response.sharing_check); + return kmError2ScopedAStatus(response.error); +} + +} // namespace aidl::android::hardware::security::sharedsecret::trusty diff --git a/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.rc b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.rc new file mode 100644 index 000000000..389af412f --- /dev/null +++ b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.rc @@ -0,0 +1,4 @@ +service vendor.keymint-trusty /vendor/bin/hw/android.hardware.security.keymint-service.trusty + class early_hal + user nobody + group drmrpc diff --git a/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml new file mode 100644 index 000000000..0ab3d64cf --- /dev/null +++ b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml @@ -0,0 +1,14 @@ +<manifest version="1.0" type="device"> + <hal format="aidl"> + <name>android.hardware.security.keymint</name> + <fqname>IKeyMintDevice/default</fqname> + </hal> + <hal format="aidl"> + <name>android.hardware.security.secureclock</name> + <fqname>ISecureClock/default</fqname> + </hal> + <hal format="aidl"> + <name>android.hardware.security.sharedsecret</name> + <fqname>ISharedSecret/default</fqname> + </hal> +</manifest> diff --git a/trusty/keymaster/keymint/service.cpp b/trusty/keymaster/keymint/service.cpp new file mode 100644 index 000000000..8f5f0f815 --- /dev/null +++ b/trusty/keymaster/keymint/service.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.security.keymint-service.trusty" +#include <android-base/logging.h> +#include <android/binder_manager.h> +#include <android/binder_process.h> + +#include <trusty_keymaster/TrustyKeyMintDevice.h> +#include <trusty_keymaster/TrustySecureClock.h> +#include <trusty_keymaster/TrustySharedSecret.h> + +using aidl::android::hardware::security::keymint::trusty::TrustyKeyMintDevice; +using aidl::android::hardware::security::secureclock::trusty::TrustySecureClock; +using aidl::android::hardware::security::sharedsecret::trusty::TrustySharedSecret; + +template <typename T, class... Args> +std::shared_ptr<T> addService(Args&&... args) { + std::shared_ptr<T> service = std::make_shared<T>(std::forward<Args>(args)...); + auto instanceName = std::string(T::descriptor) + "/default"; + LOG(ERROR) << "Adding service instance: " << instanceName; + auto status = AServiceManager_addService(service->asBinder().get(), instanceName.c_str()); + CHECK(status == STATUS_OK) << "Failed to add service " << instanceName; + return service; +} + +int main() { + auto trustyKeymaster = std::make_shared<keymaster::TrustyKeymaster>(); + int err = trustyKeymaster->Initialize(keymaster::KmVersion::KEYMINT_1); + if (err != 0) { + LOG(FATAL) << "Could not initialize TrustyKeymaster for KeyMint (" << err << ")"; + return -1; + } + + // Zero threads seems like a useless pool but below we'll join this thread to it, increasing + // the pool size to 1. + ABinderProcess_setThreadPoolMaxThreadCount(0); + + auto keyMint = addService<TrustyKeyMintDevice>(trustyKeymaster); + auto secureClock = addService<TrustySecureClock>(trustyKeymaster); + auto sharedSecret = addService<TrustySharedSecret>(trustyKeymaster); + + ABinderProcess_joinThreadPool(); + return EXIT_FAILURE; // should not reach +} |