diff --git a/keymaster/3.0/default/Android.mk b/keymaster/3.0/default/Android.mk new file mode 100644 index 0000000000..36d88905a3 --- /dev/null +++ b/keymaster/3.0/default/Android.mk @@ -0,0 +1,43 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE := android.hardware.keymaster@3.0-impl +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_SRC_FILES := \ + KeymasterDevice.cpp \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libsoftkeymasterdevice \ + libcrypto \ + libkeymaster1 \ + libhidlbase \ + libhidltransport \ + libhwbinder \ + libutils \ + libhardware \ + android.hardware.keymaster@3.0 + +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_MODULE := android.hardware.keymaster@3.0-service +LOCAL_INIT_RC := android.hardware.keymaster@3.0-service.rc +LOCAL_SRC_FILES := \ + service.cpp + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libcutils \ + libdl \ + libbase \ + libutils \ + libhardware_legacy \ + libhardware \ + libhwbinder \ + libhidlbase \ + libhidltransport \ + android.hardware.keymaster@3.0 + +include $(BUILD_EXECUTABLE) diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp new file mode 100644 index 0000000000..1208b8d33c --- /dev/null +++ b/keymaster/3.0/default/KeymasterDevice.cpp @@ -0,0 +1,691 @@ +/* + ** + ** Copyright 2016, 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.keymaster@3.0-impl" + +#include "KeymasterDevice.h" + +#include + +#include +#include +#include + +namespace android { +namespace hardware { +namespace keymaster { +namespace V3_0 { +namespace implementation { + +using ::keymaster::SoftKeymasterDevice; + +class SoftwareOnlyHidlKeymasterEnforcement : public ::keymaster::KeymasterEnforcement { + public: + SoftwareOnlyHidlKeymasterEnforcement() : KeymasterEnforcement(64, 64) {} + + uint32_t get_current_time() const override { + struct timespec tp; + int err = clock_gettime(CLOCK_MONOTONIC, &tp); + if (err || tp.tv_sec < 0) return 0; + return static_cast(tp.tv_sec); + } + + bool activation_date_valid(uint64_t) const override { return true; } + bool expiration_date_passed(uint64_t) const override { return false; } + bool auth_token_timed_out(const hw_auth_token_t&, uint32_t) const override { return false; } + bool ValidateTokenSignature(const hw_auth_token_t&) const override { return true; } +}; + +class SoftwareOnlyHidlKeymasterContext : public ::keymaster::SoftKeymasterContext { + public: + SoftwareOnlyHidlKeymasterContext() : enforcement_(new SoftwareOnlyHidlKeymasterEnforcement) {} + + ::keymaster::KeymasterEnforcement* enforcement_policy() override { return enforcement_.get(); } + + private: + std::unique_ptr<::keymaster::KeymasterEnforcement> enforcement_; +}; + +static int keymaster0_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) { + assert(mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0); + ALOGI("Found keymaster0 module %s, version %x", mod->name, mod->module_api_version); + + UniquePtr soft_keymaster(new SoftKeymasterDevice); + keymaster0_device_t* km0_device = NULL; + keymaster_error_t error = KM_ERROR_OK; + + int rc = keymaster0_open(mod, &km0_device); + if (rc) { + ALOGE("Error opening keystore keymaster0 device."); + goto err; + } + + if (km0_device->flags & KEYMASTER_SOFTWARE_ONLY) { + ALOGI("Keymaster0 module is software-only. Using SoftKeymasterDevice instead."); + km0_device->common.close(&km0_device->common); + km0_device = NULL; + // SoftKeymasterDevice will be deleted by keymaster_device_release() + *dev = soft_keymaster.release()->keymaster2_device(); + return 0; + } + + ALOGD("Wrapping keymaster0 module %s with SoftKeymasterDevice", mod->name); + error = soft_keymaster->SetHardwareDevice(km0_device); + km0_device = NULL; // SoftKeymasterDevice has taken ownership. + if (error != KM_ERROR_OK) { + ALOGE("Got error %d from SetHardwareDevice", error); + rc = error; + goto err; + } + + // SoftKeymasterDevice will be deleted by keymaster_device_release() + *dev = soft_keymaster.release()->keymaster2_device(); + return 0; + +err: + if (km0_device) km0_device->common.close(&km0_device->common); + *dev = NULL; + return rc; +} + +static int keymaster1_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) { + assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0); + ALOGI("Found keymaster1 module %s, version %x", mod->name, mod->module_api_version); + + UniquePtr soft_keymaster(new SoftKeymasterDevice); + keymaster1_device_t* km1_device = nullptr; + keymaster_error_t error = KM_ERROR_OK; + + int rc = keymaster1_open(mod, &km1_device); + if (rc) { + ALOGE("Error %d opening keystore keymaster1 device", rc); + goto err; + } + + ALOGD("Wrapping keymaster1 module %s with SofKeymasterDevice", mod->name); + error = soft_keymaster->SetHardwareDevice(km1_device); + km1_device = nullptr; // SoftKeymasterDevice has taken ownership. + if (error != KM_ERROR_OK) { + ALOGE("Got error %d from SetHardwareDevice", error); + rc = error; + goto err; + } + + // SoftKeymasterDevice will be deleted by keymaster_device_release() + *dev = soft_keymaster.release()->keymaster2_device(); + return 0; + +err: + if (km1_device) km1_device->common.close(&km1_device->common); + *dev = NULL; + return rc; +} + +static int keymaster2_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) { + assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_2_0); + ALOGI("Found keymaster2 module %s, version %x", mod->name, mod->module_api_version); + + keymaster2_device_t* km2_device = nullptr; + + int rc = keymaster2_open(mod, &km2_device); + if (rc) { + ALOGE("Error %d opening keystore keymaster2 device", rc); + goto err; + } + + *dev = km2_device; + return 0; + +err: + if (km2_device) km2_device->common.close(&km2_device->common); + *dev = nullptr; + return rc; +} + +static int keymaster_device_initialize(keymaster2_device_t** dev, uint32_t* version, + bool* supports_ec) { + const hw_module_t* mod; + + *supports_ec = true; + + int rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); + if (rc) { + ALOGI("Could not find any keystore module, using software-only implementation."); + // SoftKeymasterDevice will be deleted by keymaster_device_release() + *dev = (new SoftKeymasterDevice(new SoftwareOnlyHidlKeymasterContext))->keymaster2_device(); + *version = -1; + return 0; + } + + if (mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0) { + *version = 0; + int rc = keymaster0_device_initialize(mod, dev); + if (rc == 0 && ((*dev)->flags & KEYMASTER_SUPPORTS_EC) == 0) { + *supports_ec = false; + } + return rc; + } else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) { + *version = 1; + return keymaster1_device_initialize(mod, dev); + } else { + *version = 2; + return keymaster2_device_initialize(mod, dev); + } +} + +KeymasterDevice::~KeymasterDevice() { + if (keymaster_device_) keymaster_device_->common.close(&keymaster_device_->common); +} + +static inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { + return keymaster_tag_get_type(tag); +} + +/** + * legacy_enum_conversion converts enums from hidl to keymaster and back. Currently, this is just a + * cast to make the compiler happy. One of two thigs should happen though: + * TODO The keymaster enums should become aliases for the hidl generated enums so that we have a + * single point of truth. Then this cast function can go away. + */ +inline static keymaster_tag_t legacy_enum_conversion(const Tag value) { + return keymaster_tag_t(value); +} +inline static Tag legacy_enum_conversion(const keymaster_tag_t value) { + return Tag(value); +} +inline static keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) { + return keymaster_purpose_t(value); +} +inline static keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) { + return keymaster_key_format_t(value); +} +inline static ErrorCode legacy_enum_conversion(const keymaster_error_t value) { + return ErrorCode(value); +} + +class KmParamSet : public keymaster_key_param_set_t { + public: + KmParamSet(const hidl_vec& keyParams) { + params = new keymaster_key_param_t[keyParams.size()]; + length = keyParams.size(); + for (size_t i = 0; i < keyParams.size(); ++i) { + auto tag = legacy_enum_conversion(keyParams[i].tag); + switch (typeFromTag(tag)) { + case KM_ENUM: + case KM_ENUM_REP: + params[i] = keymaster_param_enum(tag, keyParams[i].f.integer); + break; + case KM_UINT: + case KM_UINT_REP: + params[i] = keymaster_param_int(tag, keyParams[i].f.integer); + break; + case KM_ULONG: + case KM_ULONG_REP: + params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger); + break; + case KM_DATE: + params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime); + break; + case KM_BOOL: + if (keyParams[i].f.boolValue) + params[i] = keymaster_param_bool(tag); + else + params[i].tag = KM_TAG_INVALID; + break; + case KM_BIGNUM: + case KM_BYTES: + params[i] = + keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size()); + break; + case KM_INVALID: + default: + params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + } + KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { + other.length = 0; + other.params = nullptr; + } + KmParamSet(const KmParamSet&) = delete; + ~KmParamSet() { delete[] params; } +}; + +inline static KmParamSet hidlParams2KmParamSet(const hidl_vec& params) { + return KmParamSet(params); +} + +inline static keymaster_blob_t hidlVec2KmBlob(const hidl_vec& blob) { + /* hidl unmarshals funny pointers if the the blob is empty */ + if (blob.size()) return {&blob[0], blob.size()}; + return {nullptr, 0}; +} + +inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec& blob) { + /* hidl unmarshals funny pointers if the the blob is empty */ + if (blob.size()) return {&blob[0], blob.size()}; + return {nullptr, 0}; +} + +inline static hidl_vec kmBlob2hidlVec(const keymaster_key_blob_t& blob) { + hidl_vec result; + result.setToExternal(const_cast(blob.key_material), blob.key_material_size); + return result; +} +inline static hidl_vec kmBlob2hidlVec(const keymaster_blob_t& blob) { + hidl_vec result; + result.setToExternal(const_cast(blob.data), blob.data_length); + return result; +} + +inline static hidl_vec> +kmCertChain2Hidl(const keymaster_cert_chain_t* cert_chain) { + hidl_vec> result; + if (!cert_chain || cert_chain->entry_count == 0 || !cert_chain->entries) return result; + + result.resize(cert_chain->entry_count); + for (size_t i = 0; i < cert_chain->entry_count; ++i) { + auto& entry = cert_chain->entries[i]; + result[i] = kmBlob2hidlVec(entry); + } + + return result; +} + +static inline hidl_vec kmParamSet2Hidl(const keymaster_key_param_set_t& set) { + hidl_vec result; + if (set.length == 0 || set.params == nullptr) return result; + + result.resize(set.length); + keymaster_key_param_t* params = set.params; + for (size_t i = 0; i < set.length; ++i) { + auto tag = params[i].tag; + result[i].tag = legacy_enum_conversion(tag); + switch (typeFromTag(tag)) { + case KM_ENUM: + case KM_ENUM_REP: + result[i].f.integer = params[i].enumerated; + break; + case KM_UINT: + case KM_UINT_REP: + result[i].f.integer = params[i].integer; + break; + case KM_ULONG: + case KM_ULONG_REP: + result[i].f.longInteger = params[i].long_integer; + break; + case KM_DATE: + result[i].f.dateTime = params[i].date_time; + break; + case KM_BOOL: + result[i].f.boolValue = params[i].boolean; + break; + case KM_BIGNUM: + case KM_BYTES: + result[i].blob.setToExternal(const_cast(params[i].blob.data), + params[i].blob.data_length); + break; + case KM_INVALID: + default: + params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + return result; +} + +// Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow. +Return KeymasterDevice::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) { + bool is_secure = false; + bool supports_symmetric_cryptography = false; + bool supports_attestation = false; + + switch (hardware_version_) { + case 2: + supports_attestation = true; + /* Falls through */ + case 1: + supports_symmetric_cryptography = true; + /* Falls through */ + case 0: + is_secure = true; + break; + }; + + _hidl_cb(is_secure, hardware_supports_ec_, supports_symmetric_cryptography, + supports_attestation); + return Void(); +} + +Return KeymasterDevice::addRngEntropy(const hidl_vec& data) { + return legacy_enum_conversion( + keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size())); +} + +Return KeymasterDevice::generateKey(const hidl_vec& keyParams, + generateKey_cb _hidl_cb) { + // result variables for the wire + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; + + // result variables the backend understands + keymaster_key_blob_t key_blob{nullptr, 0}; + keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}}; + + // convert the parameter set to something our backend understands + auto kmParams = hidlParams2KmParamSet(keyParams); + + auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &key_blob, + &key_characteristics); + + if (rc == KM_ERROR_OK) { + // on success convert the result to wire format + resultKeyBlob = kmBlob2hidlVec(key_blob); + resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced); + resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced); + } + + // send results off to the client + _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics); + + // free buffers that we are responsible for + if (key_blob.key_material) free(const_cast(key_blob.key_material)); + keymaster_free_characteristics(&key_characteristics); + + return Void(); +} + +Return KeymasterDevice::getKeyCharacteristics(const hidl_vec& keyBlob, + const hidl_vec& clientId, + const hidl_vec& appData, + getKeyCharacteristics_cb _hidl_cb) { + // result variables for the wire + KeyCharacteristics resultCharacteristics; + + // result variables the backend understands + keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}}; + + auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob); + auto kmClientId = hidlVec2KmBlob(clientId); + auto kmAppData = hidlVec2KmBlob(appData); + + auto rc = keymaster_device_->get_key_characteristics( + keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr, + clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr, + &key_characteristics); + + if (rc == KM_ERROR_OK) { + resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced); + resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced); + } + + _hidl_cb(legacy_enum_conversion(rc), resultCharacteristics); + + keymaster_free_characteristics(&key_characteristics); + + return Void(); +} + +Return KeymasterDevice::importKey(const hidl_vec& params, KeyFormat keyFormat, + const hidl_vec& keyData, importKey_cb _hidl_cb) { + // result variables for the wire + KeyCharacteristics resultCharacteristics; + hidl_vec resultKeyBlob; + + // result variables the backend understands + keymaster_key_blob_t key_blob{nullptr, 0}; + keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}}; + + auto kmParams = hidlParams2KmParamSet(params); + auto kmKeyData = hidlVec2KmBlob(keyData); + + auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams, + legacy_enum_conversion(keyFormat), &kmKeyData, + &key_blob, &key_characteristics); + + if (rc == KM_ERROR_OK) { + // on success convert the result to wire format + // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?) + resultKeyBlob = kmBlob2hidlVec(key_blob); + resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced); + resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced); + } + + _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics); + + // free buffers that we are responsible for + if (key_blob.key_material) free(const_cast(key_blob.key_material)); + keymaster_free_characteristics(&key_characteristics); + + return Void(); +} + +Return KeymasterDevice::exportKey(KeyFormat exportFormat, const hidl_vec& keyBlob, + const hidl_vec& clientId, + const hidl_vec& appData, exportKey_cb _hidl_cb) { + + // result variables for the wire + hidl_vec resultKeyBlob; + + // result variables the backend understands + keymaster_blob_t out_blob{nullptr, 0}; + + auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob); + auto kmClientId = hidlVec2KmBlob(clientId); + auto kmAppData = hidlVec2KmBlob(appData); + + auto rc = keymaster_device_->export_key(keymaster_device_, legacy_enum_conversion(exportFormat), + keyBlob.size() ? &kmKeyBlob : nullptr, + clientId.size() ? &kmClientId : nullptr, + appData.size() ? &kmAppData : nullptr, &out_blob); + + if (rc == KM_ERROR_OK) { + // on success convert the result to wire format + // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?) + resultKeyBlob = kmBlob2hidlVec(out_blob); + } + + _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob); + + // free buffers that we are responsible for + if (out_blob.data) free(const_cast(out_blob.data)); + + return Void(); +} + +Return KeymasterDevice::attestKey(const hidl_vec& keyToAttest, + const hidl_vec& attestParams, + attestKey_cb _hidl_cb) { + + hidl_vec> resultCertChain; + + keymaster_cert_chain_t cert_chain{nullptr, 0}; + + auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest); + auto kmAttestParams = hidlParams2KmParamSet(attestParams); + + auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams, + &cert_chain); + + if (rc == KM_ERROR_OK) { + resultCertChain = kmCertChain2Hidl(&cert_chain); + } + + _hidl_cb(legacy_enum_conversion(rc), resultCertChain); + + keymaster_free_cert_chain(&cert_chain); + + return Void(); +} + +Return KeymasterDevice::upgradeKey(const hidl_vec& keyBlobToUpgrade, + const hidl_vec& upgradeParams, + upgradeKey_cb _hidl_cb) { + + // result variables for the wire + hidl_vec resultKeyBlob; + + // result variables the backend understands + keymaster_key_blob_t key_blob{nullptr, 0}; + + auto kmKeyBlobToUpgrade = hidlVec2KmKeyBlob(keyBlobToUpgrade); + auto kmUpgradeParams = hidlParams2KmParamSet(upgradeParams); + + auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade, + &kmUpgradeParams, &key_blob); + + if (rc == KM_ERROR_OK) { + // on success convert the result to wire format + resultKeyBlob = kmBlob2hidlVec(key_blob); + } + + _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob); + + if (key_blob.key_material) free(const_cast(key_blob.key_material)); + + return Void(); +} + +Return KeymasterDevice::deleteKey(const hidl_vec& keyBlob) { + auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob); + return legacy_enum_conversion(keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob)); +} + +Return KeymasterDevice::deleteAllKeys() { + return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_)); +} + +Return KeymasterDevice::begin(KeyPurpose purpose, const hidl_vec& key, + const hidl_vec& inParams, begin_cb _hidl_cb) { + + // result variables for the wire + hidl_vec resultParams; + uint64_t resultOpHandle = 0; + + // result variables the backend understands + keymaster_key_param_set_t out_params{nullptr, 0}; + keymaster_operation_handle_t& operation_handle = resultOpHandle; + + auto kmKey = hidlVec2KmKeyBlob(key); + auto kmInParams = hidlParams2KmParamSet(inParams); + + auto rc = keymaster_device_->begin(keymaster_device_, legacy_enum_conversion(purpose), &kmKey, + &kmInParams, &out_params, &operation_handle); + + if (rc == KM_ERROR_OK) resultParams = kmParamSet2Hidl(out_params); + + _hidl_cb(legacy_enum_conversion(rc), resultParams, resultOpHandle); + + keymaster_free_param_set(&out_params); + + return Void(); +} + +Return KeymasterDevice::update(uint64_t operationHandle, + const hidl_vec& inParams, + const hidl_vec& input, update_cb _hidl_cb) { + // result variables for the wire + uint32_t resultConsumed = 0; + hidl_vec resultParams; + hidl_vec resultBlob; + + // result variables the backend understands + size_t consumed = 0; + keymaster_key_param_set_t out_params{nullptr, 0}; + keymaster_blob_t out_blob{nullptr, 0}; + + auto kmInParams = hidlParams2KmParamSet(inParams); + auto kmInput = hidlVec2KmBlob(input); + + auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput, + &consumed, &out_params, &out_blob); + + if (rc == KM_ERROR_OK) { + resultConsumed = consumed; + resultParams = kmParamSet2Hidl(out_params); + resultBlob = kmBlob2hidlVec(out_blob); + } + + _hidl_cb(legacy_enum_conversion(rc), resultConsumed, resultParams, resultBlob); + + keymaster_free_param_set(&out_params); + if (out_blob.data) free(const_cast(out_blob.data)); + + return Void(); +} + +Return KeymasterDevice::finish(uint64_t operationHandle, + const hidl_vec& inParams, + const hidl_vec& input, + const hidl_vec& signature, finish_cb _hidl_cb) { + // result variables for the wire + hidl_vec resultParams; + hidl_vec resultBlob; + + // result variables the backend understands + keymaster_key_param_set_t out_params{nullptr, 0}; + keymaster_blob_t out_blob{nullptr, 0}; + + auto kmInParams = hidlParams2KmParamSet(inParams); + auto kmInput = hidlVec2KmBlob(input); + auto kmSignature = hidlVec2KmBlob(signature); + + auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput, + &kmSignature, &out_params, &out_blob); + + if (rc == KM_ERROR_OK) { + resultParams = kmParamSet2Hidl(out_params); + resultBlob = kmBlob2hidlVec(out_blob); + } + + _hidl_cb(legacy_enum_conversion(rc), resultParams, resultBlob); + + keymaster_free_param_set(&out_params); + if (out_blob.data) free(const_cast(out_blob.data)); + + return Void(); +} + +Return KeymasterDevice::abort(uint64_t operationHandle) { + return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle)); +} + +IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* /* name */) { + keymaster2_device_t* dev = nullptr; + + uint32_t version; + bool supports_ec; + auto rc = keymaster_device_initialize(&dev, &version, &supports_ec); + if (rc) return nullptr; + + auto kmrc = ::keymaster::ConfigureDevice(dev); + if (kmrc != KM_ERROR_OK) { + dev->common.close(&dev->common); + return nullptr; + } + + return new KeymasterDevice(dev, version, supports_ec); +} + +} // namespace implementation +} // namespace V3_0 +} // namespace keymaster +} // namespace hardware +} // namespace android diff --git a/keymaster/3.0/default/KeymasterDevice.h b/keymaster/3.0/default/KeymasterDevice.h new file mode 100644 index 0000000000..23767efa08 --- /dev/null +++ b/keymaster/3.0/default/KeymasterDevice.h @@ -0,0 +1,97 @@ +/* + ** + ** Copyright 2016, 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. + */ + +#ifndef HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_ +#define HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_ + +#include + +#include +#include + +#include +namespace android { +namespace hardware { +namespace keymaster { +namespace V3_0 { +namespace implementation { + +using ::android::hardware::keymaster::V3_0::ErrorCode; +using ::android::hardware::keymaster::V3_0::IKeymasterDevice; +using ::android::hardware::keymaster::V3_0::KeyCharacteristics; +using ::android::hardware::keymaster::V3_0::KeyFormat; +using ::android::hardware::keymaster::V3_0::KeyParameter; +using ::android::hardware::keymaster::V3_0::KeyPurpose; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::sp; + +class KeymasterDevice : public IKeymasterDevice { + public: + KeymasterDevice(keymaster2_device_t* dev, uint32_t hardware_version, bool hardware_supports_ec) + : keymaster_device_(dev), hardware_version_(hardware_version), + hardware_supports_ec_(hardware_supports_ec) {} + virtual ~KeymasterDevice(); + + // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow. + Return getHardwareFeatures(getHardwareFeatures_cb _hidl_cb); + Return addRngEntropy(const hidl_vec& data) override; + Return generateKey(const hidl_vec& keyParams, + generateKey_cb _hidl_cb) override; + Return getKeyCharacteristics(const hidl_vec& keyBlob, + const hidl_vec& clientId, + const hidl_vec& appData, + getKeyCharacteristics_cb _hidl_cb) override; + Return importKey(const hidl_vec& params, KeyFormat keyFormat, + const hidl_vec& keyData, importKey_cb _hidl_cb) override; + Return exportKey(KeyFormat exportFormat, const hidl_vec& keyBlob, + const hidl_vec& clientId, const hidl_vec& appData, + exportKey_cb _hidl_cb) override; + Return attestKey(const hidl_vec& keyToAttest, + const hidl_vec& attestParams, + attestKey_cb _hidl_cb) override; + Return upgradeKey(const hidl_vec& keyBlobToUpgrade, + const hidl_vec& upgradeParams, + upgradeKey_cb _hidl_cb) override; + Return deleteKey(const hidl_vec& keyBlob) override; + Return deleteAllKeys() override; + Return begin(KeyPurpose purpose, const hidl_vec& key, + const hidl_vec& inParams, begin_cb _hidl_cb) override; + Return update(uint64_t operationHandle, const hidl_vec& inParams, + const hidl_vec& input, update_cb _hidl_cb) override; + Return finish(uint64_t operationHandle, const hidl_vec& inParams, + const hidl_vec& input, const hidl_vec& signature, + finish_cb _hidl_cb) override; + Return abort(uint64_t operationHandle) override; + + private: + keymaster2_device_t* keymaster_device_; + uint32_t hardware_version_; + bool hardware_supports_ec_; +}; + +extern "C" IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* name); + +} // namespace implementation +} // namespace V3_0 +} // namespace keymaster +} // namespace hardware +} // namespace android + +#endif // HIDL_GENERATED_android_hardware_keymaster_V3_0_KeymasterDevice_H_ diff --git a/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc new file mode 100644 index 0000000000..86ed1e70ef --- /dev/null +++ b/keymaster/3.0/default/android.hardware.keymaster@3.0-service.rc @@ -0,0 +1,4 @@ +service keymaster-3-0 /system/bin/hw/android.hardware.keymaster@3.0-service + class hal + user system + group system drmrpc diff --git a/keymaster/3.0/default/service.cpp b/keymaster/3.0/default/service.cpp new file mode 100644 index 0000000000..038bf317ef --- /dev/null +++ b/keymaster/3.0/default/service.cpp @@ -0,0 +1,33 @@ +/* +** +** Copyright 2016, 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.keymaster@3.0-service" + +#include + +#include + +using android::sp; + +using android::hardware::keymaster::V3_0::IKeymasterDevice; +using android::hardware::registerPassthroughServiceImplementation; +using android::hardware::launchRpcServer; + +int main() { + registerPassthroughServiceImplementation("keymaster"); + return launchRpcServer(1); +}