/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2012-2018. All rights reserved. * Description: process keymaster 3.0 hidl * Author: Hisilicon * Create: 2012.7.16 * History: 2019-01-19 CSEC work fix */ #define LOG_TAG "android.hardware.keymaster@3.0-impl" #include "KeymasterDevice.h" #include #include #include #include #include #include #include #include #include #define FR_TAG "fs_mgr" static const uint32_t KM_INDEX_ONE = 1; static const uint32_t KM_INDEX_TWO = 2; #define XSTR(x) STR(x) #define STR(x) #x #if defined(__LP64__) #define DLOPEN_KEYMASTER_HAL_PATH "/vendor/lib64/hw/keystore." XSTR(PLATFORM_NAME) ".so" #else #define DLOPEN_KEYMASTER_HAL_PATH "/vendor/lib/hw/keystore." XSTR(PLATFORM_NAME) ".so" #endif using ::keymaster::GetOsVersion; using ::keymaster::GetOsPatchlevel; namespace android { namespace hardware { namespace keymaster { namespace V3_0 { namespace implementation { static int Keymaster2DeviceInitialize(const hw_module_t* mod, keymaster2_device_t** dev) { if ((mod == nullptr) || (mod->name == nullptr) || (dev == nullptr)) { KLOG_ERROR(FR_TAG, "null point\n"); ALOGE("null point\n"); return -1; } ALOGI("Found keymaster2 module %s, version %x", mod->name, mod->module_api_version); keymaster2_device_t* km2Device = nullptr; int rc = keymaster2_open(mod, &km2Device); if (rc) { KLOG_ERROR(FR_TAG, "Error %d opening keystore keymaster2 device", rc); ALOGE("Error %d opening keystore keymaster2 device", rc); goto err; } *dev = km2Device; return 0; err: if (km2Device) { km2Device->common.close(&km2Device->common); } *dev = nullptr; return rc; } static int KeymasterDeviceInitialize( keymaster2_device_t** dev, uint32_t* version, bool* supportsEc, bool* supportsAllDigests) { if ((dev == nullptr) || (version == nullptr) || (supportsEc == nullptr) || (supportsAllDigests == nullptr)) { KLOG_ERROR(FR_TAG, "null point\n"); ALOGE("null point\n"); return -1; } const hw_module_t* mod = nullptr; *supportsEc = true; int rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, nullptr, &mod); if (rc) { KLOG_ERROR(FR_TAG, "Could not find any keystore module, using software-only implementation.\n"); ALOGI("Could not find any keystore module, using software-only implementation."); *version = (uint32_t)-1; return 0; } *version = KM_INDEX_TWO; *supportsAllDigests = true; return Keymaster2DeviceInitialize(mod, dev); } KeymasterDevice::~KeymasterDevice() { if (keymaster_device_ != nullptr) { 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); } /* * LegacyEnumConversion 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: * 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 LegacyEnumConversion(const Tag value) { return keymaster_tag_t(value); } inline static Tag LegacyEnumConversion(const keymaster_tag_t value) { return Tag(value); } inline static keymaster_purpose_t LegacyEnumConversion(const KeyPurpose value) { return keymaster_purpose_t(value); } inline static keymaster_key_format_t LegacyEnumConversion(const KeyFormat value) { return keymaster_key_format_t(value); } inline static ErrorCode LegacyEnumConversion(const keymaster_error_t value) { return ErrorCode(value); } class KmParamSet : public keymaster_key_param_set_t { public: KmParamSet() { paramStatus = false; } KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{ other.params, other.length } { other.length = 0; other.params = nullptr; paramStatus = false; } KmParamSet(const KmParamSet&) = delete; bool GetParamStatus() { return paramStatus; } void GetParamInfo(const hidl_vec& keyParams) { try { params = new keymaster_key_param_t[keyParams.size()]; } catch (std::bad_alloc) { KLOG_ERROR(FR_TAG, "Malloc mem for param failed\n"); ALOGE("Malloc mem for param failed\n"); return; } paramStatus = true; length = keyParams.size(); for (size_t i = 0; i < keyParams.size(); ++i) { auto tag = LegacyEnumConversion(keyParams[i].tag); auto type = TypeFromTag(tag); switch (type) { 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() { delete[] params; } private: bool paramStatus; }; inline static KmParamSet HidlParams2KmParamSet(const hidl_vec& params) { KmParamSet paramObj = KmParamSet(); paramObj.GetParamInfo(params); return paramObj; } 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* certChain) { hidl_vec> result; if (certChain == nullptr || certChain->entry_count == 0 || certChain->entries == nullptr) { return result; } result.resize(certChain->entry_count); for (size_t i = 0; i < certChain->entry_count; ++i) { auto& entry = certChain->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 = LegacyEnumConversion(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 hidlCb) { bool isSecure = !(keymaster_device_->flags & KEYMASTER_SOFTWARE_ONLY); bool supportsSymmetricCryptography = false; bool supportsAttestation = false; switch (hardware_version_) { case KM_INDEX_TWO: supportsAttestation = true; /* Falls through */ [[fallthrough]]; case KM_INDEX_ONE: supportsSymmetricCryptography = true; break; default: ALOGD("invalid version!\n"); break; }; hidlCb(isSecure, hardware_supports_ec_, supportsSymmetricCryptography, supportsAttestation, hardware_supports_all_digests_, keymaster_device_->common.module->name, keymaster_device_->common.module->author); return Void(); } Return KeymasterDevice::addRngEntropy(const hidl_vec& data) { if (!data.size()) { return ErrorCode::OK; } if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return ErrorCode::UNIMPLEMENTED; } return LegacyEnumConversion( keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size())); } Return KeymasterDevice::generateKey(const hidl_vec& keyParams, generateKey_cb hidlCb) { // result variables for the wire KeyCharacteristics resultCharacteristics; hidl_vec resultKeyBlob; // result variables the backend understands keymaster_key_blob_t keyBlob{ nullptr, 0 }; keymaster_key_characteristics_t keyCharacteristics{{ nullptr, 0 }, { nullptr, 0 }}; // convert the parameter set to something our backend understands auto kmParams = HidlParams2KmParamSet(keyParams); if (kmParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &keyBlob, &keyCharacteristics); if (rc == KM_ERROR_OK) { // on success convert the result to wire format resultKeyBlob = KmBlob2HidlVec(keyBlob); resultCharacteristics.softwareEnforced = KmParamSet2Hidl(keyCharacteristics.sw_enforced); resultCharacteristics.teeEnforced = KmParamSet2Hidl(keyCharacteristics.hw_enforced); } // send results off to the client hidlCb(LegacyEnumConversion(rc), resultKeyBlob, resultCharacteristics); // free buffers that we are responsible for if (keyBlob.key_material != nullptr) { free(const_cast(keyBlob.key_material)); } keymaster_free_characteristics(&keyCharacteristics); return Void(); } Return KeymasterDevice::getKeyCharacteristics( const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, getKeyCharacteristics_cb hidlCb) { // result variables for the wire KeyCharacteristics resultCharacteristics; // result variables the backend understands keymaster_key_characteristics_t keyCharacteristics{{ nullptr, 0 }, { nullptr, 0 }}; auto kmKeyBlob = HidlVec2KmKeyBlob(keyBlob); auto kmClientId = HidlVec2KmBlob(clientId); auto kmAppData = HidlVec2KmBlob(appData); if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->get_key_characteristics( keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr, clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr, &keyCharacteristics); if (rc == KM_ERROR_OK) { resultCharacteristics.softwareEnforced = KmParamSet2Hidl(keyCharacteristics.sw_enforced); resultCharacteristics.teeEnforced = KmParamSet2Hidl(keyCharacteristics.hw_enforced); } hidlCb(LegacyEnumConversion(rc), resultCharacteristics); keymaster_free_characteristics(&keyCharacteristics); return Void(); } Return KeymasterDevice::importKey( const hidl_vec& params, KeyFormat keyFormat, const hidl_vec& keyData, importKey_cb hidlCb) { // result variables for the wire KeyCharacteristics resultCharacteristics; hidl_vec resultKeyBlob; // result variables the backend understands keymaster_key_blob_t keyBlob{ nullptr, 0 }; keymaster_key_characteristics_t keyCharacteristics{{ nullptr, 0 }, { nullptr, 0 }}; auto kmParams = HidlParams2KmParamSet(params); if (kmParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } auto kmKeyData = HidlVec2KmBlob(keyData); if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams, LegacyEnumConversion(keyFormat), &kmKeyData, &keyBlob, &keyCharacteristics); 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(keyBlob); resultCharacteristics.softwareEnforced = KmParamSet2Hidl(keyCharacteristics.sw_enforced); resultCharacteristics.teeEnforced = KmParamSet2Hidl(keyCharacteristics.hw_enforced); } hidlCb(LegacyEnumConversion(rc), resultKeyBlob, resultCharacteristics); // free buffers that we are responsible for if (keyBlob.key_material != nullptr) { free(const_cast(keyBlob.key_material)); } keymaster_free_characteristics(&keyCharacteristics); return Void(); } Return KeymasterDevice::exportKey(KeyFormat exportFormat, const hidl_vec& keyBlob, const hidl_vec& clientId, const hidl_vec& appData, exportKey_cb hidlCb) { // result variables for the wire hidl_vec resultKeyBlob; // result variables the backend understands keymaster_blob_t outBlob{ nullptr, 0 }; auto kmKeyBlob = HidlVec2KmKeyBlob(keyBlob); auto kmClientId = HidlVec2KmBlob(clientId); auto kmAppData = HidlVec2KmBlob(appData); if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->export_key(keymaster_device_, LegacyEnumConversion(exportFormat), keyBlob.size() ? &kmKeyBlob : nullptr, clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr, &outBlob); 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(outBlob); } hidlCb(LegacyEnumConversion(rc), resultKeyBlob); // free buffers that we are responsible for if (outBlob.data != nullptr) { free(const_cast(outBlob.data)); } return Void(); } Return KeymasterDevice::attestKey( const hidl_vec& keyToAttest, const hidl_vec& attestParams, attestKey_cb hidlCb) { hidl_vec> resultCertChain; bool foundAttestationApplicationId = false; for (size_t i = 0; i < attestParams.size(); ++i) { switch (attestParams[i].tag) { case Tag::ATTESTATION_ID_BRAND: case Tag::ATTESTATION_ID_DEVICE: case Tag::ATTESTATION_ID_PRODUCT: case Tag::ATTESTATION_ID_SERIAL: case Tag::ATTESTATION_ID_IMEI: case Tag::ATTESTATION_ID_MEID: case Tag::ATTESTATION_ID_MANUFACTURER: case Tag::ATTESTATION_ID_MODEL: // Device id attestation may only be supported if the device is able to permanently // destroy its knowledge of the ids. This device is unable to do this, so it must // never perform any device id attestation. hidlCb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain); return Void(); case Tag::ATTESTATION_APPLICATION_ID: foundAttestationApplicationId = true; break; default: break; } } // KM3 devices reject missing attest application IDs. KM2 devices do not. if (!foundAttestationApplicationId) { hidlCb(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, resultCertChain); return Void(); } keymaster_cert_chain_t certChain{ nullptr, 0 }; auto kmKeyToAttest = HidlVec2KmKeyBlob(keyToAttest); auto kmAttestParams = HidlParams2KmParamSet(attestParams); if (kmAttestParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams, &certChain); if (rc == KM_ERROR_OK) { resultCertChain = KmCertChain2Hidl(&certChain); } hidlCb(LegacyEnumConversion(rc), resultCertChain); keymaster_free_cert_chain(&certChain); return Void(); } Return KeymasterDevice::upgradeKey( const hidl_vec& keyBlobToUpgrade, const hidl_vec& upgradeParams, upgradeKey_cb hidlCb) { // result variables for the wire hidl_vec resultKeyBlob; // result variables the backend understands keymaster_key_blob_t keyBlob{ nullptr, 0 }; auto kmKeyBlobToUpgrade = HidlVec2KmKeyBlob(keyBlobToUpgrade); auto kmUpgradeParams = HidlParams2KmParamSet(upgradeParams); if (kmUpgradeParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade, &kmUpgradeParams, &keyBlob); if (rc == KM_ERROR_OK) { // on success convert the result to wire format resultKeyBlob = KmBlob2HidlVec(keyBlob); } hidlCb(LegacyEnumConversion(rc), resultKeyBlob); if (keyBlob.key_material != nullptr) { free(const_cast(keyBlob.key_material)); } return Void(); } Return KeymasterDevice::deleteKey(const hidl_vec& keyBlob) { if (keymaster_device_ == nullptr || keymaster_device_->delete_key == nullptr) { return ErrorCode::UNIMPLEMENTED; } auto kmKeyBlob = HidlVec2KmKeyBlob(keyBlob); auto rc = LegacyEnumConversion( keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob)); // Keymaster 3.0 requires deleteKey to return ErrorCode::OK if the key // blob is unusable after the call. This is equally true if the key blob was // unusable before. if (rc == ErrorCode::INVALID_KEY_BLOB) { return ErrorCode::OK; } return rc; } Return KeymasterDevice::deleteAllKeys() { if (keymaster_device_ == nullptr || keymaster_device_->delete_all_keys == nullptr) { return ErrorCode::UNIMPLEMENTED; } return LegacyEnumConversion(keymaster_device_->delete_all_keys(keymaster_device_)); } using km_destroy_attestation_ids_so = int (*)(const keymaster2_device_t *dev); Return KeymasterDevice::destroyAttestationIds() { void *mHandle = dlopen(DLOPEN_KEYMASTER_HAL_PATH, RTLD_LAZY); if (mHandle == nullptr) { KLOG_ERROR(FR_TAG, "cannot load %s\n", DLOPEN_KEYMASTER_HAL_PATH); ALOGE("cannot load %s\n", DLOPEN_KEYMASTER_HAL_PATH); return ErrorCode::UNKNOWN_ERROR; } ALOGI("DLOPEN_KEYMASTER_HAL_PATH is %s\n", DLOPEN_KEYMASTER_HAL_PATH); km_destroy_attestation_ids_so KmDestroyAttestationIds = reinterpret_cast(dlsym(mHandle, "ReeKmDestroyAttestationIds")); if (KmDestroyAttestationIds == nullptr) { KLOG_ERROR(FR_TAG, "km_destroy_attestation_ids is null\n"); ALOGE("km_destroy_attestation_ids is null\n"); dlclose(mHandle); return ErrorCode::UNKNOWN_ERROR; } int result = KmDestroyAttestationIds(keymaster_device_); if (result != 0) { dlclose(mHandle); return ErrorCode::UNKNOWN_ERROR; } else { dlclose(mHandle); return ErrorCode::OK; } } Return KeymasterDevice::begin(KeyPurpose purpose, const hidl_vec& key, const hidl_vec& inParams, begin_cb hidlCb) { // result variables for the wire hidl_vec resultParams; uint64_t resultOpHandle = 0; // result variables the backend understands keymaster_key_param_set_t outParams{ nullptr, 0 }; keymaster_operation_handle_t &operationHandle = resultOpHandle; auto kmKey = HidlVec2KmKeyBlob(key); auto kmInParams = HidlParams2KmParamSet(inParams); if (kmInParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->begin(keymaster_device_, LegacyEnumConversion(purpose), &kmKey, &kmInParams, &outParams, &operationHandle); if (rc == KM_ERROR_OK) { resultParams = KmParamSet2Hidl(outParams); } hidlCb(LegacyEnumConversion(rc), resultParams, resultOpHandle); keymaster_free_param_set(&outParams); return Void(); } Return KeymasterDevice::update(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, update_cb hidlCb) { // 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 outParams{ nullptr, 0 }; keymaster_blob_t outBlob{ nullptr, 0 }; auto kmInParams = HidlParams2KmParamSet(inParams); if (kmInParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } auto kmInput = HidlVec2KmBlob(input); if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput, &consumed, &outParams, &outBlob); if (rc == KM_ERROR_OK) { resultConsumed = consumed; resultParams = KmParamSet2Hidl(outParams); resultBlob = KmBlob2HidlVec(outBlob); } hidlCb(LegacyEnumConversion(rc), resultConsumed, resultParams, resultBlob); keymaster_free_param_set(&outParams); if (outBlob.data != nullptr) { free(const_cast(outBlob.data)); } return Void(); } Return KeymasterDevice::finish(uint64_t operationHandle, const hidl_vec& inParams, const hidl_vec& input, const hidl_vec& signature, finish_cb hidlCb) { // result variables for the wire hidl_vec resultParams; hidl_vec resultBlob; // result variables the backend understands keymaster_key_param_set_t outParams{ nullptr, 0 }; keymaster_blob_t outBlob{ nullptr, 0 }; auto kmInParams = HidlParams2KmParamSet(inParams); if (kmInParams.GetParamStatus() == false) { KLOG_ERROR(FR_TAG, "Set hidl param to keymaster param failed\n"); ALOGE("Set hidl param to keymaster param failed\n"); return Void(); } auto kmInput = HidlVec2KmBlob(input); auto kmSignature = HidlVec2KmBlob(signature); if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return Void(); } auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput, &kmSignature, &outParams, &outBlob); if (rc == KM_ERROR_OK) { resultParams = KmParamSet2Hidl(outParams); resultBlob = KmBlob2HidlVec(outBlob); } hidlCb(LegacyEnumConversion(rc), resultParams, resultBlob); keymaster_free_param_set(&outParams); if (outBlob.data != nullptr) { free(const_cast(outBlob.data)); } return Void(); } Return KeymasterDevice::abort(uint64_t operationHandle) { if (keymaster_device_ == nullptr) { KLOG_ERROR(FR_TAG, "invalid param\n"); ALOGE("invalid param\n"); return ErrorCode::UNIMPLEMENTED; } return LegacyEnumConversion(keymaster_device_->abort(keymaster_device_, operationHandle)); } IKeymasterDevice* HIDL_FETCH_IKeymasterDevice(const char* name) { keymaster2_device_t* dev = nullptr; /* Under normal circumstances, this function will only be called once. */ /* and the normal process adopts "KLOG_ERROR(FR_TAG, " based on the consideration of maintainability. */ uint32_t version = (uint32_t)-1; bool supportsEc = false; bool supportsAllDigests = false; klog_set_level(6); if ((name == nullptr) || (strncmp(name, "default", strlen("default")) != 0)) { KLOG_ERROR(FR_TAG, "The keymaster device name is null or not default\n"); ALOGE("The keymaster device name is null or not default\n"); return nullptr; } KLOG_ERROR(FR_TAG, "Fetching keymaster device name %s\n", name); ALOGE("Fetching keymaster device name %s\n", name); auto rc = KeymasterDeviceInitialize(&dev, &version, &supportsEc, &supportsAllDigests); if (rc || dev == nullptr) { KLOG_ERROR(FR_TAG, "KeymasterDeviceInitialize failed\n"); return nullptr; } keymaster_key_param_t tempParam[KM_INDEX_TWO]; tempParam[0].tag = KM_TAG_OS_VERSION; ALOGE("Start call system api to get OS version\n"); tempParam[0].integer = GetOsVersion(); ALOGE("os version is %u\n", tempParam[0].integer); tempParam[1].tag = KM_TAG_OS_PATCHLEVEL; KLOG_ERROR(FR_TAG, "Start call system api to get patch lever\n"); ALOGE("Start call system api to get patch lever\n"); tempParam[1].integer = GetOsPatchlevel(); ALOGE("os patchlevel is %u\n", tempParam[1].integer); keymaster_key_param_set_t tempParamSet; tempParamSet.length = KM_INDEX_TWO; tempParamSet.params = tempParam; auto kmrc = dev->configure(dev, &tempParamSet); if (kmrc != KM_ERROR_OK) { dev->common.close(&dev->common); KLOG_ERROR(FR_TAG, "call keymaster configure api failed, ret=%d\n", kmrc); ALOGE("call keymaster configure api failed, ret=%d\n", kmrc); return nullptr; } KLOG_ERROR(FR_TAG, "Fetching keymaster device success\n"); ALOGE("Fetching keymaster device success\n"); return new KeymasterDevice(dev, version, supportsEc, supportsAllDigests); } } // namespace implementation } // namespace V3_0 } // namespace keymaster } // namespace hardware } // namespace android